保留ANTLR AST中的生产订单

时间:2012-10-05 17:57:43

标签: java antlr grammar abstract-syntax-tree

对于像这样的语法,如何保存作品出现的顺序。

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
}

所有字段最终都在单个列表中,方法在第二个列表中。保存订单的正确方法是什么?我试过......

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

我甚至尝试在两者之间插入假头而没有运气。

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

但这不起作用。

1 个答案:

答案 0 :(得分:2)

在第一种情况下,CLASS节点包含一系列FIELD个节点(FIELD fields*),后跟一系列METHOD个节点(METHOD methods*)因为制作明确指出要一起处理field个表达式,然后一起处理method个表达式:

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

你没有提到第二种和第三种方法产生了什么,但它可能不如第一种方法理想。

使用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测试语法,请用它打开(或创建)语法:

enter image description here

然后按 CTRL + D 启动调试器(不要使用解释器,这是错误的!):

enter image description here

将输入粘贴到弹出的窗口中,并确保选择正确的开始生产规则(在本例中为klass)。然后按确定

启动调试器后,按结束箭头按钮> | 解析输入,然后单击 AST 按钮看看解析器创建的AST是什么样的:

enter image description here