是否在寻找关于“ tokenizer”,“ parser”和“ lexers”是什么以及它们如何相互关联和使用的明确定义?


151

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

我一直在寻找示例并可以找到一些信息,但是我真的很难掌握语法规则,语法分析树和抽象语法树等基本概念以及它们之间的相互关系。最终,这些概念需要存储在实际程序中,但是1)它们看起来像什么,2)是常见的实现。

我一直在浏览有关Lex和Yacc等主题和程序的Wikipedia,但是从未经历过编译器类(EE主修),我发现很难完全了解正在发生的事情。

Answers:


166

令牌生成器通常通过查找空格(制表符,空格,换行)将文本流分成令牌。

一个词法分析器基本上是一个标记器,但它通常在标记上附加额外的上下文-该标记是一个数字,该标记是一个字符串文字,另一个标记是一个等于运算符。

解析器从词法分析器中获取令牌流,并将其转换为代表原始文本表示的(通常)程序的抽象语法树。

最后我检查了一下,关于该主题的最好的书是“编译器:原理,技术和工具”,通常被称为“龙书”。


8
毫无疑问,《龙书》是一本好书,但它确实要求读者在CS中有良好的基础。更具实用性的一本书是麦迪伦(Ronald Mak)的“编写编译器和解释器”,安德鲁·阿佩尔(Andrew Appel)的“现代编译器实现”。“编译器构造”,Niklaus Wirth;Pat Terry的“使用C#和Java进行编译”和“编译器和编译器生成器:C ++简介”;当然还有Terrence Parr撰写的“权威ANTLR参考”。
安德烈·阿特斯

5
可以肯定的是,我不会拒绝您的建议。“龙书”是我的第一本有关编译器技术的书,但是与Wirth的书相比,这很难,这本书可以在几个小时内完成。那时我几乎没有选择,因为那是我唯一能接触到的书(1991年,在Amazon和WWW之前)。我有那个,还有Jack W. Crenshaw生成的文本文件的集合,叫做“让我们构建一个编译器”(感谢Jack!)。仍然可以通过这本书来更全面地了解这些原理,但是大多数程序员只需要进行实用的介绍。
安德烈·阿特斯

10
我不同意解析器/ by definition /会生成抽象语法树。解析器可以产生各种不同的输出。例如,解析器通常会生成对某些构建器接口的调用序列-参见《四人制模式》一书中的“构建器模式”。关键是解析器分析标记序列,以确定该序列是否符合某些(通常无上下文)语法,并可能基于序列的语法结构产生一些输出。
Theodore Norvell

2
“让我们构建一个编译器”在这里:compilers.iecc.com/crenshaw。我从这里找到链接:prog21.dadgum.com/30.html
Roger Lipscombe

1
@Pithkos:如果仅是这些约束,则您所说的就是该函数在一个未命名(数学)域中接受输入,并在另一个未命名域中产生并输出,例如F(X)-> Y这几乎意味着您只能将此称为“功能”。如果您坚持认为X的域是<StreamOfCharacter,Grammar>,而Y的域是Tree,其属性反映了语法的形状,那么F(X,G)-> T将是我所说的解析器。通常我们会相对于G来对F进行咖喱化处理,因为G不会经常变化,因此F [G](X)-> T是您通常认为的解析器。
艾拉·巴克斯特

18

例:

int x = 1;

词法分析器或令牌生成器会将其拆分为令牌'int','x','=','1',';'。

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

  • 我们有一个声明
  • 这是一个整数的定义
  • 整数称为“ x”
  • “ x”应初始化为值1

9
词法分析器会注意到“ int”,“ =“和“;” 是没有进一步含义的令牌,“ x”是标识符名称或某些东西,值“ x”,“ 1”是整数或数字,值“ 1”。分词器不一定会那样做。
David Thornley,2009年

5

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

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


1
使用PEG解析器时,标记器和解析器之间的区别甚至更加不清楚。
安德烈·阿特斯

0

添加到给定的答案

  • 标记生成器将同时删除任何意见,并且只返回令牌的词法分析器。
  • 词法分析器将限定作用域这些令牌(变量/函数)
  • 然后解析器将构建代码/程序结构

1
您好@downvoter,您能否详细说明为什么实际进行了downvote?
Koray Tugay

1
我不是拒绝投票的人,但我认为拒绝投票的原因可能是因为您的答案似乎不正确。分词器可以消除噪声(通常为空格,但也可以删除注释),但是它通常不提供给词法分析器。基于DFA的词法分析器将标记并标识什么是标记(例如,数字,字符串,标识符,还包括空格或注释),但无法对这些标记进行范围划分,因为这将需要语法树,该语法树随后将由解析器。
卢塞罗

1)我不了解您在“ lexer”和“ tokenizer”之间的明显区别。我已经为50多种语言构建了解析器,但我从未有过两种将源文本分解为原子的单独机制,因此对我而言,它们只是同义词。2)如果要编译,则在词法分析器中删除注释和空格是有意义的。如果要构建源到源转换工具,则不能丢失注释,因为它们必须重新出现在转换后的文本中。因此,总是删除评论是错误的;我们可以争论一个人如何保留空白。...
艾拉·巴克斯特

1
... [我构建的工具(请参阅我的简历)以足够的保真度捕获了这两个工具,以便在转换后的代码中重现它们;我们走得更远,捕获原子的格式,包括诸如字符串上的引号和数字的基数/前导零计数之类的怪异事物,所有这些都可以避免用户拒绝转换后的结果。因此,您错过的不仅是词法分析程序不一定会剥离信息,而且事实上,它们可能需要捕获原始令牌之外的信息。....
Ira Baxter

... 3)词法分析器仅在难以处理的笨拙的解析器中定义“作用域”,这些解析器很难处理语法歧义。C和C ++解析器是典型的示例;请参阅我在stackoverflow.com/a/1004737/120163上的讨论)。一个人不必那样(丑陋)地做。因此,我发现您的答案完全被误导了。
Ira Baxter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.