我正在用scala编写一个玩具编译器。目标语言本身看起来像scala,但它是一个开放的实验领域。
经过几次大的重构之后,我找不到一种很好的方法来建模我的抽象语法树。我想使用scala的模式匹配工具,问题是树在编译过程中携带移动信息(如类型、符号)。
我可以看到几种解决方案,但我不喜欢:
我也不确定使用完全不变的AST是否是一个好做法,特别是在scala中,那里没有隐式共享(因为编译器不知道不可变),而且总是复制树可能会损害性能。
您能想到一个优雅的模式来使用scala强大的类型系统来建模我的树吗?
发布于 2012-07-23 15:22:25
TL;DR我更喜欢将AST保持不变,并在单独的结构(例如Map )中携带类型信息,这些信息可以由存储在AST中的ID引用。但没有完美的答案。
你绝不是第一个回答这个问题的人。让我列举一些选择:
1)在每个阶段更新的可变结构。你提到的所有优点和缺点。
2)性状/饼型。可行,但昂贵(没有分享),有点丑陋。
( 3)每个阶段都有一个新的树型。在某些方面,这是理论上最干净的。每个阶段只能处理上一阶段为其生成的结构。另外,同样的方法从前端一直到后端。例如,您可能会在某个时候"desugar“,并且有一个新的树类型意味着下游阶段甚至不需要考虑节点类型被取消的可能性。此外,低级别优化通常需要比原始AST低得多的IRs。但是这也是大量的代码,因为几乎所有的东西都必须在每一步重新创建。这种方法也可能很慢,因为在各个阶段之间几乎没有数据共享。
4)用ID标记AST中的每个节点,并使用该ID引用其他数据结构(映射和向量等)中的信息,这些结构保存着为每个阶段计算的信息。在很多方面,这是我的最爱。它保持不变,最大限度地共享和最小化您必须编写的“多余”代码。但是,您仍然需要处理“丢失”信息的可能性,这些信息很难调试。它也没有可变选项那么快,尽管比在每个阶段都需要生成一个新树的任何选项都快。
发布于 2012-07-23 15:16:09
最近,我开始为一种小型语言编写一个玩具验证器,我正在为解析器、解析器和类型检查器阶段使用基亚马库。
Kiama是一个用于语言处理的Scala库。它可以方便地分析和转换结构化数据。库支持的编程样式基于众所周知的正式语言处理范式,包括属性文法、树重写、抽象状态机和漂亮印刷。
我将尝试总结我(相当有限的)经验:
总结一下我的总结,我非常喜欢使用Kiama,我强烈建议您尝试一下,或者至少看一下示例。
(PS. )我没有隶属于Kiama)
https://stackoverflow.com/questions/11614804
复制相似问题