2009-06-27 77 views
9

自1999年以来,我一直在为编程和乐趣进行编程。我想学习新东西,最近我一直专注于解析,因为我工作的很大一部分是阅读,整合和分析数据。如果开销足够低,我认为我可以用非常简单的特定于领域的语言表达大量的重复性任务。我对这个问题有几个问题。了解关于解析的更多信息

  1. 我目前的大部分解析代码都没有定义正式的语法。我通常用我的选择语言来破解一些东西,因为这很容易,我知道该怎么做,而且我可以非常快地编写代码。对于我一起工作的其他人来说也很容易维护。与大多数程序员用来编写解析器的黑客相比,定义语法和生成真正的解析器(正如ANTLRYACC所做的那样)来解析事情有什么优点和缺点?
  2. 在C++,Perl和Ruby中编写基于语法的解析器的最佳解析器生成工具是什么?我已经看过ANTLR,并没有找到太多有关使用ANTLRv3与C++目标,但否则看起来很有趣。与ANTLR类似,我应该阅读的其他工具是什么?
  3. 有人想了解更多关于解析的标准书籍和文章是什么?不幸的是编译器课程并不属于我的教育范畴,因此非常欢迎基础材料。我听说过关于Dragon Book的很棒的事情,但还有什么呢?

回答

4

在1,我要说的主要优点是可维护性 - 做一个变化不大的语言只是意味着作出相应小变化的语法,而不是通过微小的代码中的各个景点黑客这可能与你想要改变的东西有关......数量级提高了生产力,减少了错误风险。

在2.和3.上,我不能提出超出你已经找到的东西(我主要使用Python和pyparsing,并且可以从许多以Python为中心的解析框架的经验发表评论,但对于C++,我大多使用良好无论如何,我的旧版yaccbison,以及我的龙书的旧版粗体 - 实际上并非最新版本 - 就是我为了这个目的而保留在我的身边......)。

2

Let's Build A Compiler是如何编写简单编译器的分步教程。代码是用Delphi(Pascal)编写的,但它的基本功能足以轻松翻译成大多数其他语言。

+0

有趣的是,实际上我会推荐完全相同的东西,但不记得它叫什么。 +1 – 2009-06-27 20:40:37

1

在perl中,Parse :: RecDescent模块是第一个开始的地方。向模块名称添加教程,Google应该能够找到大量教程来帮助您入门。

4

以下是一张你的(非常好)的问题:

  1. 我觉得一个解析器受益最大从那里语法实际存在的不平凡的情况。您必须了解解析器和语法如何工作才能想到这种技术,而不是每个开发人员都这么做。
  2. lex/yacc是较旧的Unix工具,可能作为C++开发人员使用。也许是野牛。
  3. ANTRL及其附带的书非常好。 "Writing Compilers and Interpreters"有您可能喜欢的C++示例。

GoF Interpreter模式是编写“小语言”的另一种技巧。看看那个。

1

使用BNF,EBNF或类似的方法定义语法更简单,稍后您可以更好地维护它。另外,你可以找到很多语法定义的例子。最后但并非最不重要的一点是,如果您要在场上向其他人讲述您的语法,最好是您讲的语言相同(BNF,EBNF等)。

编写您自己的解析代码就像重新发明轮子并容易出错。它也不易维护。当然,它可以更灵活,对于小型项目也可能是一个不错的选择,但是使用现有的解析器生成器需要语法并且吐出代码应该覆盖我们的大部分需求。

对于C++我也会建议lex/yacc。对于Ruby来说,这看起来像是一个不错的选择:Coco/R(uby)

1

有趣的时机:我花了很多时间想知道状态机和解析器,并试图弄清楚我如何能更多地了解它们。

对于2,你可以看看Ragel(这对C++和Ruby来说很好)。

+0

我忘记提到昨天晚上在机器上工作以阅读你的想法。 :)感谢Ragel的建议,我一定会看看它! – 2009-06-27 21:33:00

2

我会仔细看看Haskell中基于monadic combinator的解析(通常也会涉及词法分析)。我发现它相当令人大开眼界;使用这种方法可以轻松地从头开始构建解析器,这是多么令人惊奇。实际上,编写自己的解析器通常比尝试使用现有的库更快。

最有名的例子可能是Parsec,它有一个很好的user guide,解释如何使用它。这个库的端口列表是Parsec page of the Haskell wiki上列出的其他语言(包括C++Ruby)的端口列表,虽然我不熟悉它们,所以我不能说它们在Haskell中使用Parsec有多接近。

如果您想了解这些内部工作方式以及如何编写自己的内容,我建议您从Graham Hutton的Programming in Haskell的第8章开始(“功能解析器”)。一旦你理解了这个章节(可能需要几个读数),你将被设置。

1

这里有一个自包含的教程,完全可移植的编译器编译 可用于设计和实施“低开销” DSL的速度非常快(10页!):

http://www.bayfronttechnologies.com/mc_tutorial.html

这网站引导您通过Val Schorre 1964年关于MetaII的论文。 是的,1964年,而且太棒了。这是我从1970年开始学习编译器 的原因。