我想写一个语法来评估表达式。
我从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) ...
,而应该访问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 !");}
)*
;
但是,你真的想警告用户吗?在此警告之后,计算将继续进行。在我看来,你应该让异常被抛出。
eouti写道:
我想在我的求值器中添加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
当然不需要在这些规则之间…)
另外,您可能希望将returns [int value]
更改为returns [double value]
,特别是因为您正在使用除法。