2016-04-21 88 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); 
    } 
};