2010-11-10 66 views
2

我打了一下週圍的ANTLR,並生成簡單AST希望創建這樣的功能:在ANTLR

MOVE x y z pitch roll 

產生以下AST:

MOVE 
    |---x 
    |---y 
    |---z 
    |---pitch 
    |---roll 

到目前爲止,我我試過沒有運氣,我一直讓AST將參數作爲兄弟姐妹,而不是孩子。

到目前爲止的代碼:

C#:

class Program 
{ 
    const string CRLF = "\r\n"; 

    static void Main(string[] args) 
    { 
     string filename = "Script.txt"; 

     var reader = new StreamReader(filename); 
     var input = new ANTLRReaderStream(reader); 
     var lexer = new ScorBotScriptLexer(input); 
     var tokens = new CommonTokenStream(lexer); 
     var parser = new ScorBotScriptParser(tokens); 

     var result = parser.program(); 
     var tree = result.Tree as CommonTree; 
     Print(tree, ""); 

     Console.Read(); 
    } 

    static void Print(CommonTree tree, string indent) 
    { 
     Console.WriteLine(indent + tree.ToString()); 

     if (tree.Children != null) 
     { 
      indent += "\t"; 

      foreach (var child in tree.Children) 
      { 
       var childTree = child as CommonTree; 

       if (childTree.Text != CRLF) 
       { 
        Print(childTree, indent); 
       } 
      }  
     }    
    } 

ANTLR:

grammar ScorBotScript; 

options 
{ 
    language  = 'CSharp2'; 
    output  = AST; 
    ASTLabelType = CommonTree; 
    backtrack = true; 
    memoize  = true; 
} 

@parser::namespace { RSD.Scripting } 
@lexer::namespace { RSD.Scripting } 

program 
    : (robotInstruction CRLF)* 
    ; 

robotInstruction 
    : moveCoordinatesInstruction 
    ; 

/** 
* MOVE X Y Z PITCH ROLL 
*/ 
moveCoordinatesInstruction 
    : 'MOVE' x=INT y=INT z=INT pitch=INT roll=INT 
    ; 

INT : '-'? ('0'..'9')* 
    ; 

COMMENT 
    : '//' ~(CR | LF)* CR? LF { $channel = HIDDEN; } 
    ; 

WS 
    : (' ' | TAB | CR | LF) { $channel = HIDDEN; } 
    ; 

ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 
    ; 

STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    ; 

fragment TAB 
    : '\t' 
    ; 

fragment CR 
    : '\r' 
    ; 

fragment LF 
    : '\n' 
    ; 

CRLF 
    : (CR ? LF) => CR ? LF 
    | CR 
    ; 

parse 
    : ID 
    | INT 
    | COMMENT 
    | STRING 
    | WS 
    ; 

回答

7

我和ANTLR初學者自己,這弄得我也一樣。

我想如果你想從你的語法結構中創建一棵樹,你可以使用^!這兩個字符來提示你的語法。 This examples page顯示瞭如何。

從鏈接頁面:

默認情況下ANTLR創建樹木 「兄弟名單」。

語法必須註釋以與 樹命令以產生 創建在正確的形狀 樹木解析器(即,運營商在根,這 操作數爲兒童)。更復雜的表達式分析器 可以在這裏看到並以tar格式 在這裏下載。請注意,應該在 子樹的根部的語法終端 用^註釋。

+0

該死的,現在已經看過那麼多次了。它正是我所期望的。非常感謝! – 2010-11-10 11:50:52

+0

大聲笑很高興我可以幫助,祝你好運! – Brabster 2010-11-10 11:51:44