我还没能找到一个解决方案来为我现有的语法规则应用运算符优先级。这些操作涉及一元运算符和二元运算符,如+、-、*等。这些运算随后被视为表达式。
我掌握的语法/优先级规则如下(以大写单词为标记):
%left PLUS MINUS
%left MUL DIV
%left UMINUS NOT
expr : expr binop expr {$$ = new BinOpExpression($1, $3, $2);}
| NOT expr {$$ = new UnaryBooleanNegationExpression($2);}
| MINUS expr %prec UMINUS {$$ = new UnaryNumericNegationExpression($2);}
| LPAREN expr RPAREN {$$ = $2;}
;
binop
: PLUS { $$ = new Add(); }
| MINUS { $$ = new Sub(); }
| MUL { $$ = new Mul(); }
| DIV { $$ = new Div(); }
| GT { $$ = new GreaterThan(); }
| GE { $$ = new GreaterOrEqual(); }
| ...
;
这样做的问题是,优先级规则仅应用于一元减号运算符。例如,我的编译器为表达式"1+-2*3-8“返回的解决方案是11,而不是-13。表达式的计算结果为(前缀表示法):
+(
1,
*(
-2,
-(3, 8)
)
)
这表明运算符是按照找到它们的顺序应用的。为了解决这个问题,我为每个运算符添加了一个新规则expr (如下所示),从而解决了这个问题:
expr : expr PLUS expr {$$ = new BinOpExpression($1, $3, new Add());}
| expr MINUS expr {$$ = new BinOpExpression($1, $3, new Sub());}
| expr MUL expr {$$ = new BinOpExpression($1, $3, new Mul());}
| expr DIV expr {$$ = new BinOpExpression($1, $3, new Div());}
| ...
;
但我想避免这种情况,因为为了添加正确的运算符优先级,我必须将1个规则(例如expr binop expr
)转换为19个不同的规则(每个一元、二进制和赋值操作一个)。有没有办法避免这种情况,同时仍然获得正确的运算符优先级?
发布于 2021-08-23 16:47:54
您看到的基本问题是每个规则只能有一个优先级,那么规则expr: expr binop expr
的优先级应该是什么呢?因此,每个优先级都需要至少有一条规则。你可以这样做:
expr : expr addop expr %prec PLUS
| expr mulop expr %prec MUL
...
addop : PLUS | MINUS
mulop : MUL | DIV
这不需要太多的expr规则,但并不比为每个运算符使用单独的规则更简单。
https://stackoverflow.com/questions/68894825
复制相似问题