编译原理实验教案.docx
《编译原理实验教案.docx》由会员分享,可在线阅读,更多相关《编译原理实验教案.docx(28页珍藏版)》请在冰豆网上搜索。
编译原理实验教案
黄冈师范学院计算机系
《编译原理》实验教案
(2009·秋)
授课对象:
计科200701~03
授课教师:
张瑞红
授课时间:
2009~2010学年度第一学期
实验一、词法分析
一、授课内容:
(一)授课科目:
编译原理
(二)授课内容:
实验一词法分析
(三)授课类型:
实验
(四)授课时间:
8学时
(五)主讲教师:
张瑞红
二、教学目的要求:
1.目的:
通过设计、编制、调试一个具体的词法分析程序加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
2.要求:
(1)选择在国际国内有代表性的高级程序设计语言的源程序作为词法分析对象。
(2)根据数学要求和学生具体情况,从上列语言之一中选取一个适当大小的子集,可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。
(3)时间为6小时。
时间分为三次:
第一讲、介绍词法分析器的设计原理,以PASCAL子集为例;
第二讲、根据学生时间上机情况,辅导学生设计;
第三讲、先辅导,再进行上机操作检查。
三、教学设想:
1.教学方法设想:
先以例子讲解,然后学生动手实验,实验为主。
2.教具运用设想:
多媒体。
四、教学过程:
1.题目试用直接分析方法编制PASCAL语言子集的词法分析程序。
其BNF定义如下:
〈PASCAL子集程序〉:
:
=〈变量说明〉BEGIN〈语句表〉ENG。
〈变量说明〉:
:
=〈空〉|VAR〈变量表〉:
〈类型〉
〈变量表〉:
:
=〈变量〉|〈变量表〉,〈变量〉
〈类型〉:
:
=〈标识符〉
〈语句表〉:
:
=〈语句〉|〈语句表〉〈语句〉
〈语句〉:
:
=〈赋值语句〉|〈条件语句〉|〈WHILE语句〉|〈复合语句〉|〈过程定义〉
〈赋值语句〉:
:
=〈变量〉:
:
=〈算术表达式〉
〈条件语句〉:
:
=〈IF〉〈布尔表达式〉THEN〈语句〉ELSE〈语句〉
〈WHILE语句〉:
:
=WHILE〈布尔表达式〉DO〈语句〉
〈复合语句〉:
:
=BEGIN〈语句表〉END
〈过程定义〉:
:
=PROCEDURE〈标识符〉〈参数表〉BEGIN〈语句表〉END
〈参数表〉:
:
=〈空〉|(〈标识符表〉)
〈标识符表〉:
:
=〈标识符〉|〈标识符表〉,〈标识符〉
〈算术表达式〉:
:
=〈项〉|〈算术表达式〉+〈项〉
〈项〉:
:
=〈初等量〉|〈项〉*〈初等量〉
〈初等量〉:
:
=〈无符号数〉|〈变量〉|(〈算术表达式〉)
〈布尔表达式〉:
:
=〈算术表达式〉〈关系符〉〈算术表达式〉
〈变量〉:
:
=〈标识符〉
〈标识符〉:
:
=〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉
〈无符号数〉:
:
=〈数字〉|〈无符号数〉〈数字〉
〈关系符〉:
:
=〈=|〈〉|〉
〈字母〉:
:
=A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
〈数字〉:
:
=0|1|2|3|4|5|6|7|8|9
〈空〉:
:
=
词法分析是编译程序的第一个处理阶段。
这里所谓直接分析方法,即自左至右扫描源程序,一旦发现有独立意义的字符串时,立即将其改造成长度统一的最小语法单位,同时查填各类单词表格并做一些语法检查,为以后的语法分析提供方便。
具体的处理过程是,在扫描字符串时,一旦识别出关键字(K)、标识符(I)、常数(C)和界符(P)中之一,即以单词形式(剔去多余的空白符)输出。
每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,习惯年成相应的单词串。
各类单词均有相同的结构和长度。
每个单词由两部分组成:
(t,i)
其中t表示单词种类。
共分四类,即K类、I类、C类和P类。
每类对应一种表格,分别存放该类各个不同的单词。
i为指向该类表格一个特定项目的指针。
因此,(t,i)唯一地确定了一个单词。
K,P两种表格的内容取决于所选语言的子集,而I,C两种表格则是根据临时输入的源程序字符串形成的。
2.算法词法分析程序在扫描过程中,依次从源程序驱除源字符,并根据第一个字符(有时还需多读一个字符)判断属于K,I,C,P中的哪一类单词,确定单词的t和i。
在词法分析过程中,K、P两表是固定不变的(由语言来确定),源程序字符串只能从其中选取。
I、C两表是在分析过程中不断形成的。
其词法分析的算法如图2-7-2所示。
为了防止实习良过大,达不到实习的目的,实习时采用的数据结构在不同程度上均应作适当的简化,所选的关键字(K)和界符表(P)如表2-7-1和表2-7-2所示。
表2-7-1K表表2-7-2P表
BEGIN
DO
ELSE
END
IF
PROCEDURE
THEN
VAR
WHILE
To
关键字表包括九个代表性的关键字。
界符表包括关系运算符三种(其中小于等于和不等于均系由两个字符组成的符合字符),算术运算符和分隔符各两种,圆括号一对,加上赋值号共十一种。
这两个表的内容表明,PASCAL语言的赋值语句、条件语句、WHILE型循环语句、复合语句过程及变量说明均可作为源程序例子输入给词法分析程序。
标识符表中的每一项包含一个标识符。
常数表中的每一项包含一个整常数。
后两表都是在词法分析过程中产生的。
3.程序及运行结果下面用PASCAL语言编出符合以上几项要求的一个具体的词法分析程序为:
PROGRAMplexical(INput,output);
Label1;
Const
keylen=10;
identlen=10;
Type
tstring=ARRAY[1..identlen]OFCHAR;
outreco=RECORD
ty:
CHAR;
point:
INTEGER;
END;{outreco}
var
cip,ip,pint,i,j,l,m:
INTEGER;
CHAR1:
CHAR;
ci:
ARRAY[1..10]OFINTEGER;
k,id:
ARRAY[1..keylen]OFtstring;
token:
tstring;
outtoken:
outreco;
instring:
ARRAY[1..10]OFCHAR;
p:
ARRAY[1..11]OFARRAY[1..2]OFCHAR;
PROCEDURElexical;
var
l,m,num:
INTEGER;
b:
BOOLEAN;
PROCEDUREgetCHAR;
BEGIN
CHAR1:
=instring[pint];
pint:
=pint+1;
END;{getCHAR}
PROCEDUREerror;
BEGIN
writeln('error');
pint:
=pint+1
END;{error}
BEGIN
FORl:
=1TOidentlenDO
token[l]:
='';
getCHAR;
whileCHAR1=''DO
getCHAR;
IFCHAR1IN['a'..'z']
THEN
BEGIN
m:
=1;
while(CHAR1IN['a'..'z'])OR(CHAR1IN['0'..'9'])DO
BEGIN
IFm<=identlenTHEN
BEGIN
token[m]:
=CHAR1;
m:
=m+1;
END;
getCHAR;
END;{while}
pint:
=pint-1;
l:
=1;
b:
=FALSE;
while(l<=keylen)AND(notb)DO
BEGIN
b:
=TRUE;
i:
=1;
while(i<=identlen)ANDbDO
IFk[l][i]=token[i]
THENi:
=i+1
ELSEb:
=FALSE;
IFnotbTHENl:
=l+1
END;
IFl<=keylen
THEN
BEGIN
outtoken.ty:
='k';
outtoken.point:
=l;
END
ELSE
BEGIN
l:
=1;
b:
=FALSE;
while(l<=ip)AND(notb)DO
BEGIN
b:
=TRUE;
i:
=1;
while(i<=identlen)ANDbDO
IFid[l][i]=token[i]
THENi:
=i+1
ELSEb:
=FALSE;
IFnotbTHENl:
=l+1;
END;
IFl>ip
THEN
BEGIN
ip:
=ip+1;
FORm:
=1TOidentlenDO
id[ip][m]:
=TOken[m];
END;
outtoken.ty:
='i';
outtoken.point:
=l;
END
END
ELSE
IFCHAR1IN['0'..'9']
THEN
BEGIN
num:
=0;
whileCHAR1IN['0'..'9']DO
BEGIN
num:
=num*10+ORd(CHAR1)-ORd('0');
getCHAR
END;
pint:
=pint-1;
l:
=0;
REPEAT
l:
=l+1
until(l=cip)OR(num=ci[l]);
IFl=cip
THEN
BEGIN
ci[cip]:
=num;
cip:
=cip+1;
END;
outtoken.ty:
='c';
outtoken.point:
=l
END{INTEGER}
ELSE
IFCHAR1IN['<','(','*',':
','+',')',';',',']THEN
BEGIN
outtoken.ty:
='p';
CASECHAR1OF
'<':
BEGIN
getCHAR;
IF(CHAR1<>'=')AND(CHAR1<>'>')
THEN
BEGIN
outtoken.point:
=3;
pint:
=pint-1
END
ELSE
CASECHAR1OF
'=':
outtoken.point:
=1;
'>':
outtoken.point:
=2
END;
END;
'(':
outtoken.point:
=4;
'*':
outtoken.point:
=5;
':
':
BEGIN
getCHAR;
IFCHAR1='='
THENouttoken.point:
=6
ELSEBEGIN
outtoken.point:
=7;
pint:
=pint-1
END
END;
'+':
outtoken.point:
=8;
')':
outtoken.point:
=9;
';':
outtoken.point:
=10;
',':
outtoken.point:
=11
END{CASE}
END
ELSEerror
END;{lexical}
BEGIN
writeln('K-TABLE,INPUT!
');
FORl:
=1TOkeylenDO
FORm:
=1TOidentlenDO
READ(k[l][m]);
READLN;
FORl:
=1TOidentlenDO
FORm:
=1TOidentlenDO
id[l][m]:
='';
writeln('P-TABLE,INPUT!
');
FORl:
=1TO11DO
FORm:
=1TO2DO
READ(p[l][m]);
READLN;
ip:
=0;
cip:
=1;
1:
pint:
=1;
writeln('source,input!
');
FORj:
=1TOidentlenDO
READ(instring[j]);
lexical;
writeln(outtoken.ty);
writeln(outtoken.point);
FORl:
=1TOidentlenDO
write(token[l]);
writeln;
goTO1;
END.
词法分析的过程名为lexical,它根据输入字符串第一个字符来划分单词类型。
若第一个字符为字母,则属关键字类或标识符类(凡K表中查不到的为后者);若第一个字符为数字,则为整数类;否则,为界符类或本例无定义字符。
Lexical过程中嵌入两个小过程,一个名为gethar,其功能是从输入字符串instring[pint]中取出一个字符,同时指针pint加1,为下一个取字符作好准备。
另一个过程名为error,负责出错处理。
这里知识简单输出字符串error,通知外界作进一步的处理。
实习时,可略加扩充,如指出出错的位置、原因和性质等。
注意,主程序是以调试程序的形式给出的,它主要完成:
(1)准备工作。
给K表和P表置初值;
(2)读入PASCAL源程序字符串,如合法的关键字、标识符、整常数和界符等;
(3)调用词法分析程序,对输入字符串进行词法分析;
(4)输出词法分析的结果,即单词的t和i,以及单词本身。
其它表格的输出略去了。
运行结果示例如下(输入时注意每个单词10个字符,在输入P表时每个字要占两个位置):
K-TABLE,INPUT!
begindoelseendifprocedurethenvar
while
P-TABLE,INPUT!
<=<><(*:
=:
+);,
source,input!
begin
k
1
begin
source,input!
+
p
8
+
source,input!
c
i
1
c
source,input!
a
i
2
a
五、实验小结
(1)实习前的准备。
根据实习目的和要求,用PASCAL语言编写一个规模适当的词法分析程序,并选择相应的数据结构。
(2)调试。
调试例子应有词法正确的,也有错误的或超出实习要求的字符串。
(3)输出。
主要将调试例子与词法分析结果以对照形式输出。
必要时,凡是对以后编译有影响的数据都予以输出,如单词串、K表、I表、C表、P表以及正误信息。
(4)扩充(任选)。
有余力的学生可适当扩大题目。
譬如:
扩充界符和关键字数目;
允许有实型常数;
加细词法错误检查;
增加单词类(如字符类),或把界符类分成两类,即算符类和其它界符类;
处理对象是整个PASCAL语言的字符集合。
(5)编写上机实习报告。
实验二、语法分析
一、授课内容:
(一)授课科目:
编译原理
(二)授课内容:
实验二语法分析
(三)授课类型:
实验
(四)授课时间:
12学时
(五)主讲教师:
张瑞红
二、教学目的要求:
1.目的:
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
2.要求:
(1)选择最有代表性的语法分析方法,算符优先法、递归子程序法和状态矩阵法之一进行实验。
(2)选择对各种常见的程序语言都通用的语法结构,如赋值语句(尤其指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
(3)实验时间为4小时。
时间分为二次:
第一讲、介绍语法分析器的设计原理(递归子程序法)为主,以PASCAL子集为例,并布置设计题;
第二讲、根据学生时间上机情况,辅导学生设计,并进行上机操作检查。
三、教学设想:
1.教学方法设想:
先以例子讲解,然后学生动手实验,实验为主。
2.教具运用设想:
多媒体。
四、教学过程:
1.题目试采用具有递归功能的高级语言(如PASCAL等等)编制递归下降法的语法分析程序,并用它对FORTRAN语言算术表达式的一个简化子集进行语法分析。
分析过程不嵌入任何语义动作。
分析对象的BNF定义如下:
〈算术表达式〉:
:
=〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉
〈项〉:
:
=〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉
〈因式〉:
:
=〈变量〉|(〈算术表达式〉)
〈变量〉:
:
=〈字母〉
〈字母〉:
:
=A|B|C|D|E|f|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
2.算法用递归下降法分析上述算术表达式的框图,如图2-7-5所示。
这里,ZC过程为总控制程序,主要完成:
(1)通知外界键入算术表达式;
(2)控制E过程分析算术表达式;
(3)根据分析结果之正误,分别通知外界不同的信息。
ZC过程被设计成可以分析无穷多个算术表达式。
(在修该后,只要输入的开是字符为:
‘#’就可以返回,终止分析程序。
)E、T、F三个过程分别对应〈算术表达式〉、〈项〉、〈因式〉三个产生式的处理。
它们用到两个公共过程。
一个是函数过程SYS,它负责从输入字符串ST中取出下一个字符,并存入SYM中等待分析。
另一个过程ADVANCE负责剔除ST中的首字符。
3.程序及运行结果采用PASCAL语言描述递归下降法分析算术表达式的一个程序和表达式分析示例为:
PROGRAMparser(intput,output);
label1;
label2;
varp,tz,i:
INTEGER;
st:
array[1..20]ofCHAR;
functionsym:
CHAR;
BEGIN
sym:
=st[p]
END;
PROCEDUREerror(n:
INTEGER);
BEGIN
writeln('error',n);
END;
PROCEDUREe;
PROCEDUREt;
PROCEDUREf;
BEGIN
IFsymin['a'..'z']
THENp:
=p+1
ELSE
IFsym='('
THEN
BEGIN
p:
=p+1;
e;
IFsym=')'
THENp:
=p+1
ELSE
BEGIN
error(p);
tz:
=1;
END
END
ELSE
BEGIN
error(p);
tz:
=1
END
END;
BEGIN
f;
while(sym='*')or(sym='/')do
BEGIN
p:
=p+1;
f;
END;
END;
BEGIN
t;
while(sym='+')or(sym='-')do
BEGIN
p:
=p+1;
t;
END;
END;
BEGIN
1:
writeln('inputexpression,please!
');
FORi:
=1to20do
read(st[i]);
readln;
p:
=1;
IFsym='#'
THEN
BEGIN
writeln('finished!
');
goto2;
END;
e;
IF(sym<>'#')or(tz=1)
THEN
BEGIN
writeln('error,again');
tz:
=0;
END
ELSEwriteln('right,again!
');
goto1;
2:
END.
RUN:
inputexpression,please!
a+b*c#
right,again!
inputexpression,please!
(((c+h)*i)/j)#
right,again!
inputexpression,please!
a(+g#
error,again
inputexpression,please!
(a+i))#
error,again
inputexpression,please!
#
finished!
在该程序中,过程ADVANCE未单独列出,是依靠挪动字符串指针(P加1)的办法来实现的。
变量TZ之值标志分析的结果(表达式)是否有错。
五、实验小结
(1)实习前的准备按实习目的和要求,用PASCAL语言编写一个递归下降法的语法分析程序,同时考虑相应的数据结构。
(2)调试调试例子应包括符合语法规则的算术表达式,以及分析程序能够判别的若干错例。
(3)输出对于所输入的算术表达式,不论对错,都应有明确的信息告诉外界。
(4)扩充有余力的同学,可适当扩大分析对象。
譬如:
算术表达式中变量名可以是一般标识符,还可含一般常数、数组元素、函数调用等等。
除算术表达式外,还可扩充分析布尔、字符、位等不同类型的各种表达式。
加强语法检查,尽量多和确切地指出各种错误。
(5)编写上机实习报告。
提高型实验——语法器的设计
一、授课内容:
(一)授课科目:
编译原理
(二)授课内容:
实验三提高型实验——语法器的设计
(三)授课类型:
实验
(四)授课时间:
10学时
(五)主讲教师:
张瑞红
二、教学目的要求:
为了提高学生的程序设计能力,同时掌握编译原理中重要的组成部分——语法分析的思想,为此,经过大量的资料的查找,再结合学生的实际情况,制定了六个共选课题作为学生的提高型实验。
每个实验课题都有不同的思想,类型属于设计型。
具体的实验课题如下:
(一)、LL
(1)分析表的构造
(二)、LL
(1)分析程序的设计
(三)、OPG分析表的构造
(四)、OPG分析程序的设计
(五)、LR(0)分析表的构造
(六)、LR(0)分析程序的设计
(七)、SLR
(1)分析表的构造
(八)、SLR
(1)分析程序的设计
三、实验目的与要求以及算法
(一)、LL
(1)分析表和分析程序的设计
·LL
(1)分析表的构造
·实验目的和要求:
通过设计,编写和调试构造LL
(1)分析表(也称预测分析表)的程序,了解构造LL
(1)分析表的步骤,对文法的要求,能够从文法G出发自动生成LL
(1)分析表。
·实验原理分析(包括算法):
设计一个自动构造LL
(1)分析表的程序,该程序的输入是任一个文法G,出是对应的LL
(1)分析表,并指出该文法是否为LL
(1)文法。
例如:
设文法G为:
E->TE’
E’->+TE’|#(用#代替空字符)
T->FT’
T’->*FT’|#(用#代替空字符)
F->(E)|i
注:
i为整型常数或为标识符表示的整型变量。
构造LL
(1)分析表的算法:
构造LL
(1)分析表需以下几个步骤
1.对于文法G的每个符号X,构造FIRST(X)集合。
2.构造FIRST(X)集合又分为几种情况:
a.若X->a….(a为终结符),则FIRST(X)={a}。
b.若X->#(为空),则FIRST(X)=