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

时间:2011-05-13 03:43:55

标签: parsing compiler-construction antlr abstract-syntax-tree

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

在我看来,ANTLRWorks解释器输出的是我正在寻找的东西。在ANTLRWorks解释器中,它输出树图,其中,对于匹配的每个规则,创建节点,以及每个令牌和/或子规则的子节点。解析树,我猜它叫。

如果手动走树,让节点标记规则会不会更有用?通过使节点标记规则,将其子规则和标记作为子节点,手动步行者无需向前看几个节点以了解其所在节点的上下文。树语法对我来说似乎是多余的。给定AST节点树,树语法再次“解析”节点以产生一些其他输出。 B)鉴于解析器语法负责生成正确形成的AST并且包含规则AST节点,手动助行器是否应该避免树语法的冗余AST节点模式匹配?

我担心我对树语法机制的目的产生了极大的误解。树语法或多或少地定义了一组将在树中运行的方法,查找与树语法规则匹配的节点模式,并基于此执行某些操作。我不能依赖于根据树语法的整洁而形成我的AST输出(省略模式匹配速度的无意义令牌),而是使用AST进行颜色编码甚至是无意义的令牌。我也在写一个IDE;我也不能编写插件作者可能想要匹配的每个可能的AST节点模式,也不想要求他们使用ANTLR来编写树语法。在插件作者按照自己的标准行走树的情况下,规则节点对于避免需要模式匹配非常有用。

思考?我知道这个“问题”可能会推动成为一个SO问题的极限,但我不确定如何制定我的询问或在何处查询。

1 个答案:

答案 0 :(得分:4)

  

Sion Sheevok写道:

     

A)为什么我不应该让AST服务于多个用途而选择不省略所述令牌?

不,你也介意把它们留在那里。

  

Sion Sheevok写道:

     

在我看来,ANTLRWorks解释器输出的是我正在寻找的东西。在ANTLRWorks解释器中,它输出树图,其中,对于匹配的每个规则,创建节点,以及每个令牌和/或子规则的子节点。解析树,我猜它叫。

正确。

  

Sion Sheevok写道:

     

B)鉴于解析器语法负责生成正确形成的AST并且包含规则AST节点,手动助行器是否应该避免树语法的冗余AST节点模式匹配?

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

如果需要单独的树步行器/迭代器,那么有两个阵营提倡使用树语法,其他阵营选择使用自定义迭代器手动移动树。两个阵营都提出了关于他们首选的AST行走方式的有效观点。所以没有一种明确的方式可以用一种特定的方式来实现它。

  

Sion Sheevok写道:

     

思想?

由于您没有评估/解释,您还要注意不要使用树语法。

但是要像ANTLRWorks那样创建一个解析树(你无法访问,btw),你需要在解析器语法中混合使用AST重写规则。这是一个Q& A,解释了如何做到这一点:How to output the AST built using ANTLR?

祝你好运!