- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
符号表的实现
用局部符号表实现 proc p:x,y,z proc p1:x,y1,z1 proc p2:y y,z x,y1,z1,y proc p3:z,a x,y,a x,z
符号表的实现
用全局符号表实现 proc p0:x,y proc p1:x,z y proc p2:x1,y1 y x,z
若有,则检查其Flag位,若是1,则有重复定位错误; 若Flag=0,令其Flag位为1,并将ℓ 填入LDEF表中; 查看LUSE表,若其中有ℓ则将其删除掉。
4)进入一个结构语句时,将本语句的LDEF和LUSE表位置填 入SL表。 5)遇到一个“goto ℓ” 时: 查看LDEF表,看其中是否有ℓ; 若无,将填入LUSE表。 6)退出一个结构化语句时: 清查本层LUSE表(若有定位则删除该项):用本层的 LUSE中标号查本层定位表,若查到,则把该项从LUSE 中删除; 作废本层的LDEF。 7)退出一个过/函时: 清查本层LUSE表; 作废本层的LDEC和LDEF。 8)程序结束时,清查LUSE表,若非空,则说明有标号为定 位的错误。
标准类型: Size sub: enum: array:
Size Size Size Kind HostType Elems Low Up Leng ElemType
Kind Kind Kind
IndexType
record:
Size Kind FixBody VariBody id FixUnitType Off Next
值的内部表示
非结构类型值的内部表示:
实型 指针 有序类型:整数形式
有序类型的常量表示:
整型常量:ord(N) = N 布尔常量:ord(false)=0, ord(true) = 1 字符常量:ord(C) = ASCⅡ (C) 枚举常量:设有枚举类型(D,A,B),则有 ord(D)=0,ord(A)=1,ord(B)=2 子界常量:设有子界类型C1..C2,则值空间 为[ord(C1)...ord(C2)]
符号表
符号表的作用:为语义检查和代码生成提供 标识符的语义信息。 标识符的处理思想: 遇到定义性标识符时,在符号表中填写 被定义标识符的符号项; 当遇到使用性标识符时,用该标识符查 符号表求得其属性。
标识符的特点
标识符的作用域:标识符有效的最大程序段 嵌套作用域规则:当存在标识符的嵌套声明 时,最近定义的属性为标识符的当前属性 局部化单位:允许有声明的程序段
标号部分语义分析原理
设置五种表:LDEC,LDEF,LUSE,SL,PL
LDEC表:(Flag, Label,<Label>); LDEF、LUSE表:(Label); SL表:(kind,LDEFaddr,LUSEaddr); PL表:(LDECaddr,LDEFaddr);
标号的语义分析原理
FixBody: VariBody:
CaseUnit VariUnits
FixBody
VariBody Next
id CaseType Off
set:
Size Size Size
Kind Kind Kind
BaseType CompType TypeName
file:
pointer:
例有如下的类型定义:
语义分析例子
program p() type at=array[1..100] of array[1..10] of inteter var x:real; a:at; i:integer; proc p1(var a1:at; a2:at) var x:integer; a:real; proc p2(n:integer) var m:1..50; x:real; m,n,x(使用性出现) end a1,a2,x,a,i(使用性出现) end x,a,i(使用性出现) end
类型的内部表示
类型的种类:标准、子界、枚举、数组、记录、 集合、文件、指针类型等等。 TypeKind=(intTy,boolTy,charTy,realTy,enumTy, subTy,arrayTy,recordTy,setTy,f表示:(TypeIR)
标号的语义分析
标号出现的位置: 标号声明:label 1, 2, …, n; 标号定位(语句前):i:Statement; 标号使用(Goto后):goto i; 标号部分的语义错误: 标号重复声明; 标号重复定位; 标号有定位而无声明; 标号有使用而无定位; Goto语句有非法转入。
1)进入一个过/函时,将本层LDEC和LDEF的地址填入PL表。 2)遇到一个标号声明“label 1, 2,…,n”时,建立本层LDEC表(检查 重复声明错误),其中的Flag标志均设置为0。 3)遇到定位性标号“:Statement”时:
检查在LDEC表中有无ℓ ,若无则表示无标号声明错误;
语义定义 自然语言描述规定
判定
三种内部表示
标识符的内部表示 类型的内部表示 值的内部表示
标识符的内部表示
标识符种类:
常量名、类型名、变量名、函数名、过程名、域名。 TYPE idkind=( consKind, typeKind, varKind, fieldKind, procKind,funcKind )
at = ARRAY [1..10] OF ARRAY[1..100] OF integer; rt = RECORD x : real ; a : at; CASE u: boolean OF false:(k : integer); true:(y: real; b: boolean) END 构造类型的内部表示。
例有声明如下:
CONST pai= 3.14 ; TYPE vector=ARRAY[1..10] OF integer; VAR x, y : real ; r, s : vector ; 设当前层数和可用offset值分别为L和0, 构造标识符 pai, vector, x, y, r 和s 的属性表示。
语义分析和符号表
主要内容:
语义分析概述(必要性、功能、描述方法)
符号表
类型表达式 声明和程序体的语义分析
语义分析的必要性
语法和语义的区别: 语法:关于什么样的字符串才是该语言 在组成结构上合法的程序的法则。 语义:关于结构上合法的程序的意义的 法则。
语义分析的功能
语义种类
静态语义:在编译阶段(从程序文本上)可 以检查的语义。 动态语义:通过程序的执行才能检查的语 义。
语义的描述
语义形式化方法: 1. 操作语义 2. 指称语义 3. 公理语义 4. 代数语义
语义分析的内容:
类型分析 标识符相关信息
语义分析的功能:
检查语义错误 构造标识符属性表(符号表)
语义分析的实现:
与语法分析相结合
语义分析的功能图示
语法分析树 语义分析 符号表
TokenList
内部表示(AttributeIR):
常量: 类型: 变量: 域名*: 过函:
TypePtr TypePtr Kind Kind Value Forward
TypePtr Kind
TypePtr Kind
Access
Off
Level
Off
Off
HostType
TypePtr Kind
Level Parm Class Code Size Forward
符号表
标识符的作用: 声明部分:定义了各种对象及对应的属性和 使用规则。 程序体:对所定义的对象进行各种操作。 必要性
Token:
$id
idname
新表-符号表(种类、类型等信息):
Idname AttributeIR
有关符号表的操作: 添加、作用域删除、查询 处理符号表的模块: 定义符号表数据结构 定义符号表上的操作
P: Var x ,y,z x:=0; Q: Var x,m,n x:=1; m:=x+1; y:=x+1;
局部化区入口
Proc p(… Func f(… 形式过/函 p( … f(… Record begin…
标识符处理的原则
符号表的种类:全局符号表、局部符号表 原则: 进入一个局部化区时,记录本层符号表的 位置 遇到定义性标识符时,构造其语义信息, 查本层符号表,若存在,则有重复声明错 误,否则将语义信息填入表中 遇到一个使用性标识符时,查表(从里层 到外层),查不到则有未定义标识符错 误,否则构造新的TOKEN 退出一个局部化区时,作废本层符号表