ANTLR:表达评估器、除法和 pow
我正在尝试编写一个语法来评估表达式。
我从 ANTLR 网站上给定的示例开始(它管理 +、- 和 *)。 我添加了部门。但如果用户尝试除以 0,我想通知他。 此外,我想在我的求值器中添加 pow(优先级高于乘法和除法。(例如 2^3=8)。
希望这是可以理解的。
这是我的语法 Expr.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();} ;
提前致谢。 埃德。
I'm trying to write a grammar to evaluate expressions.
I've started with the given example on the ANTLR website (it manage +,- and *).
I added the division. But I would like to notify user if he tries to divide by 0.
Moreover, I would like to add the pow in my evaluator (with an higher precedence than multiply and divide. (for example 2^3=8).
Hope it's understandable.
Here's my grammar Expr.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();} ;
Thanks in advance.
Ed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的
multExpr
规则中,您不应该执行if (e != 0) ...
,但您应该访问e
的value
属性。另外,表达式的左侧称为e
,而右侧也称为e
。您最好给它们指定唯一的名称:但是,您真的想警告用户吗?出现此警告后,计算将继续进行。 IMO,你应该让异常被抛出。
然后在中添加一个
powExpr
规则)在multExpr
和atom
之间,并让multExpr
使用此powExpr
规则而不是atom
规则:(
powExpr
当然,实际上并不需要位于这些规则之间...)另外,您可能想要更改
returns [int value] 到
返回 [double value]
,特别是因为您正在使用除法。Inside your
multExpr
rule, you shouldn't doif (e != 0) ...
, but you should accesse
'svalue
attribute instead. Also, the left-hand-side of your expression is callede
while the right-hand-side is also callede
. You'd better give them unique names:But, do you really want to warn the user? After this warning, the calculation will just continue at the moment. IMO, you should just let the exception be thrown.
Then add a
powExpr
rule in betweenmultExpr
andatom
and letmultExpr
use thispowExpr
rule instead of theatom
rule:(
powExpr
doesn't literally need to be in between these rules of course...)Also, you might want to change
returns [int value]
intoreturns [double value]
, especially since you're using division.