解析器和词法分析器的设计指南?
我写了一个词法分析器(带有re2c)和一个解析器(带有柠檬),用于稍微复杂的数据格式:类似于CSV,但在特定位置使用特定的字符串类型(仅字母数字字符,字母数字字符和减号,除字符引号和逗号,但带平衡大括号等),大括号内的字符串和看起来像带有可以包含参数的大括号的函数调用的字符串。
我第一次看到它是一个拥有许多州的词法分析器,每个州都遵循特定的字符串格式。 但是经过许多来自词法分析器的无用的“意外输入”信息(它变得非常大)之后,我意识到也许它试图完成解析器的工作。 我放弃了第一次尝试,并使用只有一个状态的词法分析器,许多字符标记和一个将这些标记组合成不同字符串类型的解析器。 这样做效果更好,当某些事情关闭时,我从解析器中获得更多有用的语法错误,但它仍然感觉不太正确。 我正在考虑向词法分析器中添加一个或两个状态,但是从分析器启动状态,该状态具有更好的“概述”,在给定实例中需要字符串类型。 总体而言,我感觉有点愚蠢:(
我没有正式的CS背景,并且对数学理论有所偏离。 但也许有一个教程或书籍解释了词法分析器应该(而不应该)做什么以及解析器应该完成哪部分工作。 如何构建良好的标记模式,何时使用词法分析器状态,何时以及如何使用递归规则(使用LALR解析器)以及如何避免含糊不清的规则。 一本教导基础知识的实用食谱。 “Lex和YACC primer / HOWTO”很好,但还不够。 由于我只是想解析一个数据格式,编译器构建的书籍(比如红龙书)对我而言看起来有点过大。
或者也许有人可以在这里给我一些简单的规则。
你应该真正做的是为你的语言写一个语法。 一旦你有了,边界很容易:
除了拒绝不可能的字符和其他非常基本的位之外,词法分析器不负责输入验证。 解析器完成所有工作。
看看http://www.cs.rochester.edu/~nelson/courses/csc_173/grammars/parsing.html。 这是一个关于解析的简介CS课程页面。
判断解析器或词法分析器是否应该做什么的好的试金石测试就是问自己一个问题:
语法是否有任何递归的,嵌套的,自相似的元素?
(例如嵌套的括号,大括号,标签,子表达式,子句等)。
如果不是,普通的正则表达式就足够了,并且可以由词法分析器完成。
如果是的话,它应该由解析器进行分析,因为它至少是一个上下文无关的语法。
Lexer通常用于查找您的语言的“词汇”,并对它们进行分类(它是名词?动词?形容词?等)。
解析器用于找到适当的“句子”,将它们结构化为一个发现,如果它们是给定语言中的恰当句子。