从ANTLR语法生成AST:结构内部的数组

时间:2012-04-08 15:58:10

标签: antlr interpreter abstract-syntax-tree

我正在尝试解析并从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.c1MA[1]这样的表达式,但它不解析像STR.c[1]这样的表达式。如果定义了数组访问,则必须是父表达式。我希望下图有所帮助:

AST output

有没有办法修改我的语法来接受那种表达?提前谢谢。

1 个答案:

答案 0 :(得分: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,只需创建一个LOOKUP AST并将 tails 作为子节点添加到此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:

enter image description here

可以通过从左到右走孩子来轻松评估。