我正在使用jison文件并使用python PLY中的lex模块将其转换为解析器生成器。
我注意到在这个jison文件中,某些令牌有多个与之关联的规则。例如,对于令牌CONTENT
,该文件指定以下三个规则:
[^\x00]*?/("{{") {
if(yytext.slice(-2) === "\\\\") {
strip(0,1);
this.begin("mu");
} else if(yytext.slice(-1) === "\\") {
strip(0,1);
this.begin("emu");
} else {
this.begin("mu");
}
if(yytext) return 'CONTENT';
}
[^\x00]+ return 'CONTENT';
// marks CONTENT up to the next mustache or escaped mustache
<emu>[^\x00]{2,}?/("{{"|"\\{{"|"\\\\{{"|<<EOF>>) {
this.popState();
return 'CONTENT';
}
在另一种情况下,COMMENT
令牌有多个规则:
<com>[\s\S]*?"--}}" strip(0,4); this.popState(); return 'COMMENT';
<mu>"{{!--" this.popState(); this.begin('com');
<mu>"{{!"[\s\S]*?"}}" strip(3,5); this.popState(); return 'COMMENT';
当它们适用于不同的状态时,区分规则似乎很容易,但是当它们适用于同一个状态时呢?
如何使用ply.lex将此jison转换为python规则?
修改
如果它有帮助,这个jison文件是handlebars.js源代码的一部分。请参阅:https://github.com/wycats/handlebars.js/blob/master/src/handlebars.l
答案 0 :(得分:0)
这个问题很难回答;这也是两个问题。
Jison(这是用于编写把手解析器的语言,而不是bison)具有其他词法分析器中找不到的一些功能,尤其是在PLY中找不到的功能。这使得很难将您从Jison显示的词汇代码转换为PLY。但是,这不是您关注的问题。可以回答您的基本问题,多个正则表达式如何在PLY中返回单个标记,但这不会为您提供实现您选择的代码作为示例的解决方案!
首先,让我们解决您提出的问题。在PLY中为多个正则表达式返回一个标记可以通过PLY中的@TOKEN
装饰器完成,如PLY manual(第4.11节)所示。
例如,我们可以执行以下操作:
comment1 = r'[^\x00]*?/("{{")'
comment2 = r'[^\x00]+'
comment = r'(' + comment1 + r'|' + comment2 + r')'
@TOKEN(comment)
def t_COMMENT(t)
....
然而,这对于jison的规则并不适用,因为他们使用了一个名为start condition的jison新功能(参见Jison Manual)。这里,短语this.begin
用于引入状态名称,然后可以在模式中的其他位置使用。这是<mu>
,<emu>
和<com>
的来源。 PLY中没有这样的功能。
要匹配这些词位,确实需要回到句柄/胡须语言/符号的语法并创建新的正则表达式。不知怎的,我觉得完全重新实现了整个把手,因为SO回答可能是一个太过分了。
但是,我已经为您和其他任何踏上这条道路的人确定了解决方案的步骤。