ANTLR教程(五)语法树节点间数据传递

方法一: 使用程序员自定义的栈,适用于listener和visit等

lister的方法没有返回值,将值放到堆栈中。

public static class Evaluator extends LExprBaseListener {
Stack stack = new Stack();

public void exitMult(LExprParser.MultContext ctx) {
int right = stack.pop();
int left = stack.pop();
stack.push( left * right );
}
public void exitAdd(LExprParser.AddContext ctx) {
int right = stack.pop();
int left = stack.pop();
stack.push(left + right);
}
public void exitInt(LExprParser.IntContext ctx) {
stack.push( Integer.valueOf(ctx.INT().getText()) );
}
}

栈方式缺点:
程序要需要保证push和pop正确

栈方式优点:
可以传输多种值和多个返回值

方法二: 使用antlr语法树节点返回值,只适用于visit,lister函数没有返回值

public static class EvalVisitor extends LExprBaseVisitor {
public Integer visitMult(LExprParser.MultContext ctx) {
return visit(ctx.e(0)) * visit(ctx.e(1));
}
public Integer visitAdd(LExprParser.AddContext ctx) {
return visit(ctx.e(0)) + visit(ctx.e(1));
}
public Integer visitInt(LExprParser.IntContext ctx) {
return Integer.valueOf(ctx.INT().getText());
}
}

方法三: 将值存入语法树种的节点上下文中,适用于listener,visit

缺点是,语法树大时,存储的信息太多

方法一:节点上下文有个value字段,只能存放整型

e returns [int value] :
e ‘*’ e # Mult

e ‘+’ e # Add
INT # Int

;

public void exitAdd(LExprParser.AddContext ctx) {
*/ e(0).value is the subexpression value of the first e in the alternative
ctx.value = ctx.e(0).value + ctx.e(1).value; /* e ‘+’ e # Add
}

方法二:最容易的方式是使用map,可以存放任意类型

public static class EvaluatorWithProps extends LExprBaseListener {
** maps nodes to integers with Map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值