2010-12-19 11 views
1

私は次の文法を作成しました。Javaでツリーを返すインタプリタを構築する方法を考えています。これは後でスクリーンに印刷するために使用できます。 。ANTLR式インタープリタ

grammar myDSL; 

options { 
    language = Java; 
} 
@header { 
    package DSL; 
} 
@lexer::header { 
    package DSL; 
} 


program 
    : IDENT '={' components* '}' 
    ; 


components 
    : IDENT '=('(shape)(shape|connectors)* ')' 
    ; 

shape 
    : 'Box' '(' (INTEGER ','?)* ')' 
    | 'Cylinder' '(' (INTEGER ','?)* ')' 
    | 'Sphere' '(' (INTEGER ','?)* ')' 
    ; 

connectors 
    : type '(' (INTEGER ','?)* ')' 
    ;  

type 
    : 'MG' 
    | 'EL' 
    ; 

IDENT: ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'0')*; 

INTEGER: '0'..'9'+; 

// This if for the empty spaces between tokens and avoids them in the parser 
WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel=HIDDEN;}; 

COMMENT: '//' .* ('\n' | '\r') {$channel=HIDDEN;}; 

答えて

3

発言のカップル:

デフォルトのターゲット言語であるJavaの、の言語を設定する必要はありません。だから、これを削除することができます

options { 
    language = Java; 
} 

あなたIDENTにエラーが含まれています:'0'..'0')はおそらく'0'..'9')をする必要があります

IDENT: ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'0')*; 

サブルール(INTEGER ','?)*も、1 2 3 4などのソースに一致します(カンマはまったくありません)。おそらくあなたはするつもりだった:(INTEGER (',' INTEGER)*)?

今、あなたの質問:ANTLRは適切なASTを構築する方法?これはオプションのブロックでoutput = AST;を追加することによって行うことができます。rule: a b c -> ^(c b a)

options { 
    //language = Java; 
    output = AST; 
} 

そして、どちらかあなたのパーサー規則で、「ツリー・オペレーター」^!を追加、またはツリーの書き換えルールを使用して。

「ツリー演算子」^は(サブ)ツリーのルートを定義するために使用され、!は(サブ)ツリーからトークンを除外するために使用されます。

書き換え規則は^(/* tokens here */)です。最初のトークン(^(の直後)が(サブ)ツリーのルートであり、以降のすべてのトークンがルートの子ノードです。

例があるかもしれません。

program 
    : IDENT '={' components* '}' 
    ; 
あなたは components*子供、 IDENTがルートであるようにしたいとあなたが木から ={}を除外する:のはあなたの最初のルールを見てみましょう。あなたは行って、それを行うことができます。

program 
    : IDENT^ '={'! components* '}'! 
    ; 

かでをやって:

program 
    : IDENT '={' components* '}' -> ^(IDENT components*) 
    ;