ANTLR:表达式计算器、分区和pow

ANTLR:表达式计算器、分区和pow,antlr,grammar,expression-evaluation,Antlr,Grammar,Expression Evaluation,我正试图写一个语法来评估表达式。 我从ANTLR网站(it manage+、-和*)上的给定示例开始。 我加了一个除法。但我想通知用户,如果他试图除以0。 此外,我想在我的计算器中添加pow(优先级高于乘除法。(例如2^3=8)。 希望可以理解。 这是我的语法表达式: grammar Expr; @header { import java.util.HashMap; } @members { /** Map variable name to Integer object hold

我正试图写一个语法来评估表达式。
我从ANTLR网站(it manage+、-和*)上的给定示例开始。 我加了一个除法。但我想通知用户,如果他试图除以0。 此外,我想在我的计算器中添加pow(优先级高于乘除法。(例如2^3=8)。
希望可以理解。
这是我的语法表达式:

grammar Expr;

@header {  
import java.util.HashMap;  
}

@members {  
/** Map variable name to Integer object holding value */  
HashMap memory = new HashMap();  
}

prog:   stat+ ;

stat:   expr NEWLINE {System.out.println($expr.value);}  
    |   ID '=' expr NEWLINE  
        {memory.put($ID.text, new Integer($expr.value));}  
    |   NEWLINE  
    ;

expr returns [int value]
    :   e=multExpr {$value = $e.value;}
        ((   '+' e=multExpr {$value += $e.value;}
        |   '-' e=multExpr {$value -= $e.value;}
        ))*
    ;

multExpr returns [int value]
    :   e=atom {$value = $e.value;} 
        ('*' e=atom {$value *= $e.value;}
        |'/' e=atom {if (e != 0) $value /= $e.value; 
                else System.err.println("Division par 0 !");}
        )*
    ; 

atom returns [int value]
    :   INT {$value = Integer.parseInt($INT.text);}
    |   ID
        {
        Integer v = (Integer)memory.get($ID.text);
        if ( v!=null ) $value = v.intValue();
        else System.err.println("Variable indéfinie "+$ID.text);
        }
    |   '(' expr ')' {$value = $expr.value;}
    ;

ID  :   ('a'..'z'|'A'..'Z')+ ;
INT :   '0'..'9'+ ;
NEWLINE:'\r'? '\n' ;
WS  :   (' '|'\t')+ {skip();} ;
提前谢谢。 埃德

埃奥蒂写道:

我添加了除法。但是如果用户试图除以0,我想通知他

multExpr
规则中,如果(e!=0)则不应执行
操作,但应访问
e
value
属性。此外,表达式的左侧称为
e
,而右侧也称为
e
。您最好为它们指定唯一的名称:

multExpr returns [int value]
    :   e1=atom {$value = $e1.value;} 
        ( '*' e2=atom {$value *= $e2.value;}
        | '/' e2=atom {if ($e2.value != 0) $value /= $e2.value; 
                       else System.err.println("Division par 0 !");}
        )*
    ; 
但是,你真的想警告用户吗?在这个警告之后,计算将立即继续。依我看,你应该让异常被抛出

埃奥蒂写道:

我想在我的计算器中添加pow(优先级高于乘除)

然后在
multExpr
atom
之间添加
powExpr
规则,让
multExpr
使用此
powExpr
规则,而不是
atom
规则:

multExpr returns [int value]
    :   e1=powExpr       {...} 
        ( '*' e2=powExpr {...}
        | '/' e2=powExpr {...}
        )*
    ;  

powExpr returns [int value]
    :   atom      {...} 
        ('^' atom {...} 
        )*
    ;

atom returns [int value]
    :   INT          {...}
    |   ID           {...}
    |   '(' expr ')' {...}
    ;
powExpr
当然不需要介于这些规则之间……)


另外,您可能希望将
返回[int-value]
更改为
返回[double-value]
,尤其是因为您使用除法。

非常感谢,伙计!是的,我忘了说如果分母=0,我想警告用户并停止语法。我尝试添加break;->不起作用。@eouti,没有看到在
N/0
的情况下停止解析。在这种情况下,只需在
else
中抛出一个异常即可块(在
System.err…
之后)。