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

问题描述 投票:2回答:1

我在理解如何正确使用Javascript目标ANTLR4中的访问者时遇到麻烦。

我准备了一个非常基本的语法,它接受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这三个功能的Visitor。我从visitInput开始,在这里我可以通过执行operation = ctx.plusOrMinus()来获取操作ctx。

这是我被卡住的地方,我怎么知道operation是正负类型?换句话说,我在哪里将ctx.plusOrMinux()传递到visitPlus()visitMinus()

我设法创建了一个可以正常工作的访客,但I am posting it here非常丑陋,因为它可能有助于更好地理解我的问题。问题出在第20-29行。

javascript antlr antlr4
1个回答
1
投票

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

似乎您期望它像一个侦听器一样工作(您在其中设置了当Tree Walker到达该节点时调用的函数。您可以在该节点的进入或退出时调用它(取决于您是否(希望在处理完子节点之前或之后获取该节点)。访问者希望您处理自己的树导航,这有时会很有用,但是侦听器在适合其目的的地方更干净。通过嵌套,您可能想要在处理完子节点之后进行侦听,因此您需要在侦听器上实现exitPlusOrMins()函数。建议您在此函数内的调试器中停止代码,以查看可以使用的对象(在ctx对象中)。

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

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

将为您提供与您到目前为止相当的能力。您将使用诸如ANTLR之类的递归下降解析器(就本例而言),但是您的方向错误使它们具有不同的解析规则。具体来说,通过使它们成为两个可选的解析规则,您可以赋予PLUS优先于负的优先级,并且PLUS和MINUS在评估顺序上应具有相同的优先级。因此,它们必须是相同的解析规则。)当您在解析器规则中放置此类替代项时,您也在建立优先级,因此请注意这些规则的顺序。

但是,除了要加上或减去整数以外,您实际上需要lexpr和rexpr本身就是表达式(您应该阅读ANTLR书中的表达式解析;它已经很好地介绍了)。

使用该规则,您的exitPlusOrMinus可以解析lexpr和rexpr的int值,然后评估op的值以确定是相加还是相减。

© www.soinside.com 2019 - 2024. All rights reserved.