表达式求值器,除法和幂



我想写一个语法来评估表达式。
我从ANTLR网站上给出的例子开始(它管理+,-和*)。我加上了除法。但我想通知用户如果他尝试除以0。此外,我希望在我的求值器中添加pow(优先级高于乘法和除法)。(例如2^3=8).
希望你能理解。
这是我的语法课本。g:

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();} ;

提前感谢。艾德。

eouti写道:

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

在您的multExpr规则中,您不应该访问if (e != 0) ...,而应该访问evalue属性。此外,表达式的左侧称为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 !");}
        )*
    ; 

但是,你真的想警告用户吗?在此警告之后,计算将继续进行。在我看来,你应该让异常被抛出。

eouti写道:

我想在我的求值器中添加pow(优先级高于乘法和除法)。

然后在multExpratom之间添加一个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当然不需要在这些规则之间…)

另外,您可能希望将returns [int value]更改为returns [double value],特别是因为您正在使用除法。

相关内容

  • 没有找到相关文章

最新更新