我有以下语法(我只显示重要的部分)
packageDeclaration
: PACKAGE qualifiedIdentifier SEMI -> ^(PACKAGE qualifiedIdentifier+)
;
qualifiedIdentifier
: ( IDENT -> IDENT
)
( DOT ident=IDENT -> ^(DOT $qualifiedIdentifier $ident)
)*
;
让我说我有一个包“dec。”包“a.b.c”(Java解析器顺便说一句)
我现在得到的是某种形式 (包(。(。a b)c))
我想要的是内联包装以便我得到 (包a.b.c)
我不想更改qualifiedIdentifier的重写,但仅限于packageDeclaration。
我该怎么做。
我理解别名和+现在是什么意思。但是我仍然不清楚重写规则中qualifiedIdentifier和$ qualifiedIdentifier之间的区别。
至于我的第二个问题,我的意思是我删除了qualifiedIdentifier的重写规则,对于包我有以下内容:
packageDeclaration
: PACKAGE ident=qualifiedIdentifier SEMI -> ^(PACKAGE $ident+)
;
我得到的结果是嵌套的标记,如:
(package
(a) [end:a]
(.) [end:.]
(b) [end:b]
(.) [end:.]
(c) [end:c]
) [end:package]
Each token is represented as "(<token's text property>) [end: <token's text property>]"
我希望在上面的输出中清楚但我有一个带有5个孩子的父令牌(包)。现在他们处于正确的顺序和所有这一切。我想要的是同一个父母只有一个孩子,如:
(package
(a.b.c) [end:a.b.c]
) [end:package]
答案 0 :(得分:1)
如果您要从树中删除DOT
,只保留来自a
的令牌b
,c
和import a.b.c;
(带{ {root}当然是{1}}尝试:
PACKAGE
或使用qualifiedIdentifier
: IDENT (DOT IDENT)* -> IDENT+
;
,只需删除重写规则:
DOT
顺便说一下,您的qualifiedIdentifier
: IDENT (DOT IDENT)*
;
中有错误:
packageDeclaration
packageDeclaration
: PACKAGE qualifiedIdentifier SEMI -> ^(PACKAGE qualifiedIdentifier+)
;
应该是qualifiedIdentifier+
。
Coder写道:
我不想更改qualifiedIdentifier的重写,但仅限于packageDeclaration。
这是不可能的。
除非您在qualifiedIdentifier
内未使用qualifiedIdentifier
,否则您可以执行以下操作:
packageDeclaration
关于你的意见:
Coder写道:
我对重写规则中+的含义有点困惑。这里的文档antlr.org/wiki/display/ANTLR3/Tree+construction说你可以把树分成“a:(^(ID INT))+ - &gt; INT + ID +; //将树分成序列” 。
从规则:
packageDeclaration
: PACKAGE IDENT (DOT IDENT)* SEMI -> ^(PACKAGE IDENT+)
;
a
: (^(ID INT))+ -> INT+ ID+
;
表示有一个或多个(^(ID INT))+
和一个或多个ID
,只有这样才能在重写规则中使用INT
(所有内容) - >&gt;的右边。
另一方面,你有:
+
那里只有一个packageDeclaration
: PACKAGE qualifiedIdentifier SEMI
;
,所以你只能在重写规则中使用那个sinle qualifiedIdentifier
(没有qualifiedIdentifier
!)
Coder写道:
我也很困惑在重写规则中指定别名与“PACKAGE ident:qualifiedIdentifier - &gt; $ ident”vs之间的区别,使用quanlifiedIdentifier vs $ quanlifiedIdentifier
如果不明显哪个规则应该放在树中的哪个位置,或者如果您想要更好地控制子项的放置方式,则可以使用别名。例如,给定规则:
+
并且您希望第一个name
: ID '.' ID
;
成为正确的孩子。这样做的:
ID
将第一个ID作为左子项。为了使它成为正确的孩子,请执行以下操作:
name
: ID '.' ID > ^(NAME ID ID)
;
Coder写道:
我得到的结果是嵌套的标记,如:
<强> (SNIP) 强>
每个令牌都表示为......
好的,我明白你的意思了。你必须明白解析器是“词法分析器”的“馈送”。词法分析器会填充字符输入并从这些字符创建标记(name
: a=ID '.' b=ID > ^(NAME $b $a)
;
就是这样的标记,就像IDENT
一样)。然后将这些标记传递给解析器。解析器不能只创建或合并令牌。所以答案是:你想要的东西不容易做到,你的语法里面的“ANTLR语法”当然是不可能的。