我正在读一本书(Bjarne Stroustrup的编程原则和实践).
他在其中介绍了令牌:
"令牌是一系列字符,代表我们认为是单位的东西,例如数字或运算符.这就是C++编译器处理其源代码的方式.实际上,以某种形式"标记化"是大多数文本分析开始的方式."
class Token {
public:
char kind;
double value;
};
Run Code Online (Sandbox Code Playgroud)
我确实得到了他们的样子,但他从来没有详细解释过这一点,而且对我来说很困惑.
标记化对于确定程序的功能非常重要.Bjarne所指的与C++源有关的内容涉及程序含义如何受到标记化规则的影响.特别是,我们必须知道令牌是什么,以及它们是如何确定的.具体来说,当它出现在其他字符旁边时,我们如何识别单个标记,如果存在歧义,我们应该如何划分标记.
例如,考虑前缀运算符++和+.我们假设我们只有一个令牌可供使用+.以下代码段的含义是什么?
int i = 1;
++i;
Run Code Online (Sandbox Code Playgroud)
随着+而已,上面将只适用于一元+的i两倍?或者它会增加一次?它自然是暧昧的.我们需要一个额外的令牌,因此++在语言中引入它自己的"单词".
但现在还有另一个(虽然更小)的问题.如果程序员想要一次性应用一元+,而不是递增怎么办?需要令牌处理规则.因此,如果我们确定空格始终是令牌的分隔符,我们的程序员可能会写:
int i = 1;
+ +i;
Run Code Online (Sandbox Code Playgroud)
粗略地说,C++实现以一个充满字符的文件开始,最初将它们转换为一系列标记("C++语言中含有"字样),然后检查标记是否出现在一个有效的"句子"中含义.
他指的是词法分析 - 每个编译器的必要部分.它是编译器以有意义的方式处理文本(如:字节序列)的工具.例如,考虑C++中的以下行
double x = (15*3.0); // my variable
Run Code Online (Sandbox Code Playgroud)
当编译器查看文本时,它首先将该行拆分为一系列令牌,如下所示:
Token {"identifier", "double"}
Token {"space", " "}
Token {"identifier", "x"}
Token {"space", " "}
Token {"operator", "="}
Token {"space", " "}
Token {"separator", "("}
Token {"literal_integer", "15"}
Token {"operator", "*"}
Token {"literal_float", "3.0"}
Token {"separator", ")"}
Token {"separator", ";"}
Token {"space", " "}
Token {"comment", "// my variable"}
Token {"end_of_line"}
Run Code Online (Sandbox Code Playgroud)
它没有被解释像上面(注意,在我的情况都kind和value都是字符串),它只是一个例子可以怎么做.您通常通过一些正则表达式执行此操作.
无论如何,对于机器而言,原始文本更容易理解.编译器的下一步是基于标记化创建所谓的抽象语法树,最后为所有内容添加含义.
另请注意,除非您正在编写解析器,否则您不太可能使用该概念.
正如其他人提到的,Bjrane 指的是词法分析。
一般而言,标记化|| 创建令牌,是处理输入流并将它们分成块的过程,而不用担心空格等。@StoryTeller 之前对此进行了最好的描述。“或者正如 bjrane 所说:是一个字符序列,代表我们认为是一个单位的东西”。
令牌本身是 C++ 用户定义类型“UDT”(如 int 或 char)的示例,因此令牌可用于定义变量并保存值。
UDT 可以具有成员函数和数据成员。在您的代码中,您定义了两个非常基本的成员函数。
1)种类,2)价值
class Token {
public:
char kind;
double value;
};
Run Code Online (Sandbox Code Playgroud)
基于它我们可以初始化或构造它的对象。
Token token_kind_one{'+'};
Run Code Online (Sandbox Code Playgroud)
使用其类型(运算符)“+”初始化 token_kind_one。
Token token_kind_two{'8',3.14};
Run Code Online (Sandbox Code Playgroud)
token_kind_two 的种类(整数/数字)为“8”,值为 3.14。
假设我们有一个包含十个字符的表达式 1+2*3(5/4),这会转换为十个标记。
代币:
|----------------------|---------------------|
Kind |'8' |'+' |'8' |'*'|'8'|'('|'8' |'/'|'8' |')'|
|----------------------|---------------------|
Value | 1 | | 2 | | 3 | | 5 | | 4 | |
|----------------------|---------------------|
Run Code Online (Sandbox Code Playgroud)
C++ 编译器将文件数据传输到跳过所有空格的标记序列。使其能够被自己理解。
| 归档时间: |
|
| 查看次数: |
1293 次 |
| 最近记录: |