解析类C定义字符串最有效的方法?

时间:2009-04-27 06:48:05

标签: parsing yacc flex-lexer

我有一组用C语言编写的函数定义,其中一些额外的关键字可以放在某些参数之前(例如,与“unsigned”或“register”相同)我需要分析这些行以及一些函数存根并从中生成实际的C代码。

  • Flex / Yacc是最正确的方法吗?

  • 使用正则表达式写一个Shell或Python脚本会慢一些吗(这可能会变得非常痛苦,正如我想的那样,如果附加关键字的数量变得更大且效果会有相当大的不同),前提是我有对分析器/解析器没有经验(虽然我知道LALR如何完成它的工作)?

  • Lex / Yacc上是否有任何包含类似问题的好材料?我能找到的所有论文都使用了与“玩具”计算器相同的原始例子。

任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:3)

通常使用

ANTLR(和Lex \ Yacc一样)。

  

ANTLR,另一种语言工具   识别,是一种语言工具   提供了构建的框架   识别器,口译员,编译器,   和语法翻译   包含动作的描述   各种目标语言。

答案 1 :(得分:3)

还有Lemon Parser,它的语法限制较少。不好的一面是你和柠檬结婚了,当你发现一些限制很糟糕时,将解析器的语法重写为其他东西。好的一面是它非常容易使用..并且自给自足。您可以将其放入树中,而不必担心是否存在其他人。

SQLite3使用它,其他一些受欢迎的项目也是如此。我不是说使用它,因为SQLite会这样做,但如果时间允许,也许可以尝试一下。

答案 2 :(得分:1)

这完全取决于你对“有效”的定义。如果你有世界上所有的时间,最快的解析器将是一个手写的拉解析器。它们需要很长时间才能进行调试和开发,但是今天,没有任何解析器生成器在运行时性能方面胜过手写代码。

如果你想在一周左右的时间内解析有效的C,可以使用解析器生成器。代码将足够快,并且大多数解析器生成器都带有C的语法,您可以将其用作起点(避免90%的常见错误)。

请注意,regexp不适合解析递归结构。这种方法比使用生成器要慢,而且比手写的pull解析器更容易出错。

答案 3 :(得分:1)

实际上,这取决于你的语言有多复杂,以及它是否真的接近于C ......

尽管如此,即使是正则表达式,你也可以使用lex作为第一步....

我会选择lex + menhir和o'caml ....

但任何flex / yacc组合都没问题。

常规野牛(yacc的gnu实现)的主要问题源于C类型..你必须描述你的整个树(以及所有操作函数)...使用o'caml会非常容易..

答案 4 :(得分:-1)

对于您想要做的事情,我们DMS Software Reengineering Toolkit可能是一个非常有效的解决方案。

DMS专门用于支持您正在讨论的类型的客户分析器/代码生成器。它为定义任意语言解析器/分析器提供了非常强大的功能(在30多种真实语言上测试,包括几种完整的C,C ++,Java,C#和COBOL方言)。

DMS自动构建AST(因此您无需做任何事情,只需获得正确的语法以获得可用的AST),可以构建完全针对您指示的模式导向检查的自定义分析,可以构建新的表示要生成的代码的特定于C的AST,并将它们作为可编译的C源文本吐出。对于DMS,C的预先存在的定义可能会倾向于覆盖您的C语言。