Использование регулярных определений в PLY - PullRequest
0 голосов
/ 25 февраля 2020

Когда я использую следующий фрагмент кода: -

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)

1 Ответ

2 голосов
/ 25 февраля 2020

Из результатов первого примера видно, что токен соответствует правилу ID, а не правилу ASD. Помните, что шаблоны, предоставляемые в качестве функций, имеют приоритет над шаблонами, предоставляемыми в качестве переменных. (См. Руководство Ply .)

Вот мой почти минимальный тестовый пример без взаимодействия с другими правилами, который показывает, что использование переменной шаблона дает ожидаемый результат:

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 не реализует семантику с наибольшим соответствием; он предпочитает более ранние альтернативы, даже если их соответствие короче.

...