我正在读一本书(Bjarne Stroustrup的编程原则与实践)。
他介绍了Tokens:
“令牌是一系列字符,代表我们认为是单位的东西,例如数字或运算符。这就是C ++编译器处理其源代码的方式。实际上,以某种形式“标记化”是大多数文本分析开始的方式。“
class Token {
public:
char kind;
double value;
};
我确实得到了他们的样子,但他从来没有详细解释过这一点,而且对我来说很困惑。
答案 0 :(得分:7)
标记化对于确定程序的功能非常重要。 Bjarne所指的与C ++源有关的内容涉及程序含义如何受到标记化规则的影响。特别是,我们必须知道令牌是什么,以及它们是如何确定的。具体来说,当一个令牌出现在其他字符旁边时,我们如何识别它?如果存在歧义,我们应该如何划分令牌。
例如,考虑前缀运算符++
和+
。假设我们只有一个令牌+
可以使用。以下代码段的含义是什么?
int i = 1;
++i;
仅使用+
,上述内容只会在+
上两次应用一元i
吗?或者它会增加一次?它自然是暧昧的。我们需要一个额外的令牌,因此在语言中引入++
作为自己的“单词”。
但现在还有另一个问题(虽然规模较小)。如果程序员希望只应用一次+
两次而不是递增,该怎么办?需要令牌处理规则。因此,如果我们确定空格始终是令牌的分隔符,我们的程序员可能会写:
int i = 1;
+ +i;
粗略地说,C ++实现以一个充满字符的文件开始,最初将它们转换为一系列标记(“C ++语言中含有”字样),然后检查标记是否出现在“句子”中有一些有效的意思。
答案 1 :(得分:5)
他正在引用the lexical analysis - 每个编译器的必要部分。它是编译器以有意义的方式处理文本(如:字节序列)的工具。例如,考虑C ++中的以下行
double x = (15*3.0); // my variable
当编译器查看文本时,它首先将该行拆分为一系列令牌,如下所示:
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"}
它不必像上面那样解释(请注意,在我的情况下,kind
和value
都是字符串),它只是一个例子,它是如何完成的。你通常通过一些正则表达式来做到这一点。
无论如何,对于机器而言,原始文本更容易理解。编译器的下一步是基于标记化创建所谓的abstract syntax tree,最后为所有内容添加含义。
另请注意,除非您正在编写parser,否则您不可能使用此概念。
答案 2 :(得分:2)
正如其他人所说,Bjrane指的是词汇分析。
一般来说,标记化||创建令牌,是一个处理输入流并将它们分成块的过程,而不必担心@StoryTeller早先最好描述的空格等。 "或者如bjrane所说:是一系列字符代表我们认为是单位的字符"。
令牌本身就是C ++用户定义类型的一个例子' UDT'像int或char,因此token可用于定义变量和保存值。
UDT可以包含成员函数和数据成员。在您的代码中,您定义了两个非常基本的成员函数。
1)种类,2)价值
class Token {
public:
char kind;
double value;
};
基于它,我们可以初始化或构建它的对象。
Token token_kind_one{'+'};
使用其类型(运算符)' +'初始化token_kind_one。
Token token_kind_two{'8',3.14};
和token_kind_two及其种类(整数/数字)' 8'并且值为3.14。
让我们假设我们有一个10个字符的表达式1 + 2 * 3(5/4),这意味着10个令牌。
令牌:
|----------------------|---------------------|
Kind |'8' |'+' |'8' |'*'|'8'|'('|'8' |'/'|'8' |')'|
|----------------------|---------------------|
Value | 1 | | 2 | | 3 | | 5 | | 4 | |
|----------------------|---------------------|
C ++编译器将文件数据传输到跳过所有空格的标记序列。让它自己理解。
答案 3 :(得分:-1)
从广义上讲,编译器将在给定源代码上运行多个操作,然后再将其转换为二进制格式。第一阶段之一是运行标记化器,其中源文件的内容被转换为标记,标记是编译器理解的单元。例如,如果您编写语句int a
,则标记生成器可能会创建一个结构来存储此信息。
Type: integer
Identifier: A
Reserved Word: No
Line number: 10
这将被称为令牌,源文件中的大多数代码将被分解为类似的结构。