2014-10-20 99 views
1

我想用ANTLR4解析一個數學公式到LaTeX的一個子集。例如,它應該將(a+4)/(b*10)解析爲\frac{a+4}{b\cdot 10}使用ANTLR4解析一個公式

我簡單的語法創建一個樹是這樣的:

antlr tree

現在我想實現解析樹聽衆以某種方式構建LaTeX的字符串,而樹進行遍歷。在這裏,我失敗了,因爲要構建像\frac{}{}這樣的字符串,它必須遞歸構建。然而,解析樹漫步者依次訪問一個樹節點(據我所知,以廣度優先的方式)。

我讀過關於解析樹訪問者這可能是我需要的。但是我無法找到一些這些訪問者如何應用的例子。

您能否提供一個例子來說明在這種特定情況下如何解析樹聽者/訪問者?你認爲我的解析器使用ANTLR的方法首先是有意義的嗎?

回答

3

您可以通過實現ParseTreeVisitor接口來創建一個分析樹walker。爲了便於使用,您可以指定Antlr在編譯語法時生成基本訪問者(在Antlrworks中,Run->Generate Recognizer->Next->Generate Visitor->Next->Finish)。基地訪問者將被稱爲MyGrammarBaseVisitor。請注意,訪問者具有泛型類型T,每個訪問方法都應該返回。我建議使用Void進行手動操作,或者使用String以便在代碼生成過程中使用。

在擴展基本訪問者(我假設在這裏我們處理的是String)之後,您需要重寫訪問方法。這些方法以您擁有的語法規則命名。每種方法都會收到一個ParserContext ctx參數,用於訪問子規則和/或獲取終端值。例如,你可以這樣做:

class MyVisitor extends MyGrammarBaseVisitor<String> { 
    @Override 
    public String visitMultiplicative(MyGrammarParser.MultiplicativeContext ctx) { 
     if (ctx.opMult().getText().equals("/")) return "\\frac{" + visit(ctx.expr(0)) + "}{" + visit(ctx.expr(1)) + "}"; 
     else return visit(ctx.expr(0)) + "\\cdot " + visit(ctx.expr(1)); 
    } 
    // visit methods for other rules... 
} 

我假設你multiplicative規則如下multiplicative: expr opMult expr; opMult: '*' | '/';可以在The Definitive Antlr 4 Reference找到更多信息。您也可以在Antlr documentation中找到更多信息和示例。

+0

這個很好用,謝謝!我現在正在使用Antlrworks,就像你所建議的那樣(我之前在命令行中編譯過語法),現在'* Visitor'類已經正確創建。 – Mouagip 2014-10-20 16:46:22

+0

@Mouagip你仍然可以在命令行中做到這一點,只需使用'-visitor'參數!請參閱:https://theantlrguy.atlassian.net/wiki/display/ANTLR4/ANTLR+Tool+Command+Line+Options – Mephy 2014-10-20 16:47:56

+0

感謝您指出。但是直接使用Antlrworks作爲NetBeans插件現在更方便;-)儘管如此,命令行仍然是可能的構建腳本的一個選項。 – Mouagip 2014-10-20 16:52:27