Tokens做了什么以及为什么需要在C++编程中创建它们?

eli*_*eth 5 c++ token c++11

我正在读一本书(Bjarne Stroustrup的编程原则和实践).

他在其中介绍了令牌:

"令牌是一系列字符,代表我们认为是单位的东西,例如数字或运算符.这就是C++编译器处理其源代码的方式.实际上,以某种形式"标记化"是大多数文本分析开始的方式."

class Token {
public:
    char kind;
    double value;
};
Run Code Online (Sandbox Code Playgroud)

我确实得到了他们的样子,但他从来没有详细解释过这一点,而且对我来说很困惑.

Sto*_*ica 7

标记化对于确定程序的功能非常重要.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++语言中含有"字样),然后检查标记是否出现在一个有效的"句子"中含义.


fre*_*ish 5

他指的是词法分析 - 每个编译器的必要部分.它是编译器以有意义的方式处理文本(如:字节序列)的工具.例如,考虑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)

它没有被解释像上面(注意,在我的情况都kindvalue都是字符串),它只是一个例子可以怎么做.您通常通过一些正则表达式执行此操作.

无论如何,对于机器而言,原始文本更容易理解.编译器的下一步是基于标记化创建所谓的抽象语法树,最后为所有内容添加含义.

另请注意,除非您正在编写解析器,否则您不太可能使用该概念.


far*_*han 3

正如其他人提到的,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++ 编译器将文件数据传输到跳过所有空格的标记序列。使其能够被自己理解。