【发布时间】:2017-02-16 20:42:11
【问题描述】:
我正在尝试使用 Ply 创建解析器,但遇到了一个奇怪的错误。 这是发生匹配错误的 MCVE:
词法分析器
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()
解析器
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吗? -
不,这是匹配
*的正确方式。我尝试了一个单独的规则,例如 `r"*" 并且这个规则正确匹配了星号。 -
我只是在问
-
我也试过这个
r'^\* *[a-zA-Z_]+并且还有另一个奇怪的行为,即只有当第一个NAME标记前面有一个空行(仅\n)时,输入才被正确解析。
标签: python regex parsing lexer ply