ANTLR從接觸到搭建完畢


antlr4官網:http://www.antlr.org

antlr3官網:http://www.antlr3.org

剛剛成功實現從java程序中調用antlr生成的語法文件。特此記錄下。

首先需要一個php的文法文件:

https://code.google.com/p/phpparser

發現這個Php.g不能使用antlr v4編譯,下載v3的antlrworks,發現一調試一堆錯誤,很多類似

[20:04:04] E:\output\PhpParser.java:10655: 錯誤: 需要<標識符>
[20:04:04] public final void synpred23_Php_fragment() throws {

的錯誤,不明原因。

那就不要IDE了,直接下載

http://www.antlr3.org/download.html   ->   Complete ANTLR 3.5 Java binaries jar

里面已經包括了java的runtime。(如果使用其他語言還需要下載那個語言的runtime)

python:(需先下載python的runtime,然后安裝他,注意python的版本得根據runtime的版本,antlr_python_runtime-3.1.3這個只能支持python2.4 2.5啊。)

http://www.antlr.org/wiki/display/ANTLR3/Antlr3PythonTarget

支持的python版本太低了,新版antlr4里面runtime又只有java的,那就用java把。


 

下面是一個簡單例子的完整步驟。

1. 下載 antlr-3.5-complete.jar

2. 放在隨便一個目錄,比如D:/antlr/

3. 添加環境變量classpath。在后面追加  D:\antlr\antlr-3.5-complete.jar;

4. 命令行輸入 java org.antlr.Tool ,會打印出參數列表,表示antlr的命令可用了。

5. 新建一個目錄,新建一個文件命名為:E.g    內容為:

grammar E;
 
options{ 
    output=AST;
} 
program : statement + ; 
statement: (expression | VAR '=' expression) ';' ; 
expression : (multExpr (('+' |'-' ) multExpr)*) | STRING; 
multExpr : atom ('*' atom)*; 
atom : INT | '(' expression ')'; 
VAR : ('a'..'z' |'A'..'Z' )+ ; 
INT : '0'..'9' + ; 
STRING : '"' (('A'..'Z' | 'a'..'z' | ' ') +) '"' ; 
WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;

這是一個識別算術式子和字符串的文法,下面用antrl生成詞法語法分析的文件。

6. 進入到該文件的目錄,命令行輸入  java org.antlr.Tool E.g ,這時會生成三個文件 E.tokens  ELexer.java  EParser.java.

7. 接下來需要對生成的java代碼編譯運行,首先需要一個主函數,在該目錄新建一個文件命名為 run.java。輸入內容:

import org.antlr.runtime.*; 
import org.antlr.runtime.tree.*; 
public class run {
    public static void main(String[] args) throws Exception  {
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        ELexer lexer = new ELexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        EParser parser = new EParser(tokens);
        EParser.program_return r = parser.program();
        System.out.println(((BaseTree)r.getTree()).toStringTree());  }
} 

這里的parser.program()中program()是我們文法的起點,就是第一條規則的名字,如果不是這個則需要修改,同時.program_return中下划線前面的部分跟隨一起修改。

8. 編譯所有的.java文件。命令行輸入: javac *.java ,生成class文件后,執行run。輸入 java run。此時需要輸入參數,輸入

2+4*5;

str="hello";

^Z

^Z是按Ctrl+Z產生的,表示輸入結束。回車后發現結果

2 + 4 * 5 ; str = "hello";

表示運行成功了,至於為什么打印這個結果是因為run.java里使用了toStringTree(),更多的API可見

http://www.antlr3.org/api/

9. 學習API,更詳細的分析生成的抽象語法樹。

10. over.

補充:Ast樹的簡單遍歷操作

//轉為CommonTree格式,CommonTree類提供一些操作樹的方法供我們使用
        CommonTree root = (CommonTree)r.getTree();
        
        //輸出樹的string格式
        System.out.println(root.toStringTree());
        //獲取節點root的子節點個數
        System.out.println(root.getChildCount());
        //獲取root的第1個(從0開始)孩子
        CommonTree se = (CommonTree) root.getChild(1);
        //獲取root的第1個(從0開始)孩子的第2個孩子
        CommonTree th = (CommonTree) se.getChild(2);
        //獲取節點 th 的父節點
        System.out.println(th.getParent());
        //判斷節點 root 是不是根節點
        System.out.println(root.isNil());
        /*這里只寫出幾個簡單的方法供參考,更多的的請參考
        http://www.antlr3.org/api/Java/index.html
        查看 Class CommonTree 和 Class BaseTree 的部分*/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM