在Aho Ullman和Sethi的Compiler Construction中,假设源程序的输入字符串被分成具有逻辑含义的字符序列,称为标记,而词位是构成标记的序列,那么基本区别是什么?
Answers:
使用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令牌列,我们看到令牌如if
,else
,comparison
,id
,number
和literal
; 这些是令牌的名称。通常,在词法分析器/解析器中,令牌是一种结构,它不仅保存令牌的名称,还保存组成令牌的字符/符号以及组成令牌的字符串的开始和结束位置,并带有开始和结束位置用于错误报告,突出显示等。
现在,词法分析器接受字符/符号的输入,并使用词法分析器的规则将输入的字符/符号转换为标记。现在,使用词法分析器/解析器的人对自己经常使用的东西有了自己的说法。您认为构成标记的字符/符号序列就是使用词法分析器/解析器的人所说的lexeme。因此,当您看到lexeme时,只需考虑代表令牌的一系列字符/符号。在比较示例中,字符/符号的序列可以是不同的模式,例如<
或>
或else
或3.14
等。
考虑两者之间关系的另一种方法是,令牌是解析器使用的编程结构,其具有称为lexeme的属性,该属性保存来自输入的字符。现在,如果您在代码中查看令牌的大多数定义,您可能不会将lexeme视为令牌的属性之一。这是因为令牌很可能会保持代表令牌和词位的字符/符号的开始和结束位置,因此由于输入是静态的,因此可以根据需要从开始和结束位置派生字符/符号的序列。
can you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.
SO不是讨论站点。这是一个新问题,需要作为一个新问题提出。
当源程序输入到词法分析器中时,它首先将字符分解为词素序列。然后,将词素用于标记的构造中,其中将词素映射到标记中。名为myVar的变量将映射到标记< id,“ num”的令牌中,其中“ num”应指向变量在符号表中的位置。
简而言之:
一个示例包括:
x = a + b * 2
产生词素:{x,=,a,+,b,*,2}
具有相应的标记:{< id,0>,<=>,< id,1 >,<+>,< id,2>,<*>,< id,3>}
Lexeme - Lexeme是源程序中与令牌的模式匹配的字符序列,由词法分析器标识为该令牌的实例。
令牌-令牌是一对,由令牌名称和可选的令牌值组成。令牌名称是词汇单元的类别。常见令牌名称是
在编程语言C中考虑以下表达式:
总和= 3 + 2;
标记并由下表表示:
Lexeme Token category
------------------------------
sum | Identifier
= | Assignment operator
3 | Integer literal
+ | Addition operator
2 | Integer literal
; | End of statement
让我们看看词法分析器(也称为Scanner)的工作原理
让我们来看一个示例表达式:
INPUT : cout << 3+2+3;
FORMATTING PERFORMED BY SCANNER : {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;}
不是实际的输出。
扫描程序会反复查找源程序文本中的一个LEXEME,直到输入被耗尽
Lexeme是输入的子字符串,它构成语法中存在的有效终端字符串。每个词素都遵循最后解释的模式(读者最后可能会跳过的部分)
(重要的规则是寻找最长的前缀,以形成有效的终端字符串,直到遇到下一个空格为止...下文解释)
LEXEMES:
(尽管“ <”也是有效的终端字符串,但上述规则应为词素“ <<”选择模式,以生成扫描程序返回的令牌)
令牌:每次扫描程序发现一个(有效的)词素时,令牌就一次返回一个(由扫描程序在Parser请求时返回)。扫描程序在找到词素时会创建一个符号表条目(如果尚不存在的话)(具有属性:主要是令牌类别,而其他属性很少),以生成其令牌
“#”表示符号表条目。为了便于理解,我已经在上面的列表中指出了词素编号,但是从技术上讲,它应该是符号表中记录的实际索引。
对于上面的示例,以下令牌由扫描程序按指定顺序返回解析器。
<标识符#1>
<运算符,#2>
<文字#3>
<运算符,#4>
<文字#5>
<运算符,#4>
<文字#3>
<操纵杆#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.`
Lexeme Lexeme被称为令牌中的字符序列(字母数字)。
令牌 令牌是可以被识别为单个逻辑实体的字符序列。通常,令牌是关键字,标识符,常量,字符串,标点符号,运算符。数字。
模式 规则描述的一组字符串,称为模式。模式解释了什么可以是令牌,并且这些模式是通过与令牌相关联的正则表达式定义的。
词法分析器采用一系列字符来识别与正则表达式匹配的词素,并将其进一步分类为标记。因此,Lexeme是匹配的字符串,令牌名称是该Lexeme的类别。
例如,在正则表达式下面考虑输入为“ int foo,bar;”的标识符。
字母(字母|数字| _)*
因此,foo
与bar
正则表达式匹配,因此都是词素,但被归类为一个标记ID
即标识符。
还要注意,下一阶段(即语法分析器)不必了解Lexeme,而只需了解令牌。
Lexeme基本上是令牌的单位,并且基本上是与令牌匹配的字符序列,有助于将源代码分解为令牌。
例如:如果源是x=b
,则词位将是x
,=
,b
和令牌将是<id, 0>
,<=>
,<id, 1>
。