一、词法分析考题
词法分析大题:
主要考正则表达式向NFA的转换,DFA的确定化以及最简化。
正则表达式转化成NFA:a|b,ab,a*三种。
DFA的确定化:首先选取NFA的初始状态集的闭包,然后运算可以得到。
DFA的最简化:去除无关状态,然后终止状态分为一堆,非终止状态分为一堆进行化简。
注意事项:标明开始状态与终止状态。
例题:
二、(15分)假设某语言中有如下规则构成的一类单词:
(1)由字母表{a,b,c}上的符号构成;
(2)以a或b开头,以c结尾;
请写出该类单词的正则表达式,并将其转化为最小的确定有限自动机。
词法分析小题:
1.DFA与NFA的区别
(1)NFA有多个初始状态集
(2)NFA可以有空串
(3)NFA的状态转移函数可以多值。
2.高级程序设计语言实现的方式:编译与解释。
3.编译程序的组成:词法分析,语法分析,语义分析,中间代码生成,中间代码优化,目标代码生成,表格管理,错误处理。
4.根据要求生成状态机/正则表达式
二、语法分析考题(重点)
1.构造文法
例题:构造一个2型文法G,使得L(G)={a2m+1bm | m≥0}。
S->aaSb|a
2.二义性文法探究
3.求语法树以及短语,简单短语,句柄
3. 已知文法G[S]:
E→E+T | T
T→T*F | F
F→ (E) | i
给出句型E+T*F+i的所有短语、所有简单短语及句柄。
4.LL(1)语法分析\递归下降程序(大题)
消除左递归,消除公共前缀。
first集,follow集,predict集的计算。
注意:follow集计算
生成LL(1)语法分析表
实例匹配
编写递归下降子程序
三、(15分)已知文法G[S]如下:
SàMH|a
HàLSc|e
KàdML|e
LàeHf
MàK|bLM
(1) 计算G[S]中每个非终极符的First集和Follow集;
(2) 证明G[S]是LL(1)文法,并构造LL(1)分析表;
(3) 分析输入串befda是否是该文法的句子,按照表1形式给出分析过程。
表1
符号栈
输入串
驱动程序动作
#S
befda#
...
注意:在H->aLSc产生式中:follow(L)=follow(L)∪first(Sc)而不是follow(L)=follow(L)∪first(S)-{空串}∪follow(H)
5.LR(0)生成可归活前缀状态机(注意若开始符出现在右侧,则需要增加拓广产生式)
6.语法分析问答题:
(1)分析自顶向下分析方法分析能力与状态数
分析能力:LR(0)<SLR(1)<LALR(1)<LR(1);
状态数:LR(0)=SLR(1)=LALR(1)<LR(1)
(2)文法分类:分为0型文法,1型文法,2型文法,3型文法。
7.语法制导
5.设有如下LL(1)文法G[S]:
S→A B
A→a A│b
B →b B│c
设计语法制导程序完成如下任务:对输入文法 G 的任意句子 L ,输出 L 中b 串的长度。如串 abbbbc 是 G 的句子,则该处理程序将输出4。
三、语义分析考题
1.各种标识符内部表示
常量:name kind type value
name:名字
kind:constkind
type:内部表示类型
value:内部值
类型:name kind type
kind:typekind
变量:name kind type access level off value
access:直接访问还是间接访问
kind:varkind
value:初值,没有则为null
过程/函数:name kind type level off param class code size forward
kind:routkind
type:返回值类型
level:层数
off:只对形式过函有效
param:形参表;与符号表格式相同
class:actual实在过函,formal:形式过函
code:目标代码首地址
size:过程活动记录大小
forward:是否超前声明
数组类型表示:size kind low up eletype
size:数组大小
kind:arrayTY
low
up
eletype指向内部表示
枚举类型表示:size kind elemlist
kind:enumTY
elemlist:指向内部表示
枚举常量表:name value
结构体与联合体:size kind recbody
结构体:kind:structTY
recbody:name type off link
name:名字
type:类型
off:偏移量
link:
联合体:kind:unionTY
recbody:name type off link
off一定是0
指针内部表示: size kind basetype
kind=pointTY
4. 有如下声明,请填写相应标识符的符号表信息。
注:数据区起始偏移从off0开始,整型变量、字符变量占1个存储单元,浮点类型变量占2个存储单元。
typedef struct {
int number;
char name[20];
float achievement;
} student;
int a[10][10];
student b[10];
2.符号表局部化处理
(1)全局化符号表
五、(10分)下面是计算fibnacci数列的相关c程序,请给出语义分析完成后的符号表。
要求:1.采用全局符号表驻留方法;
2.变量标识符具体属性信息只需写出名字、种类、类型、层数和偏移,函数标识符具体属性信息只需写出名字、种类、类型、层数;局部数据区起始偏移从off开始,整型变量、字符型变量占1个存储单元,实型变量占2个存储单元。
int fib(int m)
{ int f0,f1,f2;
f0=0; f1=1;
if(m<=1) return m;
else
{ int i;
for(i=2;i<=m;i++)
{ f2=f0+f1; f0=f1; f1=f2; }
return f2; }
}
int sum(int (*p)(int), int m)
{
int result = 0;
for(int i = 1; i <= m; ++i)
{
result +=(* p)(i);
}
return result;
}
int main()
{
int k =5, result;
result = sum(fib, k);
}
(2)局部化符号表(只有删除不大会考)
四、中间代码生成与优化
表达式的生成(注意类型转换(FLOAT,-,t1,-,t2);
下标变量的生成;
赋值语句的生成(注意类型转换(FLOAT,-,t1,-,t2);
过程调用的生成;
goto语句的生成(JMP,-,-LL1);
标号语句的生成(label,-,-,LL1)(生成标号表);
IF语句生成;
WHILE语句生成;
过程声明语句的生成。
中间代码生成注意事项:
1.例:A[3+1]=A[4+1]+1;
先计算左边的A[3+1],再计算后边,并且=作为基本块划分界限,+有间接变量,故不外提。
2.注意类型转换(FLOAT,-,t1,-,t2)
基本块的划分:转移性语句作为出口,标号性语句作为入口,地址引用性变量赋值语句作为出口。
常量表达式的节省:以基本块为单位,生成常量定值表,赋值语句不可节省,运算型语句可节省。
公共子表达式的节省:以基本块为单位,生成值编码表,生成等价变量表,编码表达式。
循环外提:以一个循环为单位,生成变量定值表。
注意的五点:
(1)外层循环变量定值表包含内层循环变量定值表
(2)除法不外提,除数可能为0
(3)赋值不外提,可能不进入循环
(4)非良性循环不优化,例如(f()函数和地址引用性变量赋值)
(5)若运算有一分量为间接变量,该四元式不外提。但AADD不受限制。
四、(15分)设有如下程序段,其中A:Array [1..10][1..100][1..1000] of integer,程序中的所有变量都为整型变量,占1个存储单元。
1)给出该程序段代码的四元式中间代码。
2)请利用常表达节省、公共子表达式节省和循环不变式外提三种优化技术对四元式中间代码进行优化,给出优化后的四元式代码。
while(i++ <10) {
k=10;
while(j++ < 100) {
m=k*10;
while(k++ <1000)
A[i][j][k]=A[i][j][k]*n*5+n*5/m;
}
}
五、运行时存储管理
主要两种题
1.计算层数和地址
2.写局部display表,全局display表或者静态链
六、目标代码生成
1.需要使用回填技术的语句是未标号声明的goto语句,循环语句,条件语句。