Parsing 我应该如何构造和遍历ANTLR3语法的AST输出?

Parsing 我应该如何构造和遍历ANTLR3语法的AST输出?,parsing,compiler-construction,antlr,abstract-syntax-tree,Parsing,Compiler Construction,Antlr,Abstract Syntax Tree,文档和一般建议是,抽象语法树应该省略没有意义的标记。(“记录有意义的输入标记(且仅记录有意义的标记”-最终ANTLR引用)IE:在C++ AST中,你会忽略类的开始和结束的括号,因为它们没有意义,只是为了解析目的而勾画类开始和结束的机制。我理解,为了快速有效地遍历树,剔除无用的令牌节点是有用的,但为了适当地为代码着色,我需要这些信息,即使这些信息对代码的含义没有帮助。A)有什么理由我不应该让AST服务于多个目的,并且选择不忽略所述标记? 在我看来,ANTLRWorks解释器输出的内容正是我想要的

文档和一般建议是,抽象语法树应该省略没有意义的标记。(“记录有意义的输入标记(且仅记录有意义的标记”-最终ANTLR引用)IE:在C++ AST中,你会忽略类的开始和结束的括号,因为它们没有意义,只是为了解析目的而勾画类开始和结束的机制。我理解,为了快速有效地遍历树,剔除无用的令牌节点是有用的,但为了适当地为代码着色,我需要这些信息,即使这些信息对代码的含义没有帮助。A)有什么理由我不应该让AST服务于多个目的,并且选择不忽略所述标记?

在我看来,ANTLRWorks解释器输出的内容正是我想要的。在ANTLRWorks解释器中,它输出一个树形图,其中,对于每个匹配的规则,将创建一个节点,以及每个令牌和/或子规则的子节点。解析树,我想它被称为

如果手动遍历树,让节点标记规则不是更有用吗?通过让一个节点标记一个规则,并将其子规则和标记作为子规则,手动漫游器不需要向前看几个节点就可以知道它所在节点的上下文。树语法对我来说似乎是多余的。给定一个AST节点树,树语法再次“解析”节点,以生成其他输出B)考虑到解析器语法负责生成正确格式的AST,并且包含规则AST节点,手动助行器不应该避免树语法的冗余AST节点模式匹配吗?

我担心我完全误解了树语法机制的用途。树语法或多或少地定义了一组方法,这些方法将在树中运行,查找与树语法规则匹配的节点模式,并在此基础上执行一些操作。我不能依赖于根据树语法的整洁程度来形成AST输出(省略无意义的标记以提高模式匹配速度),但使用AST进行颜色编码,即使是无意义的标记。我也在写一个IDE;我也不能编写插件作者可能想要匹配的所有可能的AST节点模式,也不想要求他们使用ANTLR编写树语法。在插件作者为自己的标准遍历树的情况下,规则节点对于避免需要模式匹配非常有用

想法?我知道这个“问题”可能会把它推到一个SO问题的极限,但我不知道该如何表述我的查询,或者在哪里查询

锡安·希沃克写道:

A)我有什么理由不让AST服务于多种用途,不选择省略上述代币吗?

不,你介意把它们放在那里

锡安·希沃克写道:

在我看来,ANTLRWorks解释器输出的内容正是我想要的。在ANTLRWorks解释器中,它输出一个树形图,其中,对于每个匹配的规则,将创建一个节点,以及每个令牌和/或子规则的子节点。解析树,我想它被称为

锡安·希沃克写道:

B)考虑到解析器语法负责生成正确格式的AST,并且包含规则AST节点,手动助行器不应该避免树语法的冗余AST节点模式匹配吗?

树语法通常用于混合自定义代码以评估/解释输入源。如果您在解析器语法中混合了这些代码,并且解析器中出现了一些回溯,那么这些自定义代码的执行可能会超出预期。使用树语法遍历树(如果操作正确)只能以一种方式执行,从而导致自定义代码只执行一次

但是如果需要单独的树遍历器/迭代器,那么有两个阵营主张使用树语法,其他阵营则选择使用自定义迭代器手动遍历树。两个阵营都提出了他们喜欢的步行方式。因此,没有明确的方法以一种特定的方式来实现这一点

锡安·希沃克写道:

想法

既然你不是在评估/解释,你也不介意使用树语法

但要像ANTLRWorks那样创建解析树(顺便说一句,您无权访问),您需要在解析器语法中混合AST重写规则。下面是一个问答,解释了如何做到这一点:


祝你好运

好问题。注意,我冒昧地将标签
antlr3
更改为
antlr
,因为您的问题不仅仅适用于第三版的antlr。我本想添加标记,但一个问题总共只能添加5个标记。@Sion:您之前问过一个关于拥有
类B{std::vector x;}或类似情况,涉及类型不完整的
std::vector
。你删除了那个问题,说它有效。它实际上不起作用:不能用不完整的类型实例化标准库容器。它可能会编译,但结果是未定义的。我打算评估/解释树并生成中间代码表示,但即使使用无意义的标记,我也可以这样做。非常感谢你!向上投票并标记为答案。