2013-01-09 33 views
3

假設我有這個簡單而毫無意義的語法:tree構造:傳播子樹子

propagate  : what^ where*; 
what   : CHAR^; 
where   : NUMBER -> ^(PLUS NUMBER); 

NUMBER  : '0'..'9'; 
CHAR   : 'a'..'z'; 
PLUS   : '+'; 

如果它解析像a123456789一個字符串,它會產生像一個AST: AST

我所要做的就是將通過what解析的標記傳遞給where並創建AST(對於相同的輸入),如: AST2

我試圖以下列方式:

propagate  : w=what^ where[$w.text]*; 
what   : CHAR^; 
where[String s] : NUMBER -> ^(PLUS CHAR[s] NUMBER); 

NUMBER   : '0'..'9'; 
CHAR   : 'a'..'z'; 
PLUS   : '+'; 

它的工作原理,如果what它是一個單一的道理,但如果它是什麼樹? 這是正確的方法嗎?

回答

3

方法如下:

grammar T; 

options { 
    output=AST; 
    ASTLabelType=CommonTree; 
} 

parse 
: propagate EOF! 
; 

propagate 
: what^ where[$what.tree]* 
; 

what 
: CHAR 
; 

where[CommonTree lhs] 
: NUMBER -> ^(PLUS {new CommonTree($lhs)} NUMBER) 
; 

NUMBER : '0'..'9'; 
CHAR : 'a'..'z'; 
PLUS : '+'; 

ANTLRWorks'調試程序可能無法顯示正確的AST:創建一個小型驅動程序類自己:

import org.antlr.runtime.*; 
import org.antlr.runtime.tree.*; 
import org.antlr.stringtemplate.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    TLexer lexer = new TLexer(new ANTLRStringStream("a123")); 
    TParser parser = new TParser(new CommonTokenStream(lexer)); 
    CommonTree tree = (CommonTree)parser.parse().getTree(); 
    DOTTreeGenerator gen = new DOTTreeGenerator(); 
    StringTemplate st = gen.toDOT(tree); 
    System.out.println(st); 
    } 
} 

要運行它,這樣做:

java -cp antlr-3.3.jar org.antlr.Tool T.g 
javac -cp antlr-3.3.jar *.java 
java -cp .:antlr-3.3.jar Main > ast.dot

這將導致代表以下AST的DOT文件:

enter image description here

+0

如果'a'是一棵樹(有孩子),它似乎只傳播樹的根(只有'a'沒有孩子),你能檢查它嗎?也許它取決於'CommonTree'的構造函數? –

+0

@SalvatoreD。,好吧,你問的不是嗎?你的例子和我的演示也一樣。也許編輯你的問題並重新翻譯它,或者添加更多的例子。 –

+0

我的問題是如果我想用它的孩子而不是單個節點傳播一棵整棵樹。你的演示和我的代碼只傳播一個令牌或樹的根。如果在演示中'a'有兩個名爲'b'和'c'的孩子,我會說:'... ^(PLUS ^(abc)1)^(PLUS ^(abc)2)... ' –