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

标签 javascript antlr antlr4

我无法理解如何在 ANTLR4、Javascript 目标中正确使用 Visitors。

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

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

我设法创建了一个确实有效的访问者,但它非常丑陋,I am posting it here因为这可能有助于更好地理解我的问题。第 20-29 行是问题所在。

最佳答案

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

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

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

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

会给你一个与你目前所拥有的非常接近的等价物。你所拥有的将与像 ANTLR 这样的递归下降解析器一起工作(就这个例子而言),但是你朝着错误的方向前进,使它们成为不同的解析规则。具体来说,通过使它们成为两个替代解析规则,您赋予 PLUS 的优先级高于减号,并且 PLUS 和 MINUS 在评估顺序上应具有相同的优先级。因此,它们需要是相同的解析规则。)。当您在解析器规则中放置这样的备选方案时,您也在建立优先级,因此请注意这些规则的顺序。

不过,除了加减整数之外,您还需要 lexpr 和 rexpr 实际上是表达式本身(您应该阅读 ANTLR 书中的表达式解析;它的介绍非常好)。

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

关于javascript - 在 ANTLR4 中使用访问者的正确方法(javascript 目标),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34820927/

相关文章:

java - 在java中使用antlr4 C#语法

javascript - 如何根据 JavaScript 中的整数对字符串进行排序?

java - 使用 ANTLR 语法进行 Verilog 解析

javascript - 如何获取地理位置并显示在 map 上

parsing - 在 ANTLR4 中使用什么来解决歧义(而不是句法谓词)?

java - ANTLR4 - 树模式匹配代码错误

java - 如何序列化 antlr3 AST

exception - antlr4 在 .g4 语法文件上工作正常,但 gradle generateGrammarSources 在同一个文件上失败,TokenStreamException : unexpected char: '-'/"

javascript - 无法更改 Cordova 3.5 的 index.html 文件

javascript - 是否可以从表单提交将 var 字符串变量发送到 mysql?还是安全漏洞?