问题
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:
- Implementation for
visitExprin the base visitor prototype. - 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