如何使用PLY处理一个令牌的多个规则

时间:2014-03-26 18:00:23

标签: python bison lex ply jison

我正在使用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

1 个答案:

答案 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回答可能是一个太过分了。

但是,我已经为您和其他任何踏上这条道路的人确定了解决方案的步骤。