我正在处理一个json文件,并使用python PLY中的lex模块将其转换为解析器生成器。
我注意到在这个json文件中,某些令牌有多个与之相关的规则。例如,对于令牌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>[sS]*?"--}}" strip(0,4); this.popState(); return 'COMMENT';
<mu>"{{!--" this.popState(); this.begin('com');
<mu>"{{!"[sS]*?"}}" strip(3,5); this.popState(); return 'COMMENT';
当它们适用于不同的状态时,区分规则似乎很容易,但是当它们适用于相同的状态时呢?
如何使用plys .lex将此jison转换为python规则?
编辑
如果它有帮助,这个jison文件是handlebars.js源代码的一部分。参见:https://github.com/wycats/handlebars.js/blob/master/src/handlebars.l
这个问题很难回答;这也是两个问题在一起。
Jison(这是编写handlebars解析器的语言,而不是bison)具有一些在其他词法分析器中没有的特性,特别是在PLY中没有的特性。这使得很难将您所展示的从json到PLY的词法代码转换。然而,这不是你关注的问题。可以回答您的基本问题,如何在PLY中多个正则表达式返回单个令牌,但这不会给您实现您选择作为示例的代码的解决方案!
首先,让我们来回答你的问题。为PLY中的多个正则表达式返回一个令牌可以由PLY中的@TOKEN
装饰器完成,如PLY手册(第4.11节)所示。
comment1 = r'[^x00]*?/("{{")'
comment2 = r'[^x00]+'
comment = r'(' + comment1 + r'|' + comment2 + r')'
@TOKEN(comment)
def t_COMMENT(t)
....
然而,这并不适用于你从jison中获得的规则,因为它们使用了jison的一个新特性,称为启动条件(请参阅jison手册)。在这里,短语this.begin
用于引入状态名,然后可以在模式的其他地方使用状态名。这就是<mu>
、<emu>
和<com>
的来源。在PLY中没有这样的功能。
要匹配这些词汇,确实有必要回到handlebars/moustache语言/符号的语法并创建新的正则表达式。不知何故,我觉得在SO的答案中完全重新实现整个把手可能有点过分了。
但是,我已经为您和任何踏上这条道路的人确定了解决方案的步骤。