2012-10-30 38 views
1

的語法分析器文法
protocol.g如何操縱樹語法

grammar protocol; 

options { 
    language = Java; 
    output = AST; 
    ASTLabelType=CommonTree; 
} 

tokens{ 
TRANSITIONS; 
PAIR; 
} 

@header { 
package com.javadude.antlr3.x.tutorial; 
} 

@lexer::header { 
    package com.javadude.antlr3.x.tutorial; 
} 

parse 
: transitions EOF! 
    { 
    CommonTree root = $transitions.tree; 

    int count = root.getChildCount(); 

    Tree child1 = root.getChild(0); 
    Tree child2 = root.getChild(1); 
    Tree child3 = root.getChild(2); 
    Tree child4 = root.getChild(3); 

    System.out.println("root=" + root.getToken().getText() + " has " + count + " child nodes:"); 
    System.out.println(" - child1=" + child1.toStringTree()); 
    System.out.println(" - child2=" + child2.toStringTree()); 
    System.out.println(" - child3=" + child3.toStringTree()); 
    System.out.println(" - child4=" + child4.toStringTree()); 
    } 
; 
transitions 
: 'transitions' '=' INT pair+ ';' -> ^(TRANSITIONS INT pair+) 
; 
pair 
: '(' INT ',' INT ')' -> ^(PAIR INT INT) 
; 

INT 
    : ('0'..'9')+; 
WHITESPACE 
    : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;}; 

樹語法
protocolWalker.g

tree grammar protocolWalker; 

options { 
    language = Java; 
    tokenVocab = protocol; 
    ASTLabelType = CommonTree; 
} 


@header { 
package com.javadude.antlr3.x.tutorial; 
} 

transitions 
: ^(TRANSITIONS INT pair+) 
{ 
System.out.println("transitions=" + $INT.text); 
} 
; 

pair 
: ^(PAIR a=INT b=INT) 
{ 
System.out.println("pair=" + $a.text + ", " + $b.text); 

} 
; 

JAVA TEST RIG
Protocoltest.java

package com.javadude.antlr3.x.tutorial; 
import org.antlr.runtime.*; 
import org.antlr.runtime.tree.CommonTree; 
import org.antlr.runtime.tree.CommonTreeNodeStream; 
public class Protocoltest { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) throws Exception { 
     //create input stream from standard input 
     ANTLRInputStream input = new ANTLRInputStream(System.in); 
     //create a lexer attached to that input stream 
     protocolLexer lexer = new protocolLexer(input); 
     //create a stream of tokens pulled from the lexer 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 

     //create a parser attached to teh token stream 
     protocolParser parser = new protocolParser(tokens); 
     //invoke the program rule in get return value 
     protocolParser.parse_return r =parser.parse(); 

     CommonTree t = (CommonTree)r.getTree(); 
     //output the extracted tree to the console 
     System.out.println("\nAST is: " + t.toStringTree()); 

     //walk resulting tree; create treenode stream first 
     CommonTreeNodeStream nodes = new CommonTreeNodeStream(t); 
     //AST nodes have payloads that point into token stream 
     nodes.setTokenStream(tokens); 

     //create a tree walker attached to the nodes stream 
     protocolWalker walker = new protocolWalker(nodes); 

     //invoke the start symbol, rule parse 
     walker.transitions(); 
     } 
} 

INPUT

transitions = 3(5,0) (5,1) (5,2); 

OUTPUT

root=TRANSITIONS has 4 child nodes: 
- child1=3 
- child2=(PAIR 5 0) 
- child3=(PAIR 5 1) 
- child4=(PAIR 5 2) 

AST is: (TRANSITIONS 3 (PAIR 5 0) (PAIR 5 1) (PAIR 5 2)) 
pair=5, 0 
pair=5, 1 
pair=5, 2 
transitions=3 

問題
你可以在上面看到,在語法分析器(protocol.g)我可以存儲的過渡root作爲child1,的child2,child3和child4的所有孩子。另外,我已經打印了這些。 在樹語法中,如何存儲這些文件並對這些文件執行操作? 謝謝

+0

你打算做什麼樣的操作? – user1201210

+0

我將實例化Java類(將創建Java對象) 例如,樹中的第一個數字將確定將創建多少個對象,然後,PAIR 5 0將創建一個具有2個參數(5,0)的對象, PAIR 5 1將創建帶有2個參數(5,1)的第2個對象,並且PAIR 5 2將創建帶有2個參數的第3個對象(5,2) –

回答

1

我實例化的Java類(將創建Java對象),例如,在樹中的第一個數字將確定有多少對象將被創建,然後,對5 0將創建2物體參數(5,0),PAIR 5 1將創建帶有2個參數(5,1)的第2個對象,並且PAIR 5 2將創建帶有2個參數(5,2)的第3個對象。

這是一種簡單的方法來創建轉換並向它們添加對,並且它只需要對protocolWalker.g進行小的更改。首先,雖然,這裏的虛擬TransitionsPair類,我將使用:

Transitions.java

import java.util.ArrayList; 


public class Transitions { 
    private ArrayList<Pair> pairs = new ArrayList<Pair>(); 

    public void addPair(Pair pair){ 
     System.out.println(String.format("Added pair %s to transitions", pair)); 
     pairs.add(pair); 
    } 

    @Override 
    public String toString() { 
     return "Pairs: " + pairs; 
    } 
} 

Pair.java

public class Pair { 
    private int a; 
    private int b; 

    public Pair(int a, int b){ 
     this.a = a; 
     this.b = b; 
    } 

    @Override 
    public String toString() { 
     return String.format("(%d, %d)", a, b); 
    } 
} 

這是修改的protocolWalker.g

protocolWalker.g(修改)

tree grammar protocolWalker; 

options { 
    language = Java; 
    tokenVocab = protocol; 
    ASTLabelType = CommonTree; 
}  


@header { 
    package com.javadude.antlr3.x.tutorial; 
    import java.util.List; 
    import java.util.ArrayList; 
} 

@members { 
    //stores all the transitions objects as they get processed 
    private ArrayList<Transitions> allTransitions = new ArrayList<Transitions>(); 

    //returns all the transitions 
    public List<Transitions> getAllTransitions() { 
    return allTransitions; 
    } 
} 


transitions 
@init { 
     //create a Transitions object when the rule is hit 
     Transitions transitions = new Transitions(); 

     //store it to be accessed later. 
     allTransitions.add(transitions); 
     } 
: ^(TRANSITIONS INT transitions_pair[transitions]+) //pass the object to transitions_pair for each PAIR encountered 
{ 
    System.out.println("transitions=" + $INT.text); 
} 
; 

transitions_pair[Transitions transitions] 
: ^(PAIR a=INT b=INT) 
{ 
    System.out.println("pair=" + $a.text + ", " + $b.text); 
    //make a call to the Transitions object that was passed to this rule. 
    transitions.addPair(new Pair($a.int, $b.int)); 
} 
; 

(我改名爲pairtransitions_pair,因爲該規則現在依賴於轉變建設。)規則transitions調用transitions_pair,同時傳遞新的Transitions對象。 transitions_pair將新的Pair對象添加到收到的Transitions對象。

樹分析器和標記解析器中的規則可以寫成接受使用[ArgType argname,...]方法的對象。在這種情況下,它更容易訪問樹木的兒童PAIR

我增加了一個小改動Protocoltest.java打印出存儲的轉換:

 ... 
     //invoke the start symbol, rule parse 
     walker.transitions(); 

     //get the stored transitions and print them out.    
     List<Transitions> transitions = walker.getAllTransitions(); 
     System.out.println(transitions); 
     ... 

下面是漫步者新的輸出:

pair=5, 0 
Added pair (5, 0) to transitions 
pair=5, 1 
Added pair (5, 1) to transitions 
pair=5, 2 
Added pair (5, 2) to transitions 
transitions=3 
[Pairs: [(5, 0), (5, 1), (5, 2)]] 

這裏是我做了重大變化的概括:

  • 增加了一種方法來存儲和返回來自沃克的轉換。
  • 添加了用於在規則transitions中創建Transitions對象的代碼。
  • 添加了代碼以將對象傳遞給transitions_pair
  • 在測試儀中添加代碼以檢索來自助行器的轉換並將其打印出來。

我想你會在你實現自己的Transitions類的時候全部設置。

+0

非常感謝您提供了這樣詳細的答案,它花了我很長時間才整合到我的項目根據我自己已經編寫的Java類(例如,Transition類)。 我仍然在努力根據我的課程修改此語法,如果遇到任何問題,我會通知您。 再次,非常感謝 –