我正在使用带有Javascript目标的antlr4(4.5.3),并尝试实现访问者。
按照antlr4书的计算器示例(好书BTW),我试图创建一个类似的语法:
...
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| '(' expr ')' # parens
;
...
问题:为标记的替代品(例如visitMulDiv)创建了访问者方法,但是缺少了两件事:
visitExpr
的实施。this.visit(ctx.expr())
时自动检测正确的替代方法 - 意味着访问正确的visitX方法。这就是本书中Java的访问者的实现方式。
我通过实现visitExpr()
和黑客攻击上下文名称(类似于here)解决了这个问题,但感觉JS应该像黑客一样工作,就像Java版本一样。
这是一个错误还是我错过了什么?
答案 0 :(得分:2)
我相信这是一个错误。在运行时源代码中,最新的javascript运行时(4.5.2)中的 .inventions:hover{
-webkit-filter: brightness(40%);
}
与python2版本(4.5.3)略有不同。在python2版本中,ParseTreeVisitor.visit
利用ParseTreeVisitor.visit
方法触发不同的访问者事件。我假设Antlr4的开发人员忘了更新javascript运行时。
快速解决方法。
antlr4 /树/ Tree.js
RuleContext.accept
有一种更好的方法可以不修改库函数。
ParseTreeVisitor.prototype.visit = function(ctx) {
// if (Utils.isArray(ctx)) {
// var self = this;
// return ctx.map(function(child) { return visitAtom(self, child)});
// } else {
// return visitAtom(this, ctx);
// }
return ctx.accept(this)
};
答案 1 :(得分:1)
我相信这个问题已在antlr 4.7中修复:
ParseTreeVisitor.prototype.visit = function(ctx) {
if (Array.isArray(ctx)) {
return ctx.map(function(child) {
return child.accept(this);
}, this);
} else {
return ctx.accept(this);
}
};