2010-01-13 190 views
11

使用F#解析AST来构建解释器的最佳方式是什么?有很多F#示例用于简单的语法(基本算术操作),但我似乎无法找到具有更多功能范围的语言的任何内容。F#解析抽象语法树

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

或者我错过了一些更有效的书写口译手段吗?是否有更有效的每种类型的eval函数,或者可能使用monads?

在此先感谢

回答

13

识别联合看起来是 incrediably有用的,但你会如何 去构建一个大 多种选择? 是否更好地在其他地方定义了类型(例如,加法, 减法,条件,控制 流),并将它们作为 联合中的预定义类型一起定义为 ?

我不确定你在这里问什么;即使有大量选项,DU仍然很容易定义。见例如this blog entry是一种微型语言的DU结构(以及有关编写树型变换的更一般的讨论)。拥有更多案例的DU是很好的事情,并且在编译器/解释器中通常使用这种表示。至于解析,我更喜欢monadic解析器组合器;请查看FParsec或查看this old blog entry。在使用这种解析器组合器之后,我永远无法回到像lex/yacc/ANTLR这样的任何东西 - 外部DSL似乎比较原始。

(编辑:“微小的算术例子”你已经发现可能是什么大的解决方案看起来像,以及在“玩具”的例子通常炫耀正确的架构代表相当多。)

+0

链接到旧博客条目似乎被打破。 – 2013-12-25 06:53:11

2

我自己还没有做过翻译。希望以下帮助:)

Here的耶鲁大学使用ML,你可能会发现有用的编译课程。讲义非常简洁(简短)和内容丰富。你可以按照前几个讲义和作业。正如你所知道的F#,你不会有阅读ML程序的问题。

顺便说一下,这位教授是A. Appel的学生,他是SML实现的创造者。所以从这些笔记中,你也可以得到最自然的方式来编写ML族语言的编译器/解释器。

2

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

除此之外,您需要考虑如何实际执行AST表单中的代码,这是编译器和解释器设计的共同之处。然而,这通常被认为是更容易的部分,并且在那里应该提供关于这方面的信息的编译器/解释器有大量的一般资源。

3

你应该拿一份Robert Pickering的“Beginning F#”。

的第13章, “分析文本”,包含FsLexFsYacc一个例子,通过Noldorin的建议。

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

祝你好运。

+3

很高兴看到人们已经开始阅读开始的F#:)。我应该指出,第12章还介绍了FParsec(http://www.quanttec.com/fparsec/),这是一个monadic解析器,这可能是我在F#中创建解析器的首选,因为它意味着您不必使用外部工具和代码生成。 Rob – Robert 2010-01-13 16:30:20

3

我第二Brian的建议看看FParsec。如果你有兴趣用FsLex和FsYacc做老式的学习方法,那么寻找如何解析非平凡语言的地方就是F#源代码本身。请参阅分发中的source\fsharp\FSharp.Compiler目录。

0

This is F#和FParsec的完整Small Basic实现的一个很好的例子。它甚至包括IL编译器。整个代码是非常容易获得的,并附有来自作者的一系列博客文章http://trelford.com/blog/