Antlr4 Javascript target - issue with Visitor and labeled alternative

馋奶兔 提交于 2019-12-11 01:51:08

问题


I'm using antlr4 (4.5.3) with Javascript target, and trying to implement a visitor.

Following the antlr4 book's calculator example (great book BTW) I'm trying to create a similar grammar:

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

The issue: visitor methods are created for the labeled alternatives (for example visitMulDiv) however 2 thing are missing:

  1. Implementation for visitExpr in the base visitor prototype.
  2. Auto detection of the correct alternative when calling this.visit(ctx.expr()) - meaning visiting the correct visitX method.

This is how visitor in Java is implemented in the the book.

I have worked around this by implementing a visitExpr() and hacking the context c'tor name (similar to here) but feel the JS should work hack free, just like the Java version.

Is it a bug or am I missing something?


回答1:


I believed this is a bug. In runtime source code, ParseTreeVisitor.visit in the latest javascript runtime(4.5.2) is a bit different from python2 version(4.5.3). In python2 version, ParseTreeVisitor.visit leverage RuleContext.accept method to trigger different visitor events. I assumed developers of Antlr4 forgot to update javascript runtime.

There is quick workaround.

antlr4/tree/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)
};

There is a better way which doesn't modify library function.

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



回答2:


I believe that this problem has been fixed in 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);
    }
};


来源:https://stackoverflow.com/questions/36758475/antlr4-javascript-target-issue-with-visitor-and-labeled-alternative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!