F#解析抽象语法树

时间:2010-01-13 15:59:27

标签: f# language-design abstract-syntax-tree

使用F#解析AST以构建解释器的最佳方法是什么?有很多F#例子用于简单的语法(基本的算术运算),但我似乎找不到任何具有更大范围功能的语言。

受歧视的工会看起来非常有用,但您如何构建具有大量选项的工会呢?是否更好地在其他地方定义类型(例如加法,减法,条件,控制流)并将它们作为联合中的预定义类型组合在一起?

或者我错过了一些更有效的口译员写作方式?每个类型的eval函数是否更有效,或者可能使用monad?

提前致谢

6 个答案:

答案 0 :(得分:13)

  

受歧视的工会看起来像   非常有用,但你会怎么样?   去做一个大的   选项数量?是不是更好   定义类型(比如添加,   减法,条件,控制   在其他地方,只是带来他们   一起作为预定义的类型   工会?

我不确定你在这里问什么;即使有大量选项,DU仍然很容易定义。参见例如this blog entry用于小语言的DU结构(以及关于编写树变换的更一般的讨论)。拥有更多案例的DU是很好的,在编译器/解释器中很常见,可以使用这种表示法。

至于解析,我更喜欢monadic解析器组合;查看FParsec或查看this old blog entry。在使用这样的解析器组合器之后,我再也无法回到像lex / yacc / ANTLR这样的东西 - 外部DSL看起来比较原始。

(编辑:你发现的'微小的算术例子'可能代表了大型解决方案的样子。'玩具'例子通常展示出正确的架构。)

答案 1 :(得分:3)

你应该复制一下Robert Pickering的“Beginning F#”。

第13章“解析文本”包含Noldorin建议的 FsLex FsYacc 的示例。

除此之外,在同一本书的第12章中,作者解释了如何为他提出的算术语言构建一个实际的简单编译器。非常有启发性。最重要的部分是您正在寻找的东西: AST解析器

祝你好运。

答案 2 :(得分:3)

我第二次看到Brian的建议,看看FParsec。如果你对使用FsLex和FsYacc的老派方式感兴趣,那么寻找如何解析非平凡语言的地方就是F#源本身。请参阅发行版中的source\fsharp\FSharp.Compiler目录。

答案 3 :(得分:2)

我自己没有翻译过。希望以下有用:)

Here是耶鲁大学使用ML教授的一门编译课程,你可能觉得它很有用。讲义非常简洁(简短),内容丰富。您可以按照前几个讲义和作业进行操作。如你所知F#,读取ML程序时不会有问题。

顺便说一下,这位教授是A. Appel的学生,他是SML实施的创造者。因此,从这些注释中,您还可以使用最自然的方式编写ML系列语言的编译器/解释器。

答案 4 :(得分:2)

您可能有兴趣查看F#WikiBook的Lexing and Parsing部分。 F# PowerPack library包含 FsLex和FsYacc工具,这对此很有帮助。 WikiBook指南是开始使用它的好方法。

除此之外,您还需要考虑如何从AST表单中执行代码,这在编译器和解释器的设计中很常见。这通常被认为是更容易的部分,并且有很多关于编译器/解释器的一般资源应该提供相关信息。

答案 5 :(得分:0)

This is使用F#和FParsec完成Small Basic实现的一个很好的例子。它甚至包括IL编译器。整个代码非常容易访问,并附有作者http://trelford.com/blog/

的一系列博客文章