在 PLY 中使用常规定义

Using regular definitions in PLY

当我使用下面的代码片段时:-

t_ASD = r'(a|aa*)'

输入aaaaaaaa输出结果为:-

LexToken(ID,'aaaaaaaa',1,0)

这是意料之中的。 但是当此代码上的相同输入为 运行 时:-

ASD = r'(a|aa*)'
@TOKEN(ASD)
def t_ASD(t):
    return t

输出结果为

LexToken(ASD,'a',1,0)
LexToken(ASD,'a',1,1)
LexToken(ASD,'a',1,2)
LexToken(ASD,'a',1,3)
LexToken(ASD,'a',1,4)
LexToken(ASD,'a',1,5)
LexToken(ASD,'a',1,6)
LexToken(ASD,'a',1,7)

输出不匹配的可能原因是什么?以及如何修改第二个代码以获得输出:- LexToken(ID,'aaaaaaaa',1,0)

从您的第一个示例的输出中可以明显看出,令牌正在与 ID 规则匹配,而不是 ASD 规则。请记住,作为函数提供的模式优先于作为变量提供的模式。 (参见Ply manual。)

这是我的几乎最小的测试用例,没有与其他规则交互,这表明使用模式变量具有预期的结果:

import ply.lex as lex
tokens = ['A']
ignore = ' \t\n'
def t_error(t):
    print("Bad char: '%s'" % t.value)
    t.lexer.skip()

t_A = r'(a|aa*)'

lexer = lex.lex()
lexer.input('aaaaaaa')
for token in lexer: print(token)

输出(与python2相同的输出):

$ python3 lexorder.py 
LexToken(A,'a',1,0)
LexToken(A,'a',1,1)
LexToken(A,'a',1,2)
LexToken(A,'a',1,3)
LexToken(A,'a',1,4)
LexToken(A,'a',1,5)
LexToken(A,'a',1,6)

这是预期的结果,因为 Python 正则表达式的工作方式。 Python 正则表达式引擎没有实现最长匹配语义;它更喜欢较早的替代方案,即使它们的匹配更短。