【发布时间】:2012-11-27 12:21:40
【问题描述】:
在编写解析器时我应该遵循哪些最佳实践?
【问题讨论】:
-
解析器有什么用?编译器还是 ip 消息?
标签: c++ parsing programming-languages conventions
在编写解析器时我应该遵循哪些最佳实践?
【问题讨论】:
标签: c++ parsing programming-languages conventions
公认的智慧是使用解析器生成器 + 语法,这似乎是个好建议,因为您使用的是严格的工具,并且可能会减少工作量和这样做的潜在错误。
要使用解析器生成器,语法必须是上下文无关的。如果您正在设计要解析的语言,那么您可以控制它。如果您不确定,那么如果您从语法路线开始,可能会花费您很多精力。即使它在实践中是上下文无关的,除非语法非常庞大,否则手动编写一个像样的递归解析器会更简单。
上下文无关不仅使解析器生成器成为可能,而且还使手工编码的解析器变得更加简单。你最终得到的是每个短语一个(或两个)功能。也就是说,如果您干净地组织和命名代码并不比语法更难看(如果您的 IDE 可以显示调用层次结构,那么您几乎可以看到语法是什么)。
优点:-
我并不是说语法总是不合适的,但好处往往是微乎其微的,而且往往被成本和风险所抵消。
(我相信他们的论点似是而非的吸引人,并且普遍存在对他们的偏见,因为这是一种表明人们更具有计算机科学素养的一种方式。)
【讨论】:
几点建议:
【讨论】:
不要过度使用正则表达式 - 虽然它们有自己的位置,但它们根本没有能力处理任何类型的真正解析。你可以推动它们,但你最终会碰壁或陷入无法维护的混乱局面。您最好找到一个可以处理更大语言集的解析器生成器。如果你真的不想使用工具,你可以看看递归下降解析器——这是一个非常简单的手写小解析器的模式。它们不像大型解析器生成器那样灵活或强大,但它们的学习曲线要短得多。
除非您有非常严格的性能要求,否则请尝试将您的层分开 - 词法分析器读取单个标记,解析器将它们排列成树,然后语义分析检查所有内容并链接引用,然后是最后阶段输出正在生产的任何东西。保持逻辑的不同部分分开将使以后的维护更容易。
【讨论】:
首先阅读大部分Dragon book。
如果您知道如何构建解析器,它们并不复杂,但如果您投入足够的时间,它们并不是那种类型的东西,您最终会到达那里。建立在现有知识库上会更好。 (否则会写好几十次就扔掉)。
【讨论】:
是的。尝试生成它,而不是编写。考虑使用 yacc、ANTLR、Flex/Bison、Coco/R、GOLD 解析器生成器等。仅当现有解析器生成器都不符合您的需求时,才使用手动编写解析器。
【讨论】:
【讨论】:
首先,不要尝试使用相同的技术来解析所有内容。有许多可能的用例,从 IP 地址(一些临时代码)到 C++ 程序(需要工业强度的解析器和符号表的反馈),以及用户输入(需要非常快速)到编译器(通常可以花一点时间解析)。如果您想要有用的答案,您可能需要指定您正在做什么。
其次,记住要解析的语法。越复杂,规范就越需要正式。尽量避免过于正式。
第三,嗯,这取决于你在做什么。
【讨论】: