我正在尝试为以下代码编写作品(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。
答案 0 :(得分:3)
不可能为规则创建ANTLR v3语法:
FieldAccess -> Exp NAME
Exp -> FieldAccess
ANTLR v4 可以处理左递归,但只有直接左递归规则:
Exp -> Exp '*' Exp
| Exp '/' Exp
| Exp '+' Exp
...
| Name
...
(伪语法语法!)
但是v4也 无法 直接左递归规则
FieldAccess -> Exp NAME
Exp -> FieldAccess
我很确定你可以让ANTLR创建一个AST就像Eclipse使用一些奇特的AST重写规则一样,但是你会编辑你的问题并“绘制”(或发布一张图片)所需的AST输入a[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
规则,但如果你把它们放在那里,就会有那样的结构。)