我在理解如何正确使用Javascript目标ANTLR4中的访问者时遇到麻烦。
我准备了一个非常基本的语法,它接受INT + INT
或INT - 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将生成一个具有visitInput
,visitPlus
和visitMinus
这三个功能的Visitor。我从visitInput
开始,在这里我可以通过执行operation = ctx.plusOrMinus()
来获取操作ctx。
这是我被卡住的地方,我怎么知道operation
是正负类型?换句话说,我在哪里将ctx.plusOrMinux()
传递到visitPlus()
或visitMinus()
?
我设法创建了一个可以正常工作的访客,但I am posting it here非常丑陋,因为它可能有助于更好地理解我的问题。问题出在第20-29行。
首先... 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的值以确定是相加还是相减。