Python 在PLY中使用正则定义

Python 在PLY中使用正则定义,python,compiler-construction,lexer,ply,Python,Compiler Construction,Lexer,Ply,当我使用以下代码段时:- t_ASD = r'(a|aa*)' 输入时,aaaaaa输出为:- 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'

当我使用以下代码段时:-

t_ASD = r'(a|aa*)'
输入时,
aaaaaa
输出为:-

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
规则匹配的。请记住,作为函数提供的模式优先于作为变量提供的模式。(见附件。)

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

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相同的输出):


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

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

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

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相同的输出):


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

为什么您的模式不仅仅是
a+
?@l3via这不是问题的关键,关键是第二个代码段也应该产生与第一个代码段相同的输出。对。但这有什么不同吗?我可以想象regex引擎看到了第一个选项的析取,因此分割了所看到的标记。但这仍然是一个很好的问题,为什么行为会有所不同。为什么你的模式不仅仅是
a+
?@l3via这不是问题的关键,关键是第二个代码片段也应该产生与第一个相同的输出。对。但这有什么不同吗?我可以想象regex引擎看到了第一个选项的析取,因此分割了所看到的标记。但这仍然是一个很好的问题,为什么行为不同。