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…
之后)。