1

私は次の文法を作成しました。Javaでツリーを返すインタープリターを作成する方法を教えてください。後で画面に印刷するために使用できます。開始方法については、Imビットスタックを使用します。

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;};
4

1 に答える 1

3

いくつかの意見:

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

options {
  language = Java;
}

エラーIDENTが含まれています:

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

'0'..'0')おそらくそうあるべきです'0'..'9')

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

さて、あなたの質問に関して:ANTLRに適切なASTを構築させる方法は?output = AST;これは、オプションブロックを追加することで実行できます。

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

次に、「ツリー演算子」^!パーサールールに追加するか、ツリー書き換えルールを使用しますrule: a b c -> ^(c b a)

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

書き換えルールに^( /* tokens here */ )は、最初のトークン(直後^()が(サブ)ツリーのルートであり、後続のすべてのトークンがルートの子ノードである場合があります。

例は順番にあるかもしれません。最初のルールを考えてみましょう。

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

そして、あなたIDENTはルート、子になりたい、そしてあなたはツリーからcomponents*除外={したいと思っています。}あなたはそれをすることによってそれをすることができます:

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

または行うことによって:

program
  :  IDENT '={' components* '}' -> ^(IDENT components*)
  ;
于 2010-12-19T16:47:28.437 に答える