令牌和词素有什么区别?


86

在Aho Ullman和Sethi的Compiler Construction中,假设源程序的输入字符串被分成具有逻辑含义的字符序列,称为标记,而词位是构成标记的序列,那么基本区别是什么?

Answers:


118

使用Aho,Lam,Sethi和Ullman撰写的“编译器原理,技术和工具,第二版(WorldCat),又名《紫色龙书》

Lexeme页 111

词素是源程序中与令牌的模式匹配的字符序列,并且由词法分析器标识为该令牌的实例。

代币pg。111

令牌是由令牌名称和可选属性值组成的一对。令牌名称是代表一种词汇单元(例如,特定的关键字)或表示标识符的输入字符序列的抽象符号。令牌名称是解析器处理的输入符号。

模式pg。111

模式是对令牌词素可能采用的形式的描述。在使用关键字作为标记的情况下,模式只是构成关键字的字符序列。对于标识符和某些其他标记,模式是由许多字符串匹配的更复杂的结构。

图3.2:令牌示例pg.112

[Token]       [Informal Description]                  [Sample Lexemes]
if            characters i, f                         if
else          characters e, l, s, e                   else
comparison    < or > or <= or >= or == or !=          <=, !=
id            letter followed by letters and digits   pi, score, D2
number        any numeric constant                    3.14159, 0, 6.02e23
literal       anything but ", surrounded by "'s       "core dumped"

为了更好地理解与词法分析器和解析器的关系,我们将从解析器开始并向后处理输入。

为了简化解析器的设计,解析器不直接与输入配合使用,而是接受由词法分析器生成的标记列表。查看图3.2令牌列,我们看到令牌如ifelsecomparisonidnumberliteral; 这些是令牌的名称。通常,在词法分析器/解析器中,令牌是一种结构,它不仅保存令牌的名称,还保存组成令牌的字符/符号以及组成令牌的字符串的开始和结束位置,并带有开始和结束位置用于错误报告,突出显示等。

现在,词法分析器接受字符/符号的输入,并使用词法分析器的规则将输入的字符/符号转换为标记。现在,使用词法分析器/解析器的人对自己经常使用的东西有了自己的说法。您认为构成标记的字符/符号序列就是使用词法分析器/解析器的人所说的lexeme。因此,当您看到lexeme时,只需考虑代表令牌的一系列字符/符号。在比较示例中,字符/符号的序列可以是不同的模式,例如<>else3.14等。

考虑两者之间关系的另一种方法是,令牌是解析器使用的编程结构,其具有称为lexeme的属性,该属性保存来自输入的字符。现在,如果您在代码中查看令牌的大多数定义,您可能不会将lexeme视为令牌的属性之一。这是因为令牌很可能会保持代表令牌和词位的字符/符号的开始和结束位置,因此由于输入是静态的,因此可以根据需要从开始和结束位置派生字符/符号的序列。


12
在通俗的编译器用法中,人们倾向于交替使用这两个术语。如果需要的话,精确的区分是很好的。
Ira Baxter

虽然不是一个纯粹的计算机科学的定义,这里是自然语言处理的一个是相关的,从介绍词汇语义 an individual entry in the lexicon
盖伊打码机

绝对清楚的解释。这就是天上应该如何解释的事情。
Timur Fayzrakhmanov

很好的解释。我还有一个疑问,我也了解了解析阶段,因为解析器无法验证令牌,因此解析器向词法分析器请求令牌。您能否通过在解析器阶段进行简单输入以及解析器何时向lexer索取令牌来进行解释?
Prasanna Sasne

@PrasannaSasne can you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.SO不是讨论站点。这是一个新问题,需要作为一个新问题提出。
Guy Coder

36

当源程序输入到词法分析器中时,它首先将字符分解为词素序列。然后,将词素用于标记的构造中,其中将词素映射到标记中。名为myVar的变量将映射到标记< id,“ num”的令牌中,其中“ num”应指向变量在符号表中的位置。

简而言之:

  • 词素是从字符输入流派生的单词。
  • 令牌是映射到令牌名称和属性值的词素。


一个示例包括:
x = a + b * 2
产生词素:{x,=,a,+,b,*,2}
具有相应的标记:{< id,0>,<=>,< id,1 >,<+>,< id,2>,<*>,< id,3>}


2
它应该是<id,3>吗?因为2不是标识符
Aditya '18

但是在哪里说x是标识符?这是否意味着一个符号表是一个3列表,其中以'name'= x,'type'='identifier(id)',指针='0'作为特定条目?然后它必须具有其他一些条目,例如'name' = while,'type'='keyword',指针= '21'??

8

a)令牌是组成程序文本的实体的符号名称;例如,如果将if用作关键字,将id用作任何标识符。这些构成了词法分析器的输出。5

(b)模式是一种规则,用于指定输入中的字符序列何时构成标记;例如,令牌i的序列i,f和,以及以字母id开头的任何字母数字序列作为令牌id。

(c)词素是输入中与模式匹配的字符序列(因此构成令牌的实例);例如,if匹配if的模式,而foo123bar匹配id的模式。


8

LEXEME-由PATTERN组成的令牌匹配的字符序列

PATTERN-定义令牌的规则集

令牌-编程语言的字符集上有意义的字符集合,例如:ID,常量,关键字,运算符,标点,文字字符串


7

Lexeme - Lexeme是源程序中与令牌的模式匹配的字符序列,由词法分析器标识为该令牌的实例。

令牌-令牌是一对,由令牌名称和可选的令牌值组成。令牌名称是词汇单元的类别。常见令牌名称是

  • 标识符:程序员选择的名称
  • 关键字:已经在编程语言中使用的名称
  • 分隔符(也称为标点符号):标点符号和成对分隔符
  • 运算符:对参数进行运算并产生结果的符号
  • 文字:数字,逻辑,文本,参考文字

在编程语言C中考虑以下表达式:

总和= 3 + 2;

标记并由下表表示:

 Lexeme        Token category
------------------------------
sum      |    Identifier
 =       |    Assignment operator
 3       |    Integer literal
 +       |    Addition operator
 2       |    Integer literal
 ;       |    End of statement

5

让我们看看词法分析器(也称为Scanner)的工作原理

让我们来看一个示例表达式:

INPUT : cout << 3+2+3;

FORMATTING PERFORMED BY SCANNER :  {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;} 

不是实际的输出。

扫描程序会反复查找源程序文本中的一个LEXEME,直到输入被耗尽

Lexeme是输入的子字符串,它构成语法中存在的有效终端字符串。每个词素都遵循最后解释的模式(读者最后可能会跳过的部分)

(重要的规则是寻找最长的前缀,以形成有效的终端字符串,直到遇到下一个空格为止...下文解释)

LEXEMES:

  1. out
  2. <<

(尽管“ <”也是有效的终端字符串,但上述规则应为词素“ <<”选择模式,以生成扫描程序返回的令牌)

  1. 3
  2. +
  3. 2
  4. ;

令牌每次扫描程序发现一个(有效的)词素时,令牌就一次返回一个(由扫描程序在Parser请求时返回)。扫描程序在找到词素时会创建一个符号表条目如果尚不存在的话)(具有属性:主要是令牌类别,而其他属性很少),以生成其令牌

“#”表示符号表条目。为了便于理解,我已经在上面的列表中指出了词素编号,但是从技术上讲,它应该是符号表中记录的实际索引。

对于上面的示例,以下令牌由扫描程序按指定顺序返回解析器。

  1. <标识符#1>

  2. <运算符,#2>

  3. <文字#3>

  4. <运算符,#4>

  5. <文字#5>

  6. <运算符,#4>

  7. <文字#3>

  8. <操纵杆#6>

如您所见,令牌与lexeme不同,它是一对输入,而lexeme是输入的子字符串。

该对中的第一个元素是令牌类/类别

令牌类如下所示:

  • 关键词
  • 身份标识
  • 文学作品
  • 标点器
  • 操作员
  • 还有一件事,扫描程序检测到空格,将其忽略并且根本不为空格形成任何标记。并非所有的定界符都是空白,空白是扫描仪用于此目的的一种形式的定界符。输入中的制表符,换行符,空格,转义字符统称为空白定界符。其他分隔符很少是“;” ','':'等,它们被广泛认为是形成令牌的词素。

    这里返回的令牌总数为8,但是对于词素仅创建6个符号表条目。Lexeme总数也为8(请参阅Lexeme的定义)

    ---你可以跳过这部分

    A ***pattern*** is a rule ( say, a regular expression ) that is used to check if a string-of-terminals is valid or not

    If a substring of input composed only of grammar terminals is following the rule specified by any of the listed patterns , it is validated as a lexeme and selected pattern will identify the category of lexeme, else a lexical error is reported due to either (i) not following any of the rules or (ii) input consists of a bad terminal-character not present in grammar itself.

    for example :
    
    1. No Pattern Exists : In C++ , "99Id_Var" is grammar-supported string-of-terminals but is not recognised by any of patterns hence lexical error is reported .
    
    2. Bad Input Character : $,@,unicode characters may not be supported as a valid character in few programming languages.`
    

    5

    Lexeme - Lexeme是一个字符串,是编程语言中最低级别的语法单元。

    令牌-令牌是形成词素类的语法类别,这意味着该词素所属的类是关键字,标识符还是其他任何东西。词法分析器的主要任务之一是创建一对词素和标记,即收集所有字符。

    让我们举个例子:

    如果(y <= t)

    y = y-3;

    Lexeme代币

    如果关键字

    (左上肢

    y标识符

    <=比较

    t标识符

    正确的理解

    y标识符

    =结盟

    y标识符

    _算术

    3整数

    ;                                    分号

    Lexeme与令牌之间的关系

    Lexeme与令牌之间的关系


    4

    令牌:(关键字,标识符,标点符号,多字符运算符)的种类就是令牌。

    模式:由输入字符组成令牌的规则。

    Lexeme:它是源程序中的一系列字符,与令牌的模式匹配。基本上,它是令牌的元素。


    3

    令牌: 令牌是可以被视为单个逻辑实体的字符序列。典型的令牌有:
    1)标识符
    2)关键字
    3)运算符
    4)特殊符号
    5)常量

    模式:输入中的一组字符串,为其生成相同的令牌作为输出。这组字符串由称为与令牌关联的模式的规则描述。
    Lexeme:Lexeme是源程序中由令牌模式匹配的字符序列。


    1

    Lexeme Lexeme被称为令牌中的字符序列(字母数字)。

    令牌 令牌是可以被识别为单个逻辑实体的字符序列。通常,令牌是关键字,标识符,常量,字符串,标点符号,运算符。数字。

    模式 规则描述的一组字符串,称为模式。模式解释了什么可以是令牌,并且这些模式是通过与令牌相关联的正则表达式定义的。


    1

    和Math一样,CS研究人员都喜欢创建“新”术语。上面的答案都很不错,但是显然,不需要如此区分令牌和词位恕我直言。它们就像两种表示同一事物的方式。一个词素是具体的-这里是一组字符;另一方面,令牌是抽象的-如果有意义,通常指代词素的类型及其语义值。只是我的两分钱。


    0

    词法分析器采用一系列字符来识别与正则表达式匹配的词素,并将其进一步分类为标记。因此,Lexeme是匹配的字符串,令牌名称是该Lexeme的类别。

    例如,在正则表达式下面考虑输入为“ int foo,bar;”的标识符。

    字母(字母|数字| _)*

    因此,foobar正则表达式匹配,因此都是词素,但被归类为一个标记ID即标识符。

    还要注意,下一阶段(即语法分析器)不必了解Lexeme,而只需了解令牌。


    -2

    Lexeme基本上是令牌的单位,并且基本上是与令牌匹配的字符序列,有助于将源代码分解为令牌。

    例如:如果源是x=b,则词位将是x=b和令牌将是<id, 0><=><id, 1>


    答案应该更具体。一个例子可能是有用的。
    Zverev Evgeniy
    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.