无法让 Antlr4 解析器遵循隐式乘法的操作顺序

  • 本文关键字:操作 顺序 Antlr4 c# antlr antlr4
  • 更新时间 :
  • 英文 :


我是ANTLR的新手,我正在尝试使用ANTLR4和C#为计算器应用程序生成一个相对简单的解析器。这是我的语法文件。

parser grammar CalculatorExpressionParser;
options{
language = CSharp2;
}
expr:  FUNC expr? (COMMA expr)* RIGHTPAREN               #CallFunction
    |  LEFTPAREN expr RIGHTPAREN                         #Parens
    |  expr POW<assoc=right> expr                        #Pow
    |  expr op=(MULTIPLY | DIVIDE)? expr                 #MultDivide
    |  expr op=(ADD | SUBTRACT) expr                     #AddSubtract
    |  SUBTRACT expr                                     #Negative
    |  NUMBER                                            #Number
    ;

我编写了一个自定义词法分析器来生成标记,以便在解析之前支持隐式乘法和将变量转换为其等效数值。

但是在输入后,我得到以下结果。

2+6/3 => 4 (correct)
6/3+2 => 1.2 (should be 4)
6/(3+2) => 4 (also correct)
1+2*3 => 7 (correct)
2*3+1 => 8 (should be 7 too)
(2*3)+1 => 7 (correct)

请注意,我尝试关闭错误恢复功能并将其设置为报告所有歧义错误,但我似乎没有得到任何错误。

无论如何,如果我通过在除法/乘法运算符之后删除 ? ,那么它似乎工作得很好,除了不再支持隐式乘法。

parser grammar CalculatorExpressionParser;
options{
language = CSharp2;
}
expr:  FUNC expr? (COMMA expr)* RIGHTPAREN               #CallFunction
    |  LEFTPAREN expr RIGHTPAREN                         #Parens
    |  expr POW<assoc=right> expr                        #Pow
    |  expr op=(MULTIPLY | DIVIDE) expr                  #MultDivide
    |  expr op=(ADD | SUBTRACT) expr                     #AddSubtract
    |  SUBTRACT expr                                     #Negative
    |  NUMBER                                            #Number
    ;

我想知道为什么放置 ? 会破坏匹配顺序?有没有简单的方法可以解决这个问题?

"

expr expr"不符合运算符的模式,尽管ANTLR 4.2可能会处理这个问题。Sam 仍在努力更新 C# 目标。

将 expr 语句拆分为多个语句,以便获得正确的操作顺序。

通常如下所示:请注意每个 expr 如何仅处理一组数学运算,然后向下调用较低的优先级规则。 通常,最低规则是原子运算符,如INTFLOAT

因此,在这种情况下,您处理逻辑 AND 和 OR 然后比较,然后是指数,然后是乘法/除法,然后是加法/减法。

注意,我还应该指出,在这里我创建了一个 AST 树,而不是内联操作。

expr
: subExpr -> ^(EXPR subExpr)
;
subExpr : logicalAndExp (addSubtractOp^ logicalAndExp)*
;   
logicalAndExp
: logicalOrExp (multiplyDivideOp^  logicalOrExp)*    
;
logicalOrExp
: comparatorExp (CARET^  comparatorExp)*    
;
comparatorExp
: powExp (comparatorOp^  powExp)*   
;
powExp  : multExp (BARBAR^   multExp)*  
;
multExp 
:  expressionAtom (AMPAMP^ expressionAtom)*
;expression 
: subExpr -> ^(EXPR subExpr)
;
subExpr : logicalAndExp (addSubtractOp^ logicalAndExp)*
;   
logicalAndExp
: logicalOrExp (multiplyDivideOp^  logicalOrExp)*    
;
logicalOrExp
: comparatorExp (CARET^  comparatorExp)*    
;
comparatorExp
: powExp (comparatorOp^  powExp)*   
;
powExp  : multExp (BARBAR^   multExp)*  
;
multExp 
:  expressionAtom (AMPAMP^ expressionAtom)*
;

相关内容

  • 没有找到相关文章

最新更新