我正在尝试在 Python 中构建一个 CAS,目前我正坚持实现解析器,我将使用它从表达式字符串转到我最终可以操作和简化的 Anytree 树。问题似乎是,在解析时,yacc 没有GROUP使用我的解析器语法规范中定义的正确子节点来实现我的节点。我试过弄乱优先级和关联性,改变语法规则的顺序,但似乎没有什么能让它正确地成为节点的父节点。更奇怪的是,在调试/详细模式下,当它与表达式模式匹配时,它会为表达式创建一个节点,但它(出于某种原因)GROUP在识别LPAREN expression RPAREN令牌时无法将其作为节点的父节点
这是我的代码:
import ply.yacc as yacc
from anytree import Node, RenderTree
import ply.lex as lex
#init token names
tokens = (
'INTEGER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
)
#init regex rules for said tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
#init regex rule/function for integers
def t_INTEGER(t):
r'\d+'
t.value = int(t.value)
return t
#ignoring whitespace
t_ignore = '\t'
#handling unknown characters (%s inserts whatever is past the second %)
def t_error(t):
print("Illegal character '%s'" %t.value[0] )
t.lexer.skip(1)
#building the lexer
lexer = lex.lex()
#parser grammar spec
#binary operators
def p_expression_binop(p):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression '''
p[0] = Node(p[2],children = [Node(p[1]),Node(p[3])])
#brackets/grouping
def p_expression_group(p):
'expression : LPAREN expression RPAREN'
p[0] = Node(p[1], children = [Node(p[2])])
#integers
def p_expression_number(p):
'expression : INTEGER'
p[0] = Node(p[1])
def p_error(p):
print("Input syntax error ")
treeParser = yacc.yacc()
while True:
try:
s = input("Calculate this >")
except EOFError:
break
if not s: break
ParsTree = treeParser.parse(s)
print(RenderTree(ParsTree))
样本输入:(2)+(2)
样本输出:
Calculate this >(2)+(2)
Node('/+')
├── Node("/+/Node('/GROUP')")
└── Node("/+/Node('/GROUP')")
如您所见,它仅创建GROUP节点,并且不会在所述节点下创建任何子整数GROUP节点
编辑:使代码自包含并添加示例输入和输出以更好地解释问题