令牌和词位有什么区别?

在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中的标记列,我们可以看到诸如ifelsecomparisonidnumberliteral标记; 这些是令牌的名称。 通常在使用词法分析器的情况下,令牌是一种结构,不仅包含令牌的名称,而且还包含组成令牌的字符/符号和组成令牌的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:

  1. COUT
  2. <<

(虽然“<”也是有效的terminalstring,但是上面提到的规则应该select词法“<<”的模式以便产生由扫描器返回的令牌)

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

TOKENS:每当扫描器发现一个(有效)的词位时,一次返回一个令牌(当由Parser请求时由Scanner进行)。 扫描器创build一个符号表条目(具有属性:主要是符号类别和其他几个) ,当它find一个词位时,为了生成它的符号

“#”表示符号表项。 为便于理解,我在上面的列表中指出了词位号,但在技术上应该是符号表中logging的实际索引。

对于上面的例子,下面的令牌按照指定的顺序由扫描器返回给parsing器。

  1. <标识符,#1>

  2. <运营商,#2>

  3. <文字,#3>

  4. <运营商,#4>

  5. <文字,#5>

  6. <运营商,#4>

  7. <文字,#3>

  8. <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>