1

ANTLR文法からASTをパーサーして生成しようとしています。構造体内の配列と構造体の配列を解析しようとすると、いくつかの問題が発生します。

これは宣言の例です。

TYPE MY_ARRAY : 
     ARRAY [ 0..2 ] OF INT;
END_TYPE

TYPE est :
     STRUCT
          c1 : INT;
          c : MY_ARRAY;
     END_STRUCT;
END_TYPE

TYPE MSA : 
    ARRAY [ 0..2 ] OF est; 
END_TYPE

VAR 
      MA : MY_ARRAY;
      STR : est;
      STR2 : MSA;
END_VAR

宣言に問題はありません。次のように式を解析するための文法を書くことができません:

STR.c[1]
STR2[2].c[1]

次のコードは、私のANTLR文法の抜粋を示しています。

operand
    : variable_simbolic
    | DIRECT_VAR<Localization>
    | CTE_INT<ConstantINT>
    | CTE_BOOL<ConstantBOOL>
    | CTE_REAL<ConstantREAL>
    ;

variable_simbolic
    : (ID -> ID<Identificador>) ( (('[' operand (',' operand)* ']') -> ^(ARRAY_ACCESS<ArrayAccess> ID<Identificador> operand+))
                    | (('.' operand )   -> ^(FIELD_ACCESS<FieldAccess> ID<Identificador> operand))
                    | (('#' operand )   -> ^(ENUM_ACCESS<EnumAccess> ID<Identificador> operand))
                    )?
    ;

この文法では、STR.c1またはMA[1]のような式を解析できますが、のような式は解析されませんSTR.c[1]。配列アクセスが定義されている場合、それは親式である必要があります。次の図がお役に立てば幸いです。

AST出力

そのような表現を受け入れるように文法を変更する方法はありますか?前もって感謝します。

4

1 に答える 1

1

おそらくこのようなもの:

operand
 : variable_simbolic
 | CTE_INT
 ;

variable_simbolic
 : (ID -> ID) (variable_simbolic_tail -> ^(ID variable_simbolic_tail))?
 ;

variable_simbolic_tail
 : array variable_simbolic_tail?  -> ^(ARRAY_ACCESS array variable_simbolic_tail?)
 | '.' ID variable_simbolic_tail? -> ^(FIELD_ACCESS ID variable_simbolic_tail?)
 | '#' ID variable_simbolic_tail? -> ^(ENUM_ACCESS ID variable_simbolic_tail?)
 ;

array
 : '[' operand (',' operand)* ']' -> ^(ARRAY_OPS operand+)
 ;

編集

少し違う方法を提案します。多くの異なるレベルで複雑なASTを構築しようとする代わりに、単一のLOOKUPASTを作成し、テールをこのastの子ノードとして追加します。

文法の小さな例:

grammar T;  

options {
  output=AST;
}

tokens {
  LOOKUP;
  ARRAY_ACCESS;
  FIELD_ACCESS;
  ENUM_ACCESS;
}

parse
 : operand EOF
 ;

operand
 : variable_simbolic
 | CTE_INT
 ;

variable_simbolic
 : ID variable_simbolic_tail* -> ^(LOOKUP ID variable_simbolic_tail*)
 ;

variable_simbolic_tail
 : '[' operand (',' operand)* ']' -> ^(ARRAY_ACCESS operand+)
 | '.' ID                         -> ^(FIELD_ACCESS ID)
 | '#' ID                         -> ^(ENUM_ACCESS ID)
 ;

CTE_INT : '0'..'9'+;
ID      : ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z'  |'0'..'9')*;
SPACE   : (' ' | '\t' | '\r' | '\n')+ {skip();};

入力を解析するSTR2[2].c[1]と、次のASTが得られます。

ここに画像の説明を入力してください

これは、子供たちを左から右に歩くことで簡単に評価できます。

于 2012-04-08T19:16:46.650 に答える