编译过程中的词法和句法分析是什么?预处理是否在词法和句法分析之后发生?
答案 0 :(得分:14)
考虑以下代码:
int a = 10;
if (a < 4)
{
printf("%d", a);
}
在词法分析阶段:您识别每个单词/标记并为其指定含义。 在上面的代码中,首先要确定 i ,然后是 n ,然后是 t ,然后空格是 int < / strong>,它是一个语言关键字; 1 后跟 0 ,空格是 10 ,等等。
在语法分析阶段:验证代码是否遵循语言语法(语法规则)。例如,您检查运算符的LHS上是否只有一个变量(考虑语言C),每个语句都以; 终止,如果通过条件/布尔语句等。
与其他人提到的一样,通常,预处理在词法分析或句法分析之前发生。
答案 1 :(得分:2)
词法分析发生 BEFORE 语法分析。这是合乎逻辑的,因为当需要调用宏时,必须首先识别标识符的边界。这是通过词法分析完成的。在语法分析开始之后。请注意,在开始语法分析之前,编译器通常不会生成完整的预处理源。他们读取源一次选择一个lexema,如果需要进行预处理,并将结果提供给句法分析。
在一个案例中,词法分析发生两次。这是粘贴缓冲。看一下代码:
#define En(x) Abcd ## x ## x
enum En(5)
{
a, b = 20, c, d
};
此代码定义名称为Abcd55
的枚举。在宏扩展期间处理##
时,数据将放入内部缓冲区。之后,这个缓冲区的扫描就像一个小的#include。在扫描期间,编译器会将缓冲区的内容分解为lexemas。可能会发生扫描的lexemas的边界与放入缓冲区的原始lexemas的边界不匹配。在上面的例子中,3个lexemas放入缓冲区,但只检索了一个。
答案 2 :(得分:1)
预处理在词法分析之前发生 注释被过滤掉,#define,...然后,编译器生成带有扫描器/词法分析器(词法分析)的标记。之后编译器生成用于语法分析的分析树
答案 3 :(得分:0)
有例外情况,但通常会出现这样的情况:
“抽象语法”的定义可能有所不同。在一次通过编译器中,抽象语法相当于tartget代码。但是这些日子通常是树或DAG逻辑上代表程序的结构。
答案 4 :(得分:0)
当我们谈论C编程语言时,我们应该注意到该语言有一个ISO(ANSI)标准。以下是C99的最后公开草案(ISO / IEC 9899:1999):www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
有一节“5.1.1.2翻译阶段”,说明如何解析C程序。有阶段:
...多字节,三字符和反斜杠处理的一些步骤......
3)。源文件被分解为预处理令牌和序列 空格字符(包括注释)。
这是预处理的词法分析。只有预处理程序指令,标点符号,字符串常量,标识符,注释在这里被激活。
4)。执行预处理指令,扩展宏调用
这是预处理本身。此阶段还将包含来自#include
的文件,然后它将删除预处理指令(如#define
或#ifdef
和其他)
...处理字符串文字...
7)。分隔标记的空白字符不再重要。每 预处理令牌转换为令牌。由此产生的代币是 语法和语义分析和翻译为翻译单位。
转换为令牌意味着语言关键字检测和常量检测。 这是最终词汇分析的一步;句法和语义分析。
所以,你的问题是:
预处理是否在词法和句法分析之后发生?
需要进行一些词法分析来进行预处理,所以顺序是: lexical_for_preprocessor,preprocessing,true_lexical,other_analysis。
PS:Real C编译器的组织方式可能略有不同,但必须的行为方式与标准编写方式相同。