java - 在 ANTLR AST 中保留生产订单

标签 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) 
         ;

但这没有用。

最佳答案

在第一种情况下,CLASS 节点包含一系列 FIELD 节点(FIELD fields*),后跟一系列 FIELD 节点(FIELD fields*) >METHOD 节点(METHOD 方法*),因为产生式明确指出先处理 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)。然后按确定

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

enter image description here

关于java - 在 ANTLR AST 中保留生产订单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12751598/

相关文章:

java - AES 在 java 中解密文本,在 C# 中加密

java - 如何在不使用同步方法或 block 的情况下实现线程安全?

java - 用 Java 读取 VB 5.0 二进制文件

automation - 如何创建重构工具?

ANTLR语法错误

java - JDK 10 支持的计算字符串宽度(像素)的方法是什么

c++ - 处理 C++ 目标中的 ANTLR3 错误

java - 是否可以将ANTLR3语法转换为正则表达式?

parsing - Antlr 解析器运算符优先级

parsing - 类香料语言识别器的语法