6

我正在开发一种工具,它将对程序执行一些简单的转换(如提取方法)。为此,我必须执行编译的前几个步骤(标记化、解析并可能构建符号表)。我将从 C 开始,然后希望将其扩展到支持多种语言。

我的问题是,执行这些步骤的最佳方法是:

1.) 不会重新发明轮子。显然我不想手动编写 Flex/Bison 规范。我是否只是获取预先存在的规范并从那里开始工作?Antlr是去这里的路吗?

2.) 可扩展到多种语言。显然,每个人的词法分析/解析都会有所不同,但我想要一个可以轻松扩展到其他语言的解决方案。至少有一套技术可以使这变得易于管理。

顺便说一句,我正在使用 C 编写我的应用程序

如果有人有任何想法,那就太好了!谢谢!

4

5 回答 5

7

放下任何解析的最佳方法是ANTLR。作者有两本关于这个主题的好书是必须的。The Definitive ANTLR Reference: Building Domain Specific LanguagesLanguage Implementation Patterns都是非常宝贵的资源。ANTLR 可以生成许多不同语言的处理代码。

于 2010-02-12T15:31:06.227 回答
4

由于您将使用已经编写好的语法和正则表达式,因此您对工具的选择是无用的。

你可以使用flex / bison,你会发现很多语法已经写好了。否则,您可以使用应该在 C、C++ 和 Java 上毫无问题地工作的ANTLR ,并为它做同样的事情。

您没有谈到您将在这项工作中使用哪种语言,因此提出更好的方法并不容易。

想想每种语言都有自己的特点,例如,与 C++ 相比,Ruby 中符号表的构造方式不同。那是因为你可以有更严格或更宽松的声明等等..所以你应该好好想想你需要什么(你也可以在你的问题中解释它,所以我可以提供更好的帮助)。

在你的两个阶段中,我可以说

  • 标记化非常简单,不需要每种语言都有不同的结构,并且可以轻松扩展以支持过多的编程语言。

  • 解析可能更困难。你必须建立一个程序的抽象语法树,然后在上面做任何你想做的事情。如果你喜欢 OOP 风格,你必须为每个节点类型使用一个类,但是节点类型可以在语言之间改变,因为它们在结构上是不同的,所以做一些通用的并且很容易扩展到其他语言的东西是相当棘手的..

在这一点上,ANTLR 战胜了 Flex 和 Bison,因为它提供了 AST 的自动生成(如果我没记错的话)。

这两个编译器的编译器之间的主要区别在于,ANTLR 使用LL(k)解析器(即自上而下),而 Bison 使用自下而上的LALR(1) ,但如果您使用已经编写的语法,则不应该没那么难。

个人建议:我编写了许多解释器或编译器,但从未从功能齐全的语言开始。C语法真的很大,所以也许你应该从一个子集开始,然后看看你可以用标记和 AST 做什么,然后扩展它以支持完整的语法。

于 2010-02-12T15:33:37.813 回答
2

你用什么语言编写程序?

我会选择 antlr(实际上我会选择解析 Java)。它支持很多语言,也有很多示例语法,您可以免费获得http://www.antlr.org/grammar/list。不幸的是,它们不一定是完美的(Java 语法没有 AST 规则),但它们为您提供了一个良好的开端,我想社区对于解析器生成器来说相当大。

除了许多语言目标之外,antlr 的伟大之处在于 LL(*) 与 antlr 支持的谓词结合起来非常强大且易于理解,生成的解析器也是如此。

对于“可扩展为多种语言”,我想您的意思是多种源语言。这并不容易,但我想你可能会在将它们翻译成具有尽可能多的通用符号的 AST 并编写一个可以处理这些语言差异的通用 tree walker 时取得一些成功。但这可能非常困难。

但是请注意,只有在您阅读了官方 antlr 书籍并理解了 LL(*) 以及语义和句法谓词之后,在线文档才有效。

于 2010-02-12T15:40:40.077 回答
1

你没有指定语言,所以我只推荐我前几天找到的这个小宝石:

http://irony.codeplex.com/

它使用起来超级简单,甚至还为多种语言(甚至 C#)预先构建了语法。如果您想使用 Python 作为源语言,还有 pyparsing ( http://pyparsing.wikispaces.com/ )。

于 2010-02-12T15:25:57.210 回答
-2

要通过的一扇门是 Eclipse。它具有针对多种语言的解析,包括容错解析。Eclipse 具有内部模块化,允许您在不接触 IDE 的情况下利用此功能。

于 2010-02-12T15:31:30.183 回答