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.c1or之类的表达式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 回答