编写编程语言解析器的最佳实践

26

在编写解析器时,有哪些最佳实践值得遵循?


2
解析器用于什么?编译器或IP消息? - Tim
7个回答

19
所接受的智慧是使用解析器生成器+语法,这似乎是一个好建议,因为您正在使用一个严谨的工具,并且在这样做时可以减少工作量和潜在的错误。
要使用解析器生成器,语法必须是上下文无关的。如果您正在设计要解析的语言,则可以控制此内容。如果您不确定,那么如果您开始进行语法路线,它可能会花费您很多力气。即使在实践中它是上下文无关的,除非语法很庞大,否则手动编写递归下降解析器可能更简单。
上下文无关不仅使解析器生成器成为可能,而且也使手动编写的解析器简单得多。您最终得到的是每个短语一个(或两个)函数。如果您清晰地组织和命名代码,则这并不比语法难看到多少(如果您的IDE可以向您显示调用层次结构,那么您几乎可以看到语法是什么)。
优点:
- 更简单的构建 - 更好的性能 - 更好的输出控制 - 可以处理小的偏差,例如使用不完全上下文无关的语法
我不是说语法总是不合适的,但通常收益微不足道,而成本和风险往往超过了收益。
(我认为他们的论点是虚假吸引人的,并且存在一般倾向于它们,因为这是一种表明自己更精通计算机科学的方式。)

10

几点建议:

  • 熟悉你的语法 - 以适当的形式写下来
  • 选择合适的工具。使用Spirit2x在C++中完成,或选择外部解析器工具,如antlr,yacc或其他适合您的工具
  • 你需要一个解析器吗?也许正则表达式就足够了?或者用perl脚本来解决问题?编写复杂的解析器需要时间。

7
不要过度使用正则表达式——虽然它们有它们的用处,但它们没有处理任何真正解析的能力。你可以试着推一下,但最终你会撞到瓶颈或者得到一个难以维护的混乱。最好找一个可以处理更大语言集的解析器生成器。如果你真的不想使用工具,可以看看递归下降解析器——这是一个手写小型解析器的非常简单的模式。它们不像大型解析器生成器那样灵活和强大,但学习曲线要短得多。
除非你有非常严格的性能要求,否则尽量保持你的层次分离——词法分析器读入各个标记,解析器将它们排列成树形结构,然后语义分析检查所有内容并链接引用,最后输出正在生成的任何内容。保持逻辑的不同部分分离会使事情更容易在以后维护。

7

首先,大部分阅读龙书

如果您知道如何构建解析器,则解析器并不复杂,但这不是那种只要花足够的时间就能达到目标的事情。更好的方式是在现有的知识基础上进行构建。(否则,预计需要写并且抛弃几十次)。


5

是的,尝试生成它,而不是手写。考虑使用yacc、ANTLR、Flex/Bison、Coco/R、GOLD Parser generator等工具来生成解析器。只有在没有现有的解析器生成器符合您的需求时,才会手动编写解析器。


3
  • 选择适合的解析器,有时候递归下降解析器就足够了,但是有些情况需要使用LR 解析器(还有很多种类型的LR解析器)。
  • 如果您有一个复杂的语法,请构建抽象语法树。
  • 尝试非常清楚地识别什么是分析器中的内容、什么是语法的一部分以及什么涉及语义。
  • 尽量使解析器与词法分析器实现的耦合度最小。
  • 为用户提供良好的接口,让他不关心解析器的实现方式。

2
首先,不要尝试将相同的技术应用于解析所有内容。有许多可能的用例,从IP地址(一些临时代码)到需要工业级解析器并从符号表中反馈的C++程序,以及从用户输入(需要非常快速地处理)到编译器(通常可以花费一点时间进行解析)。如果您想要有用的答案,您可能需要指定您正在做什么。
其次,要有一个可解析的语法。它越复杂,规范就需要越正式。尽量在正式方面出错。
第三,在某种程度上取决于您正在做什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接