令牌和词位有什么区别?
在Aho Ullman和Sethi的“编译器构造”中,将源程序的字符inputstring分为具有逻辑意义的字符序列,称为记号,词位是组成记号的序列,基本的区别是什么?
使用Aho,Lam,Sethi和Ullman的“ 编译器原理,技术和工具,第二版 ” (WorldCat)
Lexeme pg。 111
词法是源程序中与令牌模式相匹配的一系列字符,由词法分析器标识为该令牌的一个实例。
令牌页 111
令牌是由令牌名称和可选属性值组成的一对。 令牌名称是表示一种词汇单位的抽象符号,例如特定关键字或表示标识符的input字符序列。 令牌名称是parsing器处理的input符号。
模式页 111
一个模式是一个令牌的词汇可能采取的forms的描述。 在关键字作为标记的情况下,模式只是形成关键字的字符序列。 对于标识符和一些其他的标记,模式是更复杂的结构,被许多string匹配。
图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"
为了更好地理解这个与词法分析器和parsing器的关系,我们将从parsing器开始,向后回溯到input。
为了更容易deviseparsing器,parsing器不直接使用input,而是使用词法分析器生成的令牌列表。 查看图3.2中的标记列,我们可以看到诸如if
, else
, comparison
, id
, number
和literal
标记; 这些是令牌的名称。 通常在使用词法分析器的情况下,令牌是一种结构,不仅包含令牌的名称,而且还包含组成令牌的字符/符号和组成令牌的string的开始和结束位置,开始和结束位置用于错误报告,突出显示等
现在词法分析器接受字符/符号的input,并使用词法分析器的规则将input的字符/符号转换为记号。 现在使用词法分析器的人对于他们经常使用的东西有自己的词汇。 你认为构成一个标记的一系列字符/符号是使用词法分析器/parsing器的人称为词法的。 所以当你看到词位时,只要想象一下代表一个标记的字符/符号序列。 在比较例子中,字符/符号的顺序可以是不同的模式,例如<
或>
,或者3.14
等
另一种思考两者之间关系的方法是令牌是parsing器使用的一种编程结构,它具有一个名为lexeme的属性,该属性保存来自input的字符/符号。 现在,如果您在代码中查看大多数定义的标记,则可能不会将lexeme看作标记的属性之一。 这是因为令牌更可能保持表示令牌和词位的字符/符号的开始和结束位置,因为input是静态的,所以可以根据需要从开始和结束位置导出字符/符号的序列。
当一个源程序被送入词法分析器时,它将字符分解为词位序列。 然后将词位用于构build令牌,其中将词位映射为令牌。 一个名为myVar的variables将被映射到一个标识为< id ,“num”>的标记中,其中“num”应该指向variables在符号表中的位置。
简而言之:
- Lexemes是从字符inputstream派生的单词。
- 令牌是词位映射到令牌名称和属性值。
一个例子包括:
x = a + b * 2
这就产生了词位:{x,=,a,+,b,*,2}
使用相应的标记:{< id ,0>,<=>,< id ,1>,<+>,< id ,2>,<*>,< id ,3>
a)令牌是构成程序文本的实体的符号名称; 例如,如果关键字是if,id是任何标识符。 这些组成了词法分析器的输出。 五
(b)模式是规定input中的字符序列何时构成令牌的规则; 例如,序列i,f表示令牌if,以及任何以字母id开头的字母数字序列。
(c)词位是一个从input中匹配一个模式的字符序列(因此构成一个标记的一个实例); 例如,如果匹配if的模式,并且foo123bar匹配id的模式。
令牌:(关键字,标识符,标点符号,多字符运算符)的种类,简直就是一个令牌。
模式:从input字符形成标记的规则。
Lexeme:它是SOURCE PROGRAM中的一个字符序列,与令牌的模式相匹配。 基本上,它是令牌的一个元素。
令牌:令牌是可以被视为单个逻辑实体的一系列字符。 典型的令牌是,
1)标识符
2)关键字
3)运营商
4)特殊符号
5)的常数
Pattern(模式):input中的一组string,其中生成相同的标记作为输出。 这组string由一个称为与该标记关联的模式的规则来描述。
Lexeme: lexeme是源程序中由符号模式匹配的一系列字符。
LEXEME – 由形成TOKEN的PATTERN匹配的字符序列
PATTERN – 一组定义TOKEN的规则
TOKEN – 在编程语言的字符集上有意义的字符集合:例如:ID,常量,关键字,操作符,标点符号,文字string
让我们看看词法分析器(也称为扫描器)
我们来看一个例子:
INPUT : cout << 3+2+3; FORMATTING PERFORMED BY SCANNER : {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;}
不是实际的输出。
扫描仪简单地看到一个LEXEME的源程序文本,直到input是exhausted
Lexeme是input的一个子string,它构成了语法中有效的terminalstring。 每个词义都遵循最后解释的模式 (读者可能最后跳过的部分)
(重要的规则是寻找最长的可能的前缀形成一个有效的terminal串,直到下一个空白遇到…下面解释)
LEXEMES:
- COUT
- <<
(虽然“<”也是有效的terminalstring,但是上面提到的规则应该select词法“<<”的模式以便产生由扫描器返回的令牌)
- 3
- +
- 2
- ;
TOKENS:每当扫描器发现一个(有效)的词位时,一次返回一个令牌(当由Parser请求时由Scanner进行)。 扫描器创build一个符号表条目(具有属性:主要是符号类别和其他几个) ,当它find一个词位时,为了生成它的符号
“#”表示符号表项。 为便于理解,我在上面的列表中指出了词位号,但在技术上应该是符号表中logging的实际索引。
对于上面的例子,下面的令牌按照指定的顺序由扫描器返回给parsing器。
-
<标识符,#1>
-
<运营商,#2>
-
<文字,#3>
-
<运营商,#4>
-
<文字,#5>
-
<运营商,#4>
-
<文字,#3>
-
<Punctuator,#6>
正如你可以看到的不同,一个标记是一个不同于一个input子串的词位。
而这一对的第一个元素是令牌类/类别
令牌类如下所示:
还有一件事,Scanner检测到空白,忽略它们,并没有形成任何空白符号。 不是所有的分隔符都是空格,空格是扫描器为了达到目的而使用的一种分隔符。 标签,换行符,空格,input中的转义字符全部统称为空白分隔符。 很less有其他的分隔符是';' ',''''等等,这些都被广泛认可为形成标记的词位。
这里返回的令牌总数是8,但是只有6个符号表条目用于词位。 Lexemes也是总共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
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.
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 – 词法分析器是源程序中与令牌模式相匹配的一系列字符,由词法分析器标识为该令牌的一个实例。
令牌 – 令牌是由令牌名称和可选令牌值组成的一对。 令牌名称是一个词法单位的类别。常用的令牌名称是
- 标识符:程序员select的名称
- 关键字:已经在编程语言中的名字
- 分隔符(也称为标点符号):标点符号和成对分隔符
- 操作员:操作参数并产生结果的符号
- 文字:数字,逻辑,文本,参考文字
在编程语言C中考虑这个expression式:
sum = 3 + 2;
用下表表示和表示:
Lexeme Token category ------------------------------ sum | Identifier = | Assignment operator 3 | Integer literal + | Addition operator 2 | Integer literal ; | End of statement
Lexeme基本上是一个令牌的单位,它基本上是与令牌匹配的字符序列,有助于将源代码分解为令牌。
例如:如果源是x=b
,那么词位将是x
, =
, b
,并且记号将是<id, 0>
, <=>
<id, 0>
, <id, 1>
。