2016-04-21 63 views
1

我使用antlr4(4.5.3)与JavaScript的目标,并试图实现访问者。Antlr4 Javascript的目标 - 与访问者问题和标签替代

继antlr4本书的计算器示例(伟大的书BTW)我试图创建一个类似的语法:

... 
expr: expr op=(​'*'​|​'/'​) expr  # MulDiv 
    | expr op=(​'+'​|​'-'​) expr  # AddSub 
    | INT       # int 
    | ​'('​ expr ​')'​    # parens 
    ; 
... 

问题:为标记的替代物创建访问者方法(例如visitMulDiv),但是2缺少的东西:

  1. 在基地访问者原型中执行visitExpr
  2. 当调用this.visit(ctx.expr())时,自动检测正确的选项 - 意思是访问正确的visitX方法。

这就是本书如何实现Java的访问者。

我已经通过实施visitExpr()和黑客上下文c'tor名称(类似于here)来解决此问题,但感觉JS应该可以免费使用,就像Java版本一样。

这是一个错误还是我错过了什么?

回答

2

我相信这是一个错误。在运行时源代码中,最新的javascript运行时(4.5.2)中的ParseTreeVisitor.visit与python2版本(4.5.3)有点不同。在python2版本中,ParseTreeVisitor.visit利用RuleContext.accept方法来触发不同的访客事件。我认为Antlr4的开发人员忘记更新JavaScript运行时。

有快速的解决方法。

antlr4 /树/ Tree.js

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) 
}; 

有不修改库函数更好的方法。

ValidatorVisitor.prototype.visitExpr = function(ctx) { 
    return ctx.accept(this); 
} 
+0

感谢 - 这个伟大工程。因为我不想修改库函数,所以在我的ValidatorVisitor.prototype.visitExpr() – Froyke

+0

的实现中使用了相同的概念。您的解决方案更好!我已经更新了我的答案。 – gzc

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); 
    } 
};