语义分析是编译器设计的关键组成部分,主要关注程序的意义,即确保程序的逻辑正确性。在本篇“编译原理及实现技术:17.语义分析_语义表示基础”中,我们将深入探讨这一主题。
我们需要区分语法和语义。语法指的是程序的结构规则,决定了哪些字符串构成有效的程序。而语义则是关于这些结构合法的程序实际意义的规则。语义分为静态语义和动态语义。静态语义是在编译阶段可检查的,如标识符的声明;动态语义则在程序运行时检查,如除零错误或溢出。
语义分析的主要任务包括类型分析和标识符相关信息的提取。它负责检查语义错误,如类型不兼容、表达式中操作数类型不匹配等,并构建标识符属性表,也就是符号表。符号表包含诸如常量、变量、类型、函数和过程等标识符的详细信息,以供后续编译阶段使用。
在进行语义错误检查时,会涉及以下方面:
1. 确保条件表达式的结果是布尔类型。
2. 运算符的操作数类型应相容。
3. 赋值语句的左右两边类型需一致。
4. 形参和实参的类型匹配。
5. 下标表达式的类型是允许的类型。
6. 函数声明与实现的返回类型一致。
语义分析处理后,会生成一系列新的Token序列,以及符号表、常量表、类型表、函数信息表、数组信息表、记录信息表等,用于存储标识符的各种信息。
标识符在程序中有两种出现方式:声明性和使用性。声明性出现在程序头部或函数头,如变量或类型的声明;使用性出现在程序体或函数体,如变量的使用。
标识符可以分为几种类型:常量标识符、类型标识符、变量标识符(包括实参和形参)、过函标识符(实际函数和形式函数)以及域名标识符。每个标识符都有其特定的属性,包括名字、种类信息、类型信息和针对不同类型的独特信息。
对于常量标识符,其内部表示通常包括名字、常量类型和值的指针。类型标识符则包含名字、类型标识符标志和类型表示的指针。变量标识符的内部表示则涉及其访问类型(直接或间接)、声明所在的层次、偏移量、类型指针以及可能的初始值。
语义分析在编译过程中起到确保源代码逻辑正确性的关键作用,通过检查和表示标识符的语义信息,保证程序在编译阶段就能识别和纠正许多潜在错误,从而提高程序的质量和可维护性。