以下规则是较大规则的摘录。注意语法尾部的可选部分。在解析输入之后,我们遍历生成的解析树以评估表达式。第一条规则的监听器代码也在下面给出。
arithmeticTerm
: arithmeticFactor (op=(MULT|DIVIDE) arithmeticFactor)*
;
arithmeticFactor: INTEGER /* For now , let it be simple terminal */
监听
import java.util.ArrayList;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
public class PredicateEvaluator extends PredicateGrammarBaseListener {
private ParseTreeProperty<Float> floatValues = new ParseTreeProperty<Float>();
private ArrayList<Float> arithmeticTermFactorList = null;
private void setFloatValue(ParseTree node, float value){
floatValues.put(node, value);
}
private float getFloatValue(ParseTree node){
return floatValues.get(node);
}
public void enterArithmeticTerm(
@NotNull PredicateGrammarParser.ArithmeticTermContext ctx)
{
arithmeticTermFactorList = new ArrayList<Float>();
}
目前,我正在以这种方式评估算术术语。我需要检测类型op和divie或乘以因子。但是,我的编译器找不到getType()方法。我查看了antlr4生成的代码,但它不在那里。我正在关注antlr4的创建者的书,他在类似的场景中使用了getType()方法,但同样的事情在这里不起作用。你的帮助真的很有用。
public void exitArithmeticTerm(
@NotNull PredicateGrammarParser.ArithmeticTermContext ctx)
{
float evaluatedValue = 0.0f;
if (ctx.op == null){
evaluatedValue = getFloatValue(ctx.arithmeticFactor().get(0));
}else{
for(float value : arithmeticTermFactorList){
if(ctx.op.getType() == PredicateGrammarLexer.MULT) {
evaluatedValue *= value;
}else{
evaluatedValue /= value;
}
}
}
arithmeticExprTermList.add(evaluatedValue);
}
public void exitArithmeticFactor(
@NotNull PredicateGrammarParser.ArithmeticFactorContext ctx)
{
Float evaluatedValue = NEGATIVE * Integer.valueOf(ctx.INTEGER().getText());
arithmeticTermFactorList.add(evaluatedValue);
}
}
答案 0 :(得分:3)
而不是:
arithmeticTerm
: arithmeticFactor (op=(MULT|DIVIDE) arithmeticFactor)*
;
做这样的事情:
expression
: MINUS expression #unaryMinusExpression
| expression MULT expression #multExpression
| expression DIVIDE expression #divideExpression
| expression ADD expression #addExpression
| expression MINUS expression #minusExpression
| INTEGER #integerExpression
| '(' expression ')' #parensExpression
;
然后在你的听众中,你只需要覆盖#...Expression
方法:
@Override
public void enterMultExpression(@NotNull PredicateGrammarParser.MultExpressionContext ctx)
{
...
}
请注意,MULT
和DIVIDE
表达式的优先级高于ADD
和MINUS
,因为它们是在后者之前定义的。