scala – 优雅的AST模型

我正在 scala中编写一个玩具编译器.目标语言本身看起来像scala,但是实验的开放领域.

经过几次大的重构,我找不到一个很好的方法来建模我的抽象语法树.我想使用scala的模式匹配的设施,问题是树在编译过程中携带移动信息(如类型,符号).

我可以看到一些解决方案,没有一个我喜欢的:

>具有可变字段的案例类(我相信scala编译器这样做):问题是这些字段不存在于编译的每个阶段,因此必须被置零(或Option’d),并且调试变得非常重/写代码.此外,如果是例如,我在打字阶段之后找到一个空类型的节点,我真的很难找到错误的原因.
>巨大的特征/案例类层次结构:像Node,NodeWithSymbol,NodeWithType,…似乎是一个痛苦的写和工作
一些完美的手工制作与提取

我也不确定这是一个完美不变的AST的好习惯,特别是在没有隐含共享的scala中(因为编译器不知道不可变性),并且可能会伤害表演来复制树.

你能想到一个优雅的图案来模拟我的树,使用scala的强大的类型系统?

解决方法

TL; DR我喜欢保持AST不变,并将类似信息的东西放在单独的结构中,例如一个地图,可以由存储在AST中的ID引用.但是没有完美的答案.

你不是第一个与这个问题斗争的人.让我列举一些选择:

1)在每个阶段得到更新的可变结构.你提到的所有的这一切和缺点.

2)特征/蛋糕图案.可行,但昂贵(没有分享),有点丑陋.

3)每个阶段都有一种新的树型.在某些方面这是理论上最干净的.每个阶段只能处理上一阶段为其生成的结构.同样的方法一直从前端到后端.例如,您可能在某个时间点“脱灰”,并且具有新的树类型意味着下游阶段甚至不必考虑通过停止消除的节点类型的可能性.此外,低级优化通常需要比原始AST显着降低的IR.但是这也是很多代码,因为几乎每一步都必须重新创建.这种方法也可能很慢,因为阶段之间几乎没有数据共享.

4)使用ID标识AST中的每个节点,并使用该ID来引用其他数据结构(映射和向量等)中保存为每个阶段计算的信息的信息.在许多方面这是我最喜欢的.它保留不变性,最大化共享并最大限度地减少您必须编写的“多余”代码.但是,您仍然需要处理可能难以进行调试的“丢失”信息的潜力.它也不如mutable选项那么快,尽管比在每个阶段需要生成一个新树的任何选项要快.

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...