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