寻找"标记器","解析器"和"词法分析器"的清晰定义以及它们如何相互关联和使用?

lor*_*hog 134 parsing tokenize lexer

我正在寻找"tokenizer","parser"和"lexer"是什么以及它们如何相互关联的明确定义(例如,解析器是否使用了tokenizer,反之亦然)?我需要创建一个程序,将通过c/h源文件来提取数据声明和定义.

我一直在寻找示例,可以找到一些信息,但我真的很难掌握语法规则,解析树和抽象语法树等基础概念以及它们如何相互关联.最终这些概念需要存储在实际程序中,但1)它们看起来像什么,2)是否有共同的实现.

我一直在关注这些主题和程序,如Lex和Yacc维基百科,但从未经历过编译器类(EE专业),我发现很难完全理解正在发生的事情.

Rog*_*mbe 151

标记生成器通常通过查找空格(制表符,空格,换行符)将文本流分解为标记.

词法分析器基本上是一个标记化器,但它通常会为标记附加额外的上下文 - 这个标记是一个数字,该标记是一个字符串文字,另一个标记是一个相等运算符.

解析器从词法分析器获取标记流并将其转换为表示由原始文本表示的(通常)程序的抽象语法树.

最后我查了一下,关于这个主题的最好的书是"编译器:原理,技术和工具",通常被称为"龙书".

  • 我不同意解析器/定义/生成抽象语法树.解析器可以产生各种不同的输出.例如,解析器通常会生成一系列对构建器接口的调用 - 请参阅"四人帮"模式书中的"构建器模式".关键点在于解析器分析一系列令牌以确定序列是否符合某些(通常是无上下文的)语法,并可能根据序列的语法结构产生一些输出. (10认同)
  • 毫无疑问,"龙书"是一本好书,但它确实需要读者在CS中有一个良好的基础.一些具有更多实际吸引力的书将由Ronald Mak撰写的"编写编译器和口译员","现代编译器实现",Andrew Appel; "编译器构建",Niklaus Wirth; Pat Terry的"用C#和Java编译"和"编译器和编译器生成器:C++简介"; 当然还有Terrence Parr的"最终的ANTLR参考". (6认同)
  • 只是为了确定,我不是在敲你的推荐."龙书"是我关于编译技术的第一本书,但与Wirth的书相比,这本书很难实现,这本书可以在几个小时内完成.当时我没什么选择,因为这是我能拿到的唯一一本书(1991年,亚马逊和WWW之前).我有这个和Jack W. Crenshaw制作的一组文本文件叫做"让我们建立一个编译器"(感谢杰克!).这仍然是要更全面地理解原理的书,但大多数程序员只需要一个实用的介绍. (4认同)
  • “让我们构建一个编译器”在这里:http://compilers.iecc.com/crenshaw/。我从这里找到了链接:http://prog21.dadgum.com/30.html (2认同)
  • @Pithkos:如果这些是唯一的约束,那么您所说的就是该函数在一个未命名(数学)域中接受输入,并在另一个未命名域中产生和输出,例如 F(X) -> Y 几乎这意味着您只能将其称为“函数”。如果你坚持 X 的域是 <StreamOfCharacter,Grammar> 并且 Y 的域是 Tree 并且它反映了语法的形状,那么 F(X,G) -> T 将是我称之为解析器。通常我们对 G 使用咖喱 F,因为 G 不经常改变,所以 F[G](X)->T 就是你通常看到的解析器。 (2认同)

小智 14

例:

int x = 1;
Run Code Online (Sandbox Code Playgroud)

词法分析器或分词器将它分成标记'int','x','=','1',';'.

解析器将获取这些令牌并使用它们以某种方式理解:

  • 我们有一个声明
  • 它是整数的定义
  • 整数称为'x'
  • 'x'应该用值1初始化

  • 词法分析者会注意到"int","="和";" 是没有进一步含义的标记,"x"是标识符名称或其他东西,值"x","1"是整数或数字,值"1".标记器不一定会这样做. (7认同)

Wil*_*ean 5

我会说词法分析器和分词器基本上是一回事,它们将文本粉碎成其组成部分(“标记”)。然后解析器使用语法解释标记。

不过,我不会太拘泥于精确的术语用法——人们经常使用“解析”来描述解释一段文本的任何动作。