PLY的词法分析器是否支持“最大匹配”?

4
许多编程语言的语法要求按照“最大匹配原则”对它们进行标记化。也就是说,标记应该从输入流中尽可能多地构建字符。
PLY的词法分析器似乎没有应用这个原则。例如:
import ply.lex as lex

tokens = ('ASSIGNMENT', 'EQUALITY')

t_ASSIGNMENT = r'[+\-*/]?='
t_EQUALITY   = r'=='

lexer = lex.lex()

lexer.input('==')
for tok in lexer:
    print(tok)

根据“最大匹配原则”,此代码的输出应该是LexToken(EQUALITY,'==',1,0),但实际结果为LexToken(ASSIGNMENT,'=',1,0) LexToken(ASSIGNMENT,'=',1,1)。这似乎是因为词法分析器更喜欢ASSIGNMENT而不是EQUALITY,即优先考虑较长的正则表达式而不是较长的匹配。
是否有可能让PLY的词法分析器遵循“最大匹配原则”?
如果不行,是否有任何指导方针可以避免出现像上面那种“不够最大匹配”的情况?
1个回答

3
PLY使用Python自带的re包来匹配记号,通过将多个规则组合成单个正则表达式的方式实现。由于Python的正则表达式库不是"最大匹配"算法,所以PLY也不是。
相反,被选中的匹配是在这个大正则表达式中第一个匹配的模式,并且顺序记录在PLY手册中:
在构建主正则表达式时,遵循以下顺序添加规则:
1. 函数定义的所有记号按出现在词法器文件中的顺序依次添加。 2. 字符串定义的标记根据其正则表达式长度的降序排序(较长的表达式先添加)。
由于匹配=的模式更长,因此它会先被插入,导致==无法匹配。
要解决这个问题,可以将模式定义为函数,然后根据需要对它们进行排序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接