1 / 33

第六章 语义分析

语义分析概述 符号表. 第六章 语义分析. 必要性 分类 语义错误 功能. 1 语义分析. 1.1 语义分析的必要性. 语法和语义的区别 语法:关于什么样的字符串才是该语言在组成结构上合法的程序的法则。 语义:关于结构上合法的程序的意义法则。. 1.2 语义分析的分类. 语义种类 指称语义 操作语义 公理语义 静态语义 :在编译阶段(从程序文本上)可以检查的语义。 动态语义 :通过程序的执行才能检查的语义。. 1.3 语义错误. 各种条件表达式的 类型 是不是 boolean 型 ? 运算符的分量的 类型 是否相容 ?

morwen
Download Presentation

第六章 语义分析

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 语义分析概述 符号表 第六章 语义分析

  2. 必要性 分类 语义错误 功能 1 语义分析

  3. 1.1语义分析的必要性 • 语法和语义的区别 语法:关于什么样的字符串才是该语言在组成结构上合法的程序的法则。 语义:关于结构上合法的程序的意义法则。

  4. 1.2语义分析的分类 • 语义种类 • 指称语义 • 操作语义 • 公理语义 • 静态语义:在编译阶段(从程序文本上)可以检查的语义。 • 动态语义:通过程序的执行才能检查的语义。

  5. 1.3语义错误 • 各种条件表达式的类型是不是boolean型? • 运算符的分量的类型是否相容? • 赋值语句的左右部的类型是否相容? • 形参和实参的类型是否相容? • 下标表达式的类型是否为所允许的类型? • 函数说明中的函数类型和返回值的类型是否一致? • V[E]中的V是不是变量,而且是数组类型? • V.id中的V是不是变量,而且是记录类型? id是不是该记录类型中的域名? • y+f(…)中的f是不是函数名?形参个数和实参个数是否一致? • p(…)语句中的p是不是过程名?形参个数和实参个数是否一致? • V↑中的V是不是指针或文件变量? • 变体记录中表示情形的常量是否为合法类型? • 子界类型中的下界和上界类型是否相容?下界是否小于等于上界?

  6. 语义错误 cont. • 每个使用性标识符是否都有声明?在同层内有无标识符被声明多次? • 标号是否有声明?有无重复声明和重复定位错误?有无非法转入错误?

  7. 1.4语义分析的功能 • 语义分析的内容: • 类型分析; • 标识符相关信息提取; • 语义分析的功能: • 检查语义错误 • 构造标识符属性表(符号表) • 语义分析的实现: • 与语法分析相结合

  8. 语义分析的功能图示 语法分析树 语义分析 符号表 TokenList 语义定义 判定语义错误 自然语言描述规定

  9. 2 符号表

  10. 2.1地位

  11. 2.2符号的内部表示 • 值的内部表示 • 类型的内部表示 • 标识符的内部表示

  12. 2.2.1值的内部表示 基本类型:整型,实型 无序类型:指针,数组,结构体 有序类型:布尔,字符,枚举,数组下标 • 布尔常量:ord(false)=0, ord(true)= 1 • 字符常量:ord(C) = ASCⅡ(C) • 枚举常量:设有枚举类型(D,A,B),则有ord(D)=0,ord(A)=1,ord(B)=2

  13. 2.2.2类型的内部表示 • 类型的种类:标准、子界、枚举、数组、记录、集合、文件、指针类型等 Type=(intTy,boolTy,charTy,realTy, subTy,enumTy, arrayTy,recordTy,setTy,fileTy,pointerTy) • 内部表示:(TypeIR) int/bool/ char/real: enum: array: pointer:

  14. 实例 int f(real x, char y){ bool t=true; enum a {a1,a2,a3}; real b[M]; char c*; return t; } 写出各类型的内部表示。

  15. 类和结构体 • 结构体 • 类

  16. 实例 class Student{ String name; int age; real mark; public Student(String n,int a, real m){ this.name=n; this.age=a; this.mark = m;} get… set… }

  17. 2.2.3标识符的内部表示 • 常见标识符种类:常量名、类型名、变量名、函数名、过程名、域名。 Kind=(consKind, typeKind, varKind,fieldKind, funcKind,procKind) • 内部表示(AttributeIR): 常量名: 变量名: 类型名: 过函名: 域名名:

  18. 层数和偏移 • 层数(level) • 过程/函数的定义(不)可以嵌套; • 最外层程序的层数为1(0); • 偏移量(offset) • 原因:执行过程/函数的调用时, 需要为其中的变量分配空间; • 计算:偏移量指的是变量针对其所在过程/函数的空间的首地址的偏移量;

  19. 实例 #define Pi 3.14 bool g(real x, int * y){ int v[10];real z;return 0;} enum gender {male,female}; Main(){…} 令当前层数和偏移分别为L和0,构造标识符Pi,g,x,y,v,z,gender的属性表。

  20. 2.3符号表 • 标识符在不同位置的不同作用: • 声明部分:定义了各种对象及对应的属性和使用规则。 • 程序体:对所定义的对象进行各种操作。 • 必要性 • Token序列: • 符号表(种类、类型等信息):

  21. 2.3.1建立和访问 有关符号表的操作: 添加、作用域删除、查询 处理符号表的模块: 定义符号表数据结构 定义符号表上的操作

  22. 2.3.2符号表的处理 • 符号表的作用:为语义检查和代码生成提供标识符的语义信息。 • 标识符的处理思想: • 遇到定义性标识符时,在符号表中填写被定义标识符的符号项; • 遇到使用性标识符时,用该标识符查符号表求得其属性。

  23. 标识符的特点 • 标识符的作用域:标识符有效的最大程序段 • 嵌套作用域规则:当存在标识符的嵌套声明时,最近定义的属性为标识符的当前属性 • 局部化单位:允许有声明的程序段 P: Var x ,y,z x:=0; Q: Var x,m,n x:=1; m:=x+1; y:=x+1;

  24. 局部化区入口 • Proc p(… • Func f(… • Record begin…

  25. 标识符处理的原则 • 符号表的种类:全局符号表、局部符号表 • 处理原则: • 进入一个局部化区时,记录本层符号表的位置 • 遇到定义性标识符时,构造其语义信息,查本层符号表,若存在,则有重复声明错误,否则将语义信息填入表中 • 遇到一个使用性标识符时,查表(从里层到外层),查不到则有未定义标识符错误,否则构造新的TOKEN • 退出一个局部化区时,作废本层符号表

  26. 语义分析例子 int x,y; void swap(int *a,int *b){ int tmp; temp=*a; *a=*b;*b=tmp; } void main(){ x=10; y=20; swap(&x,&y); }

  27. 符号表的分类 • 单表结构 vs. 多表结构 • 单表:标识符都放在同一张符号表中 • 多表:常量、变量、类型、函数、等分别存放 • 局部表 vs. 全局表 • 局部式:每个局部化单位建立一个独立符号表 • 全局式:整个程序的符号表作为一个表

  28. 全局符号表的局部化 删除法 vs. 驻留法

  29. 局部化实例 int main() { int a; float b,d; { int c; float a; { int d; float c; { float d; //... a=b+c+d; } } { char d; } } return 0; }

  30. 局部符号表管理——Scope栈 • 用于存放当前有效的局部化区的局部符号表首地址; • 进入新局部化区时新符号表首地址入栈; • 退出局部化区时栈顶地址出栈。

  31. 标号的语义分析 • 标号出现的位置: 标号声明:label 1, 2, …, n; 标号定位(语句前):i:Statement; 标号使用(Goto后):goto i; • 标号部分的语义错误: • 标号重复声明; • 标号重复定位; • 标号有定位而无声明; • 标号有使用而无定位; • Goto语句有非法转入.

More Related