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
}

所有字段都在单个列表中,方法在第二个列表中。保持秩序的正确方法是什么?我试着做..

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)

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

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

在此处输入图像描述

并按CTRL+D启动调试器(不要使用解释器,它有问题!):

在此处输入图像描述

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

启动调试器后,按end-arrow按钮>|解析输入,然后单击AST按钮查看解析器创建的 AST 的样子:

在此处输入图像描述

于 2012-10-05T20:16:37.380 回答