Antlr AST 产生(可能的)疯狂
以下情况可能吗?我想“反转”给予 antlr 的输入,并使每个标记成为前一个标记的子标记。
因此,对于输入(假设每个标记由“.”字符分隔):
Stack.Overflow.Horse
我希望我的语法生成以下 AST:
Horse
|---Overflow
|---Stack
到目前为止,我已设法反转节点,但无法创建它们彼此的孩子:
function
: ID PERIOD function
-> function ID
| ID
;
ID : 'a'..'z'*
;
Is the following even possible? I want to "reverse" the input given to antlr and make each token a child of the previous one.
So, for the input (Assume each token is separated by the '.' char) :
Stack.Overflow.Horse
I would like my grammar to produce the following AST:
Horse
|---Overflow
|---Stack
So far, I've managed to reverse the nodes, but I'm unable to make them children of each other:
function
: ID PERIOD function
-> function ID
| ID
;
ID : 'a'..'z'*
;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为没有一个简单的方法可以做到这一点。您可以像这样制定规则:
但这只会使最后一个节点成为根节点,而所有其他节点成为其子节点。例如,以下源:
将生成以下树:
我看不到简单的修复方法,因为当您第一次解析
abcde
时,a
将是ID
和bcde
对function
的递归调用:导致
bcde
将具有a
作为它的孩子。当b
成为ID
时,它也会作为子项添加到a
旁边。在您的情况下,应将a
作为子项删除,然后将其添加到b
的子项列表中。但据我所知,这在 ANLTR 中是不可能的(至少在语法中不可能以干净的方式)。编辑
好吧,作为一种解决方法,我想到了一些优雅的东西,但这并没有像我希望的那样起作用。因此,作为一个不太优雅的解决方案,您可以将
last
节点匹配为重写规则中的根:然后在
中收集所有可能的前面节点(
:children
) >使用+=
运算符列出并在解析器中使用自定义成员方法将这些
子元素
“注入”到树的根中(进入在您的List
中从右到左!):一个小演示:
和一个小测试类:
它将生成一个如下所示的 AST:
对于输入字符串:
I don't think there's an easy way to do that. You could make your rule like this:
but that only makes the last node the root and all other nodes its children. For example, the following source:
will result in the following tree:
I can't see an easy fix since when you first parse
a.b.c.d.e
,a
will be theID
andb.c.d.e
the recursive call tofunction
:resulting in the fact that
b.c.d.e
will havea
as its child. When thenb
becomes theID
, it too is added as a child next toa
. In your case,a
should be removed as a child and then added to the list ofb
's children. But AFAIK, that is not possible in ANLTR (at least, not in a clean way inside the grammar).EDIT
Okay, as a work-around I had something elegant in mind, but that didn't work as I had hoped. So, as a less elegant solution, you could match the
last
node as the root in your rewrite rule:and then collect all possible preceding nodes (
children
) in aList
using the+=
operator:and use a custom member-method in the parser to "inject" these
children
into the root of your tree (going from right to left in yourList
!):A little demo:
And a little test class:
which will produce an AST that looks like:
For the input string: