第六章 语义分析和符号表

合集下载

第6章语法制导

第6章语法制导
• 方法
–编写说明语句的文法 编写说明语句的文法 –将类型信息作为类型描述 T 的属性 type 将类型信息作为类型描述 in。 和变量表 L 的属性 in。
• 目的
–分析说明语句 D,为变量指定类型 分析说明语句
13
addtype
addtype
addtype
例:real id1,id2,id3 的分析树和 属性计算 14
2
语义分析的任务
• 语义检查
–例:类型、运算、维数、越界 例 类型、运算、维数、
• 语义处理
–例:变量的存储分配 例 –例:表达式的求值 例 –例:语句的翻译(中间代码的生成) 例 语句的翻译(中间代码的生成)
• 总目标:生成等价的中间代码 总目标:
3
处理方法
• 对应每一个产生式编制一个语义子程序, 对应每一个产生式编制一个语义子程序, 当一个产生式获得匹配时, 当一个产生式获得匹配时,调用相应的语 义子程序实现语义检查与翻译。 义子程序实现语义检查与翻译。 • 在产生式的右部的适当位置,插入相应的 在产生式的右部的适当位置, 语义动作,按照分析的进程, 语义动作,按照分析的进程,执行遇到的 语义动作。 语义动作。
第六章
• • • • •
属性文法和语法制导翻译
语法制导翻译概述 属性文法 翻译模式 自顶向下翻译方法 自底向上翻译方法
1
6.1 语法制导翻译概述
• 语法制导翻译以属性文法为基础 • 语法结构具有规定的语义 • 在进行语法分析的同时,完成相应的语 在进行语法分析的同时, 义处理 • ???如何根据被识别出的语法成分进 ???如何根据被识别出的语法成分进 行语义处理
消除左递归后的翻译模式: 消除左递归后的翻译模式: E → T {R.i := T.val} R{E.val:=R.s} R → + T {R1 .i:=R.i+T.val} } R → - T {R1 .i:=R.i+T.val} } R → ε {R.s:=R.i} R T → num T → ( E )

编译原理课件(刘铭)第6章

编译原理课件(刘铭)第6章

本章小结
也就是说标识符是一个没有意义 的字符序列,而名字有确切的意义。 在程序语言中标识符可以是一个变量 的名字或一个函数的名字。
例如 area , 作为标识符,它没有 任何意思,但作为名字,可以表示 变量名或函数名等。
本章小结
3. 符号表的查找
符号表查找算法与该符号表的构造方法 密切相关即有顺序查找、折半查找和杂 凑查找算法。
6.3 符号表的组织
一个编译程序,从词法分析、语法 分析、语义分析到代码生成的整个过程 中,符号表是连贯上下文进行语义检查、 语义处理、生成代码和存储分配的主要 依据,因此符号表的组织直接关系到这 些语义功能的实现和语义处理的时空效 率。
6.3 符号表的组织
符号表的表格形式
名 字 栏 信 息 栏
符号表的作用
符号表的组织
符号表的建立和查找
6.1 符号表的作用与生成期
符号表的作用 符号表用来存放程序语言中出现 的有关标识符的属性和特征。 符号表在整个编译期间的作用归 纳为以下几个方面: 将标识符的名字及属性登录在符号 表中
6.1 符号表的作用与生成期
在分析说明语句时,编译程序根 据说明语句信息将标识符的相应属性 如标识符的类型:实型,整型,布尔 型等;标识符的种属:数组名,变量 名,过程名,函数名等; 标识符的作用 域:全局变量或局部变量等信息登录 到符号表中。
名字栏存放标识符的名字,信息栏存放 名字相关属性。
. . .
. . .
6.3 符号表的组织
符号表的总体组织 1. 编译程序按名字的不同属性构造出多 个符号表。如常量表、变量名表等。 符号表结构相同,表项等长。不便管理。
2. 编译程序把语言中的所有名字组织在 一张符号表中。 符号表便于管理,但表结构复杂且表项 不等长。

ch06--语义分析

ch06--语义分析
7
6.2

符号表
符号表在翻译过程中起两方面的重要作用:
–检查语义(即上下文有关)的正确性 –辅助正确地生成代码

通过在符号表中插入和检索变量的属性来实现的 符号表是一张动态表
–在编译期间符号表的入口不断地增加 –在某些情况下又在不断地删除

Wensheng Li BUPT
编译程序需要频繁地与符号表进行交互,符号表的 效率直接影响编译程序的效率。
变量名 able_n b_loop count flag form mlist x_total 类型 1 1 2 1 3 6 1 维数 0 0 1 0 2 0 0 声明行 5 5 2 7 4 6 3 引用行 11,23,25 10,11,13 9,14,15 28,29 36,37,38 17,21 12,14
优化 目标代码
其他遍
符号表

Wensheng Li BUPT
两方面的优点:
– 对语法分析程序来讲降低了文法的复杂性 – 允许用更系统的方法对上下文有关的错误进行检测和校正。
11
二、符号表内容


符号表中记录的是和标识符相关的属性 出现在符号表中的属性种类,在一定程度上取决 于程序设计语言的性质。 符号表的典型形式:
–实参的个数与形参的个数一致 –实参的类型与相应形参的类型一致

Wensheng Li BUPT
在符号表组织中:
–把参数的个数看作它的维数是很方便的,因此,可将这 两个属性合并成一个。 –这种方法也是协调的,因为对这两种属性所做的类型检 查是类似的。
17
交叉引用表


编译程序可以提供的一个十分重要的程序设计辅 助工具:交叉引用表 编译程序一般设一个选项,用户可以选择是否生 成交叉引用表

第六章 语义分析和符号表

第六章 语义分析和符号表

FixBody: VariBody:
CaseUnit VariUnits
FixBody
VariBody Next
id CaseType Off
set:
Size Size Size
Kind Kind Kind
BaseType CompType TypeName
file:
pointer:
例有如下的类型定义:
标号部分语义分析原理
设置五种表:LDEC,LDEF,LUSE,SL,PL
LDEC表:(Flag, Label,<Label>); LDEF、LUSE表:(Label); SL表:(kind,LDEFaddr,LUSEaddr); PL表:(LDECaddr,LDEFaddr);
标号的语义分析原理
符号表
符号表的作用:为语义检查和代码生成提供 标识符的语义信息。 标识符的处理思想: 遇到定义性标识符时,在符号表中填写 被定义标识符的符号项; 当遇到使用性标识符时,用该标识符查 符号表求得其属性。
标识符的特点
标识符的作用域:标识符有效的最大程序段 嵌套作用域规则:当存在标识符的嵌套声明 时,最近定义的属性为标识符的当前属性 局部化单位:允许有声明的程序段
标准类型: 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
类型的内部表示
类型的种类:标准、子界、枚举、数组、记录、 集合、文件、指针类型等等。 TypeKind=(intTy,boolTy,charTy,realTy,enumTy, subTy,arrayTy,recordTy,setTy,fileTy,pointerTy)

语义分析和语法制导翻译-编译原理-06-(二)

语义分析和语法制导翻译-编译原理-06-(二)
E.p
是语法结构树指针 是名字的表项入口 是数值
id.entry num.val
树构造函数
mknode 建中间结点 mkleaf 建叶结点
生成语法树的属性文法
产生式 S→id:=E 语义规则 S.p:= mknode(':=', mkleaf(id, id.entry), E.p)
E→E1+E2 E.p:= mknode('+', E1.p, E2.p) E→E1*E2 E.p:= mknode('*', E1.p, E2.p) E→ -E1 E→ (E1) E→ id E→ num E.p:= mknode('-', 0, E1.p) E.p:= E1.p E.p:= mkleaf(id, id.entry) E.p:=mkleaf(num,num.val)
翻译模式的设计
D → T { L.in := T.type } L T → int { T.type := integer } T → real { T.type := real } L → { L1.in := L.in } L1 , id { addtype(id.entry, L.in) } L → id { addtype(id.entry, L.in) }
从其兄弟结点和父结点的属性值计算出来的 如:L.in
固有属性(单词属性)
属性的计算
构造语法分析树,填加响应的语义规则 综合属性
自底向上按照语义规则来计算各结点的综
合属性值
继承属性
需要探讨计算次序
例6-3:3*5+4 的
语法树与属性计算
E.val=15 T.val=15 T.val=3 F.val=3 digit.attr=3 *

符号表组织符号表组织语义分析之一

符号表组织符号表组织语义分析之一
• CLEN(成分类型的长度)– 成分类型的数据所占值单 元的个数;
※ 这里假定:值单元个数依字长为单位计算。
路漫漫其修远兮, 吾将上下而求索
6.3.4 结构表(RINFL)
※ 结构:
每个域占表中一个纪录
ID
OFF TP
• ID(结构的域名)—
• OFF(区距)—是idk的值单元首址相对于所在记录值 区区头位置;

名字 类型 种类 地址
PFINFL(函数表)
TYPEL(类型表) TVAL TPOINT· AINFL(数组表 )
RINFL(结构表)

CONSL(常量表)
LENL(长度表 ) VALL(活动纪录 )
路漫漫其修远兮, 吾将上下而求索
6.3.1 符号表总表(SYNBL)
※ 结构: NAME TYP CAT ADDR
约定:off1=0, off2= off1+LEN(tp1), …… offn= offn-1+LEN(tpn-1)。 idn-1的长度
• TP(域成分类型指针) – 指针,指向idk域成分类型 路漫漫其修远兮, (在类型表中的信息);
吾将上下而求索
6.3.5 函数表(PFINFL)
---- 过程或函数语义信息 ※ 结构:
※ 结构:

路漫漫其修远兮, 吾将上下而求索
6.4 符号表的构造过程示例:
SYNBL
PFINFL
exp rtp f
?
2 ENT
线性表、顺序表、索引表和散列表,皆可以采用。
路漫漫其修远兮, 吾将上下而求索
6.2.3 符号表的维护、管理方式
※一个源文件有若干个函数组成,通常,每个函数对 应一个符号表,此外,还是有一个公用符号表;

第6章 语义分析(2)

第6章 语义分析(2)
类型声明
– 一般形式 id = type; 一般形式: – 内部表示 内部表示:
建立 type的内部表示; 建立 id的内部表示;
TypePtr
Kind typeKind
6.4 声明的语义分析
变量声明
– 一般形式: type id; 一般形式 – 内部表示 : 建立 type的内部表示;
获取<CurrentLevel, CurrentOffset> 获取 确定存取方式: 确定存取方式 dir/indir 建立 id的内部表示; CurrentOffset += sizeof(type)
语句
… FunNode1
6.4 声明的语义分析
常量声明
– 一般形式 id = number; 一般形式: – 内部表示 内部表示:
建立 number值的内部表示; 建立 number类型的内部表示; 建立 id的内部表示;
TypePtr
Kind constKind
Value
6.4 声明的语义分析
第六章 语义分析
6.1 语义分析概述 6.2 符号表 6.3 类型的语义分析 6.4 声明的语义分析 6.5 程序体的语义分析 6.6 属性文法和动作文法
内容回顾
什么是语义分析? 什么是语义分析
– 建立符号表 建立符号表; – 检查语义错误 检查语义错误;
在何处进行分析? 在何处进行分析
– 声明部分 --- 建立符号表;检查“重复声明”错误 建立符号表;检查“重复声明”错误; – 体部分 --- 查找符号表,检查“有使用无声明”错误和 查找符号表,检查“有使用无声明”
Size
Kind structTy
Body
6.3 类型的语义分析

编译原理_第6章__语义分析和中间代码生成

编译原理_第6章__语义分析和中间代码生成

非终结符T有一个综合属性type,其值为 int或float。语义规则L.in=T.type表示L.in的属性 值由相应说明语句指定的类型T.type决定;属 性L.in被确定后将随语法树的逐步生成而传递 到下边的有关结点使用,这种结点属性称为继 承属性。由此可见,标识符的类型可以通过继 承属性的复写规则来传递。 例如,对输入串int a,b,根据上述的语义 规则,可在其生成的语法树中看到用“→”表 示的属性传递情况,如图6–3所示。
直接生成目标代码 直接生成机器语言或汇编语言形式的目标 代码的优点是编译时间短且无需中间代码到目 标代码的翻译。 生成中间代码 生成中间代码的优点是使编译结构在逻辑 上更为简单明确,特别是使目标代码的优化比 较容易实现。
语义分析时语义检查的分类:
动态语义检查
需要生成相应的目标代码,它是在运行时进行的;
例如,简单算术表达式求值的属性文法如下: 规则 语义规则 (1) S→E print (E.val) (2) E→E(1)+T E.val=E(1).val+T.val (3) E→T E.val=T.val (4) T→T(1)*F T.val=T(1).val*F.val (5) T→T(1) T.val=T(1).val (6) F→(E) F.val=E.val (7) F→i F.val=i.lexval
6.1 概

6.1.1 语义分析的概念 一个源程序经过词法分析、语法分析之后,表 明该源程序在书写上是正确的,并且符合程序语言 所规定的语法。但是语法分析并未对程序内部的逻 辑含义加以分析,因此编译程序接下来的工作是语 义分析,即审查每个语法成分的静态语义。如果静 态语义正确,则生成与该语言成分等效的中间代码, 或者直接生成目标代码。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 退出一个局部化区时,作废本层符号表
相关文档
最新文档