我正在尝试为以下代码编写作品(LL)
a[i].b[a[p]].id.xyz.a[c].o = i;
在Eclipse中使用ASTView,产品就像
FieldAccess -> Exp NAME
Exp -> FieldAccess
FieldAccess -> ArrayAccess NAME
ArrayAccess -> ArrayAccess Exp
ArrayAccess -> FieldAccess
Exp -> FieldAccess
.....
如何在Antlr中定义以上内容?他们是递归的,据我所知,JAVA是LL.
解决方法:
无法为规则创建ANTLR v3语法:
FieldAccess -> Exp NAME
Exp -> FieldAccess
ANTLR v4可以处理左递归,但是只能使用直接左递归规则:
Exp -> Exp '*' Exp
| Exp '/' Exp
| Exp '+' Exp
...
| Name
...
(伪语法语法!)
但第4版也无法处理您的间接左递归规则:
FieldAccess -> Exp NAME
Exp -> FieldAccess
我敢肯定,就像Eclipse使用一些精美的AST重写规则一样,您可以使ANTLR创建AST,但是您将编辑问题并为输入的AST“画”(或张贴图片)所需的AST. [i] .b [a [p] .x] .id.xyz.a [c] .o = i ;,我可能会受到刺伤.
编辑
这是一个小示例,演示如何在发布的类似AST中解析示例输入:
grammar T;
options {
output=AST;
}
tokens {
ASSIGN;
IND;
FA;
}
parse
: assign EOF -> assign
;
assign
: lookup '=' expr ';' -> ^(ASSIGN lookup expr)
;
expr
: lookup
;
lookup
: (NAME -> NAME) ( array_index -> ^(IND $lookup array_index)
| field_access -> ^(FA $lookup field_access)
)*
;
array_index
: '[' expr ']' -> expr
;
field_access
: '.' NAME -> NAME
;
NAME : 'a'..'z'+;
SPACE : ' ' {skip();};
当我使用输入a [i] .b [a [p] .x] .id.xyz.a [c] .o = i;在ANTLRWorks中调试解析器时,将生成以下AST:
编辑
规则:
lookup
: (NAME -> NAME) ( array_index -> ^(IND $lookup array_index)
| field_access -> ^(FA $lookup field_access)
)*
;
仅此而已:
lookup
: NAME ( array_index^
| field_access^
)*
;
除了第一个遗嘱,对于输入“ a [i] .b”,将创建一个AST,如下所示:
FA
/ \
IND B
/ \
A I
后者会创建一个“反向” AST:
FA
/ \
B IND
/ \
I A
(当然,FA和IND不在最后一个AST中,因为它们不在array_index和field_access规则中,但是如果将它们放在那里,它将具有该结构).