我遇到了 PLY (Python Lex-Yacc) 的问题,它无法识别我定义的解析器中的标记。此错误导致解析器无法构建。
尝试构建解析器时,我收到以下错误:
ERROR: C:\Users\###\Desktop\Scratch\scrybe\src\scrybe\scriptparser\parser.py:236: Symbol 'NOT' used, but not defined as a token or a rule
WARNING: Token 'COMMENT' defined, but not used
WARNING: Token 'NEWLINE' defined, but not used
WARNING: Token 'UMINUS' defined, but not used
WARNING: There are 3 unused tokens
Traceback (most recent call last):
...
parser = yacc.yacc()
File "C:\Program Files\Python313\Lib\site-packages\ply\yacc.py", line 3432, in yacc
raise YaccError('Unable to build parser')
ply.yacc.YaccError: Unable to build parser
这是我的词法分析器的相关代码:
reserved = {
...
"this": "THIS",
"not": "NOT",
"and": "AND",
...
}
tokens.extend(reserved.values())
...
def t_SYMBOL(token):
r"\b[a-zA-Z_]\w*\b"
token.type = reserved.get(token.value, "VARIABLE")
return token
这是我在 parser.py 中的优先级表:
precedence = (
...
("left", "AND"),
("right", "NOT"),
("left", "IN"),
...
)
这是我的解析器中生成错误的代码:
def p_logical_operation(prod):
"""logical_operation : expression LESSTHAN expression
| expression GREATERTHAN expression
| expression LESSTHANEQUAL expression
| expression GREATERTHANEQUAL expression
| expression EQUALTO expression
| expression NOTEQUALTO expression
| expression AND expression
| expression OR expression
| expression IN expression
| NOT expression"""
prod[0] = {
"lexpos": prod.lexpos(1) if len(prod) == 3 else prod[1]["lexpos"] if isinstance(prod[1], dict) else prod.lexpos(2),
"type": "logical operation",
"condition": prod[2] if len(prod) == 4 else prod[1],
}
if len(prod) == 4:
prod[0].update({
"comparand 1": prod[1],
"comparand 2": prod[3]
})
else:
prod[0].update({"comparand": prod[2]})
我已经确认词法分析器在一段测试输入上单独运行时正在生成预期的标记。
问题:为什么 PLY 无法识别“NOT”标记,尽管它是在保留字典中定义的,特别是考虑到我可以用任何其他保留关键字替换它并让它正常工作?如何解决这个问题并成功构建解析器?任何帮助或见解将不胜感激。
我发现了问题。我将
p_logical_operation
导入到另一个解析器中,该解析器的词法分析器没有定义 'NOT'
标记。所以,这个错误有点误导,但错误是我的。