解決した

Antlr4 Javascriptターゲット - ビジターとラベル付き代替の問題

フロントエンド

私はJavascriptターゲットでantlr4(4.5.3)を使用しており、ビジターを実装しようとしています。

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()を実装し、コンテキストの名前をハックすることでこれを回避しましたが、JavaバージョンのようにJSがハックフリーで動作するように感じます。

それはバグですか、何か不足していますか?


Progress 100%

一番いい

回答

フロントエンド

私はこれがバグだと信じていました。 ランタイムソースコードでは、最新のjavascriptランタイム(4.5.2)のParseTreeVisitor.visitはPython2バージョン(4.5.3)とは少し異なります。 Python2バージョンでは、 ParseTreeVisitor.visitRuleContext.acceptメソッドを利用してさまざまなビジターイベントをトリガーします。 私Antlr4の開発者がjavascriptランタイムを更新するのを忘れてしまったと思った。

迅速な回避策があります。

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

ライブラリ関数を変更しないより良い方法があります。

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