C编译器编译过程中的词法和语法分析是什么?
考虑以下代码:
int a = 10;
if (a < 4)
{
printf("%d", a);
}
在词法分析阶段:你确定每个词/令牌和分配的意义吧。 在上面的代码中,通过识别我随后Ñ随后吨然后空间是字INT,而且它是一种语言关键字开始; 其次是和一个空格是一个数字等等。
在句法分析阶段:验证代码是否遵循语言语法(语法规则)。例如,您检查一个操作符的LHS是否只有一个变量(考虑语言C),每个语句是否由终止;,即如果后跟一个条件/布尔语句等
像其他人一样,通常预处理发生在词法分析或语法分析之前。
也有例外,但它通常爆发这样的:
- 预处理 - 变换程序文本编程文本
- 词法分析 - 变换程序文本为“令牌”,它基本上是小的整数附
- 句法分析的属性 - 变换程序文本到抽象语法
“抽象语法”的定义可能会有所不同。在单通道编译器中,抽象语法相当于tartget代码。但是,这些日子通常是树或DAG,它们逻辑上代表了程序的结构。
词法分析发生在之前的语法分析。这是合乎逻辑的,因为当有必要调用宏时,首先需要标识标识符的边界。这是通过词法分析完成的。之后进行语法分析。请注意,编译器通常在开始语法分析之前不会生成完整的预处理源。他们一次读取源代码选择一个词素,根据需要进行预处理,并将结果提供给语法分析。
在一种情况下,词法分析发生两次。这是粘贴缓冲。看看代码:
#define En(x) Abcd ## x ## x
enum En(5)
{
a, b = 20, c, d
};
此代码定义名为Abcd55
的枚举。在宏扩展期间处理##
时,数据被放入内部缓冲区。之后,这个缓冲区被扫描得很像一个小#include。在扫描期间,编译器会将缓冲区的内容分解为lexemas。可能发生的情况是,被扫描的词素的边界将与放入缓冲区的原始词法的边界不匹配。在上面的例子中,3个lexemas被放入缓冲区,但只有一个被检索。
当我们谈论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,预处理,true_lexical,other_analysis。 PS:Real C编译器可能会以稍微不同的方式组织,但它的必须的行为与标准中写入的方式相同。
你在说什么语言?请添加相关标签。 –
@OliCharlesworth完成! – Raulp
预处理发生在链接完成之前。所有的宏在编译前都被替换。 – squiguy