对于像这样的语法,如何保留产生式出现的顺序。
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*
) >METHODMETHOD 方法*
),因为产生式明确指出先处理 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 测试语法,请使用它打开(或创建)语法:
然后按CTRL+D启动调试器(不要使用解释器,它有问题!):
将您的输入粘贴到弹出的窗口中,并确保选择正确的开始生产规则(在本例中为klass
)。然后按确定。
启动调试器后,按end-arrow按钮>|解析输入,然后单击AST按钮查看解析器创建的 AST 是什么样的:
关于java - 在 ANTLR AST 中保留生产订单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12751598/