2

文法のように、プロダクションが現れる順序を維持する方法。

class: 'class' ID 
        '{' (fields 
         | methods) * '}'         -> ^(CLASS ID ^(FIELD fields*) ^(METHOD methods) 
         ;

プロダクションは期待どおりに機能しますが、次のようなクラスがある場合

class abc {
   field 1 
   field 2
   method 1
   method 2
   field 3
   method 3
   field 4
}

すべてのフィールドは最終的に単一のリストになり、メソッドは 2 番目のリストになります。順序を維持する正しい方法は何ですか? やってみた..

class: 'class' ID 
        '{' (fields               -> ^(FIELD fields)
         | methods                -> ^(METHOD methods)
         )* '}'                   -> ^(CLASS ID $class)
         ;

間にダミーヘッドを挿入してみましたが、うまくいきませんでした。

class: 'class' ID 
        '{' (fields 
         | methods) * '}'         -> ^(CLASS ID ^(FIELD fields*) ^NODE ^(METHOD methods) 
         ;

しかし、これはうまくいきませんでした。

4

1 に答える 1

2

この最初のケースでは、CLASSノードには一連のノード ( ) が含まれ、その後に一連のノードFIELD( FIELD fields*) が続きます。これは、式が一緒に処理され、次に式が一緒に処理されることが明示的に述べられているためです。METHODMETHOD methods*fieldmethod

-> ^(CLASS ID ^(FIELD fields*) ^(METHOD methods)

2 番目と 3 番目のアプローチが何を生み出したかについては触れていませんが、おそらく最初のアプローチほど理想的ではありませんでした。

body代わりに、式を使用して次のアプローチを試してください。

grammar temp;
options {output=AST;}
tokens { KLASS; FIELD; METHOD; }

klass   :   'class' ID body -> ^(KLASS ID body)
        ;

body    :   '{'!
                (field | method) *
            '}'! 
        ;

field   : 'field' INT -> ^(FIELD INT)
        ;

method  : 'method' INT -> ^(METHOD INT)
        ;

ID      : ('a'..'z')+;
INT     : ('0'..'9')+;
WS      : (' '|'\r'|'\n')+ {$channel = HIDDEN;} ;

次の AST 結果が得られます。

-KLASS
   -abc
   -FIELD
      -1
   -FIELD
      -2
   -METHOD
      -1
   -METHOD
      -2
   -FIELD
      -3
   -METHOD
      -3
   -FIELD
      -4

ANTLRWorks で文法をテストしたい場合は、ANTLRWorks で文法を開きます (または作成します)。

ここに画像の説明を入力

CTRL+を押しDてデバッガーを起動します (インタープリターは使用しないでください。バグがあるためです!):

ここに画像の説明を入力

ポップアップするウィンドウに入力内容を貼り付け、正しい生産開始ルール (klassこの場合は ) を選択していることを確認してください。を押しOKます。

デバッガーが起動したら、終了矢印ボタンを押し>|て入力を解析し、ASTボタンをクリックして、パーサーが作成した AST がどのように見えるかを確認します。

ここに画像の説明を入力

于 2012-10-05T20:16:37.380 に答える