在ANTLR4中使用访问者的正确方法(javascript目标)

时间:2016-01-15 22:27:39

标签: javascript antlr antlr4

我无法理解如何在ANTLR4,Javascript目标中正确使用访问者。

我准备了一个非常基本的语法,它接受INT + INTINT - INT次操作。

grammar PlusMinus;
INT    : [0-9]+;
WS     : [ \t\r]+ -> skip;

PLUS  : '+';
MINUS : '-';

input : plusOrMinus
    ;

plusOrMinus
    : numberLeft PLUS numberRight # Plus
    | numberLeft MINUS numberRight # Minus
    ;

numberLeft : INT;
numberRight : INT;

根据这一语法,ANTLR将生成一个具有以下三个功能的访问者:visitInputvisitPlusvisitMinus。我从visitInput开始,我可以通过执行operation = ctx.plusOrMinus()来获取操作ctx。

这就是我被卡住的地方,我怎么知道operation的类型是加号还是减号?换句话说,我在哪里将ctx.plusOrMinux()传递给visitPlus()visitMinus()

我成功创建了一个可以工作的访问者,但它非常难看,I am posting it here因为这可能有助于更好地理解我的问题。第20-29行就是问题所在。

1 个答案:

答案 0 :(得分:1)

首先...... PLUS和MINUS是词法规则。您不访问令牌(词法分析器规则的结果)。

看起来你期望它像监听器一样工作(你设置你的函数,当树步行者到达那个节点时被调用。你可以在进入或退出节点时被调用(取决于是否你希望在你处理它的孩子之前或之后得到节点。访问者希望你处理你自己的树导航,这有时是有用的,但听众在适合目的的地方更干净。有了嵌套,你可能想要在处理子节点之后监听,所以你需要在你的监听器上实现一个exitPlusOrMins()函数。我建议你在这个函数里面的调试器中停止你的代码,看看你可以使用的对象(在ctx对象中)。

(您还需要重新考虑您的numberLeft和numberRIght解析器规则。更像是:

plusOrMinus:lexpr = INT(op = PLUS | op = MINUS)rexpr = INT;

会给你一个非常接近的东西,相当于你到目前为止。你所拥有的将使用像ANTLR这样的递归下降解析器(就这个例子而言),但是你朝着错误的方向前进,使它们成为不同的解析规则。)

为了比增加或减去整数更进一步,你需要lexpr和rexpr实际上是表达式本身(你应该阅读ANTLR书中的表达式解析;它的覆盖非常好)。

使用该规则,exitPlusOrMinus可以解析lexpr和rexpr的int值,然后计算op的值以确定是添加还是减去。