我目前正在构建一个Python解析器,并且正在定义算术表达式。算术表达式背后的规则在我添加括号之前一直工作正常。
这里是出发点:
%token TOKEN_ARITH_ADD TOKEN_ARITH_SUB
%token TOKEN_ARITH_MUL TOKEN_ARITH_DIV TOKEN_ARITH_MOD
%token TOKEN_ARITH_POWER
%token TOKEN_ASSIGN
%token TOKEN_PAREN_OPEN TOKEN_PAREN_CLOSE
然后:
arith_expr: factor
| arith_expr TOKEN_ARITH_ADD factor { $$ = ast_init_arith_op($3, "+", $1); };
| arith_expr TOKEN_ARITH_SUB factor { $$ = ast_init_arith_op($3, "-", $1); };
| TOKEN_PAREN_OPEN arith_expr TOKEN_PAREN_CLOSE { $$ = $2; };
;
factor: power { $$ = ast_init_arith_op($1, NULL, NULL); };
| factor TOKEN_ARITH_MUL power { $$ = ast_init_arith_op($3, "*", $1); };
| factor TOKEN_ARITH_DIV power { $$ = ast_init_arith_op($3, "/", $1); };
| factor TOKEN_ARITH_MOD power { $$ = ast_init_arith_op($3, "%", $1); };
;
power: term
| power TOKEN_ARITH_POWER term { $$ = ast_init_arith_op($3, "**", $1); }
term: identifier;
| literal_int;
| literal_float;
结果是,例如,如果我输入:
myVar = (a + b) * 2
我得到error: syntax error, unexpected TOKEN_ARITH_MUL, expecting TOKEN_EOL
。
因此,我尝试将前三个版本的%token
更改为%left
,但遇到了同样的问题。
我还尝试将赋值的%token
更改为%right
,不幸的是,我在编译时得到了一个错误(error: rule given for assign, which is a token
)-回想起来,这是有意义的。
看起来TOKEN_PAREN_OPEN arith_expr TOKEN_PAREN_CLOSE
崩溃成arith_expr
,assign
马上就起作用了。我做错了什么?
1条答案
按热度按时间3htmauhk1#
根据语法,乘法运算符只能出现在
factor
和power
之间。括号中的表达式两者都不是,也不能简化为两者之一。就所提供的语法部分而言,它是arith_expr
。@n.m.的评论是正确的:您将带括号表达式的规则放在了错误的位置。它应该是
term
,而不是arith_expr
。但是,您的后续评论表明您误解了。不要更改生成。只需按原样移动它,使其成为term
的备选项之一:它允许带括号的表达式本身显示为完整的表达式或任何运算符的操作数。