Я пытаюсь создать парсер, используя Ply, но я столкнулся с странной ошибкой. Вот MCVE, где происходит ошибка соответствия:Python parser ply соответствует неправильному регулярному выражению
Lexer
import ply.lex as lex
tokens = (
'IDENTIFIER',
'NAME',
'EQUALS'
)
def t_IDENTIFIER(t):
r'\* *[a-zA-Z_]+'
print("identifier")
return t
def t_NAME(t):
r"[a-zA-Z_]+"
print("name")
return t
t_EQUALS = r"="
t_ignore = ' \t'
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
# Error handling rule
def t_error(t):
print("Illegal character '%s' at line' %s'" % (t.value[0] , t.lexer.lineno))
t.lexer.skip(1)
# Build the lexer
lexer = lex.lex()
Parser
import ply.yacc as yacc
from l import tokens
def p_main(p):
'''
main : NAME EQUALS NAME
'''
def p_error(p):
if p is not None:
print ("Line %s, illegal token %s" % (p.lineno, p.value))
else:
print("Syntax error in input!")
parser = yacc.yacc()
with open('simple2','r') as f:
result = parser.parse(f.read())
Мой входной файл содержит только это:
A = B
И то, что происходит в том, что первое слово A
совпадает с токеном IDENTIFIER
, даже если он не должен делать, поскольку регулярное выражение требует буквы *
. После этого анализатор не может распознать выражение, поскольку лексер не возвращает правильные жетоны.
Что не так? Регулярное выражение, используемое для маркера IDENTIFIER, отлично работает в Python.
Возможно, '\ *' рассматривается как '' many \ or none "'? Вы попробовали '\ A = B'? – furas
Нет, это правильный способ соответствия '*'. Я пробовал одно отдельное правило типа «r» \ * », и это правильно соответствует звездочке. – ibi0tux
Я был только quessing – furas