《编译原理》实验说明书.docx

上传人:b****4 文档编号:4617754 上传时间:2022-12-07 格式:DOCX 页数:12 大小:24.67KB
下载 相关 举报
《编译原理》实验说明书.docx_第1页
第1页 / 共12页
《编译原理》实验说明书.docx_第2页
第2页 / 共12页
《编译原理》实验说明书.docx_第3页
第3页 / 共12页
《编译原理》实验说明书.docx_第4页
第4页 / 共12页
《编译原理》实验说明书.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

《编译原理》实验说明书.docx

《《编译原理》实验说明书.docx》由会员分享,可在线阅读,更多相关《《编译原理》实验说明书.docx(12页珍藏版)》请在冰豆网上搜索。

《编译原理》实验说明书.docx

《编译原理》实验说明书

 

《编译原理》

实验指导书

 

执笔人:

陈义仁

2008年3月

实验一词法分析器的设计

一、实验目的和要求

加深对状态转换图的实现及词法分析器的理解。

熟悉词法分析器的主要算法及实现过程。

要求学生掌握词法分析器的设计过程,并实现词法分析。

二、实验基本内容

给出一个简单语言的词法规则,画出状态转换图,并依据状态转换图编制出词法分析程序,能从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

(遇到错误时可显示“Error”,然后跳过错误部分继续显示)

词法规则如下:

单词符号

种别码

内码

单词符号

种别码

内码

break

101

>=

209

char

102

210

do

103

<=

211

double

104

==

212

else

105

213

float

106

&&

214

for

107

||

215

if

108

!

216

int

109

<<

217

return

110

>>

218

void

111

|

219

while

112

&

220

201

221

202

+=

222

*

203

-=

223

/

204

*=

224

%

205

/=

225

++

206

%=

226

--

207

>>=

227

208

<<=

228

单词符号

种别码

内码

单词符号

种别码

内码

&=

229

}

306

|=

230

#

307

[

301

308

]

302

309

303

标识符

400

304

常数

500

二进制形式

{

305

三、实验时间:

上机三次。

第一次按照自己的思路设计一个程序。

第二、三次在理论课学习后修改程序,使得程序结构更加合理。

四、实验过程和指导:

(一)准备:

1.阅读课本有关章节(c/c++,数据结构),花一周时间明确语言的语法,写出基本算法以及采用的数据结构和要测试的程序例。

2.初步编制好程序。

3.准备好多组测试数据。

(二)上课上机:

将源代码拷贝到机上调试,发现错误,再修改完善。

(400,”main”)

(303,”(“)

(304,”)“)

(305,”{“}

(109,”int”)

(400,”a”)

(309,”,”)

(400,”b”)

(308,”;”)

(400,”a”)

(221,”=”)

(500,”1010”)

(308,”;”)

(400,”b”)

(221,”=”)

(400,”a”)

(201,”+”)

(500,”10100”)

(308,”;”)

(306,”}“)

(三)程序要求:

程序输入/输出示例:

输入如下一段:

main()

{

/*

一个简单的c++程序

*/

inta,b;//定义变量

a=10;

b=a+20;

}

要求输出如右图。

要求:

(1)剔除注解符

(2)常数为无符号整数(可增加实型数,字符型数等)

(四)练习该实验的目的和思路:

程序开始变得复杂起来,可能是大家以前编过的程序中最复杂的,但相对于以后的程序来说还是简单的。

因此要认真把握这个过渡期的练习。

程序规模大概为200行及以上。

通过练习,掌握对字符进行灵活处理的方法。

(五)为了能设计好程序,注意以下事情:

1.模块设计:

将程序分成合理的多个模块(函数/类),每个模块(类)做具体的同一事情。

2.写出(画出)设计方案:

模块关系简图、流程图、全局变量、函数接口等。

3.编程时注意编程风格:

空行的使用、注释的使用、缩进的使用等。

4.程序设计语言不限,建议使用面向对象技术及可视化编程语言,如C++,VC,JAVA,VJ++等。

四、上交:

1.程序源代码及可执行文件(当堂检查/通过网络提交);

2.已经测试通过的测试数据3组(全部存在一个文本文件中,以“第一组输入/输出/第二组输入/输出/第三组输入/输出”的顺序存放);

3.实验报告按照提供的模板填写:

(1)功能描述:

该程序具有什么功能?

(2)算法描述:

所采用的数据结构,基本实现算法及某些特殊过程的实现算法(如在处理某个问题时,你所采取的好的处理方法等)注意此处不要简单的将源程序抄上来。

(源程序将打印出来作为附录)

(3)程序结构描述:

函数调用格式、参数含义、返回值描述、函数功能;另外可以附加函数之间的调用关系图、程序总体执行流程图及类的层次图。

(4)实验总结:

你在编程过程中花时多少?

多少时间在纸上设计?

多少时间上机输入和调试?

多少时间在思考问题?

遇到了哪些难题?

你是怎么克服的?

你对你的程序的评价?

你的收获有哪些?

(5)写出上机调试时发现的问题,以及解决的过程;

(6)附上源程序(打印的)

五、问题描述及基本算法提示

1.状态转换图的实现

让每个结点对应一小段程序。

需引进一组全局变量和过程

(1)ch字符变量,存放最新读进的源程序字符。

(2)strToken字符数组,存放构成单词符号的字符串。

(3)GetChar子程序过程,将下一输入字符读到ch中,搜索指示器前移一字符位置。

(4)GetBC子程序过程,检查ch中字符是否为空白。

若是,则调用GetChar直至ch中进入一个非空白字符。

(5)Concat子程序过程,将ch中的字符连接到strToken之后。

例如,假定strToken原来的值为“AB”,而ch中存放着’C’,经调用Concat后,strToken的值就变为”ABC”。

(6)IsLetter和IsDigit布尔函数过程,它们分别判断ch中的字符是否为字母和数字。

(7)Reserve整型函数过程,对strToken中的字符找保留字表,若它是一个保留字,则返回它的编码,否则返回0值。

(8)Retract子程序过程,将搜索指示器回调一个字符位置,将ch置为空白字符。

(9)InsertId整型函数过程,将strToken中的标识符插入符号表,返回符号表指针。

(10)InsertConst整型函数过程,将strToken中的常数插入常数表,返回常数表指针。

2.词法分析器构造基本算法

intcode,value;

strToken:

=“”;置strToken为空串*/

GetChar();GetBC();

if(IsLetter())

begin

while(IsLetter()orIsDigit())

begin

Concat();GetChar();

end

Retract();

code:

=Reserve();

if(code=0)

begin

value:

=InsertId(strToken);

return($ID,value);

end

else

return(code,-);

end

elseif(IsDigit())

begin

while(IsDigit())

begin

Concat();GetChar();

end

Retract();

value:

=InsertConst(strToken);

returnr($INT,value);

end

elseif(ch=‘=‘)retutn($ASSIGN,-);

elseif(ch=‘+’)return($PLUS,-);

elseif(ch=’*’)

begin

GetChar();

If(ch=‘*’)return($POWER,-);

Retract();return($STAR,-);

end

elseif(ch=‘;’)return($SEMICOLON,-);

elseif(ch=‘(‘)return($LPAR,-);

elseif(ch=‘)’)return($RPAR,-);

elseif(ch=‘{‘)return($LBRACE,-);

elseif(ch=‘)’)rerurn($RBRACE,);

elseProcError();/错误处理/

 

实验二①语法分析器设计之一

---预测分析器

一.实验目的和要求

理解预测分析器程序的构造过程,掌握预测分析程序的设计.

二.实验基本内容

编写预测分析程序,能实现:

1.给定文法,消除左递归及左公因子

2.构造并输出FIRST和FOLLOW(A)

3.构造并输出分析表,判断是否为LL

(1)文法

4.任意输入一个输入串,可得到成功的分析或错误的提示,输出其分析过程或打印语法分析树。

三.问题描述及算法提示

1.理解左递归消除算法及左公因子的提取。

2.求出FIRST(α)和FOLLOW(A)

(1)FIRST(X)构造算法:

①若X∈VT,则FIRST(X)={X}

②若X∈VN,且有产生式X→a…,则a加入FIRST(X),若X→ε,则ε加入FIRST(X)

③若X→Y…是一产生式且Y∈VN,则把FIRST(Y)中所有的非ε元素加到FIRST(X)中;若X→Y1Y2…YK是一个产生式,Y1,Y2,…,Yi-1∈VN,且对于,,FIRST(Yj)都含有ε(Y1…Yi-1=*>ε),则把FIRST(Yi)中所有非ε元素都加到FIRST(X)中;若所有FIRST(Yj)均含有ε,j=1,2,…,k,则把ε加到FIRST(X)中。

④重复②、③直到所有FIRST(X)不再扩大为止。

(2)FOLLOW(B)构造算法:

①对于文法的开始符号S,把#加入FOLLOW(S)。

(由语句括号“#S#”中的S#得到)

②若有A→αBβ(α可为空),则将FIRST(β)\{ε}加入FOLLOW(B)。

③若有A→αB或A→αBβ且β=*>ε,则把FOLLOW(A)加入到FOLLOW(B)。

④重复②、③直到FOLLOW集不再增大为止。

3.依据FIRST(A)和FOLLOW(A)构造分析表

①对文法G的每个产生式A→α执行②,③

②对任意a∈FIRST(α),把A→α加至M[A,a]中

③若ε∈FIRST(α),则对任意b∈FOLLOW(A),把A→α加至M[A,b]中

④把所有无定义的M[A,a]标上“出错标志”

4.依据分析表进行分析

将“#”和文法开始符号依次入栈;

把第一个输入符读入a;

while

(1)

{把栈顶符号弹出并放入x中;

if(x∈VT){

if(x==a)将下一输入符读入a;

elseerror();}

elseif(x==‘#’){

if(x==a)break;

elseerror();}

elseif(M[x,a]==“x→y1y2…yk”)

把ykyk-1…y1依次入栈;//即y1y2…yk逆序依次入栈

//若y1y2…yk=ε,则不进行入栈操作

elseerror();

}

 

实验二②语法分析器设计之二

――算符优先分析器

一.实验目的和要求

熟悉FIRSTVT、LASTVT、优先关系表构造算法的实现,掌握算符优先分析器的构造过程。

二.实验基本内容

编写一个自下而上的语法分析程序,能够实现

1.输入文法,判断是否为算符文法

2.输出该文法的每个非终结符的FIRSTVT集和LASTVT集

3.构造并输出分析表,判断是否为算符优先文法,若不是提示无法进行分析

4.生成算符优先文法语法分析程序

5.用户输入句子若合法,输出归约的过程或语法树

三.问题描述及算法提示

1.理解算符文法,算符优先文法的概念

2.求出FIRSTVT和LASTVT

3.依据FIRSTVT,LASTVT构造优先表

FOR每条产生式P→X1X2…Xn

FORI:

=1TOn-1DO

BEGIN

IFXi和Xi+1均为终结符THEN置

Xi=Xi+1

IFi≤n-2且Xi和Xi+2都为终结符

但Xi+1为非终结符THEN置Xi=Xi+2

IFXi为终结符而且Xi+1为非终结符THEN

FORFIRSTVT(Xi+1)中的每个aDO

置Xi<a

IFXi为非终结符而且Xi+1为终结符THEN

FORLASTVT(Xi)中的每个aDO

置a>Xi+1

END

 

4.依据分析表进行算符优先分析

k=1;S[k]=‘#’;//k代表栈S的使用深度

do{a=下一个输入符;

if(S[k]∈VT)j=k;elsej=k−1;/*j指栈顶终结符,任何两终结符之间最多只有一非终结符,故若S[k]∈VT则S[k−1]∈VT*/

while(S[j]>a){//找出最左子串S[j]⋖S[j+1]…S[k]⋗a

do{Q=S[j];//j从最左素短语末逐步移向首

if(S[j−1]∈VT)j=j−1;elsej=j−2;

}while(S[j]=Q);

把S[j+1]…S[k]归约为某个N;

k=j+1;S[k]=N;//将归约后的非终结符N置于原S[j+1]位

//置

}

if((S[j]

elseerror();//若栈顶S[j]

}while(a!

=‘#’);

实验三语法分析器设计之三

――LR分析器

一.实验目的和要求

使学生理解LR分析器的构造过程及产生分析表的具体算法

二.实验基本内容

选择一种LR文法(LR(0)、SLR

(1)、LALR

(1)、LR

(1)),设计出一个LR分析器,能够实现:

1.对输入的文法进行判断,是否为相应LR文法,若不是提示重新输入文法。

2.输出相应的项目集规范簇

3.输出相应的LR分析表。

4.输入一个句子,输出其分析过程(移进,归约,接受)

三.问题描述及算法提示

1.文法进行拓广

2.构造I的闭包CLOSURE(I)

I是文法G的任一项目集。

(1)I的任何项目都属于CLOSURE(I)

(2)若A→α•Bβ属于CLOSURE(I)。

则关于B∈VN的产生式

B→γ项目B→•γ∈CLOSURE(I)

(3)重复执行上述步骤直至CLOSURE(I)不再增大。

3.求出状态转换函数GO(I,X)

GO(I,X)=CLOSURE(J)

J={形如A→α•Xβ的项目|A→α•Xβ属于I}

4.求出项目集规范族C的算法

(1)CLOSURE({S’→•S})C

(2)对C中每一项目集I和文法G’的每个符号X做

若GO(I,X)非空且不属于C,则把GO(I,X)加入C

(3)重复1,2直至C不再增大为止.

5.分析表构造

假定C={I0,I1…In},每个项目Ik的下标K作为分析器状态,令包含项目S’→•S的集合Ik的下标K为初态.

分析表的ACTION子表和GOTO子表的构造

(1)若项目A→α•aβ属于Ik且GO(Ik,a)=Ij.a∈VT,则置ACTION[k,a]为”把(j,a)移进栈”,简记为Sj

(2)若项目A→α•∈Ik,那么对于任意a∈VT(或#)置ACTION[k,a]为“用产生式A→α进行归约”简记为rj(A→α是文法G’的第j个产生式)

(3)若项目S’→•S∈Ik,则置ACTION[k,#]为“接受“,记为“acc”

(4)若GO(Ik,A)=Ij,A为非终结符,置GO[k,a]=j

(5)分析表中凡不能用规则1—4填入信息的空白格置上“报错标志”

6.写出总控程序进行分析

输入:

一个输入串ω和一张LR分析表

输出:

若ω∈L(G),对于ω的一个自下而上的分析,否则出错。

开始时,(S0,#)在分析栈顶,ω#在输入缓冲区

ip指向输入串ω的第一个输入符号

while(t=True)DO

BEGIN

使S是栈顶状态,a是ip指向的符号;

ifaction[s,a]=sjthen

Begin

将a和j压入分析栈,

修改ip,使其指向下一个输入符号;

end;

elseifaction[s,a]=rj(A→β)

Begin

从分析栈顶弹出2×|β|个符号,

令S’是当前栈顶状态;

将A和goto[s’,A]压入分析栈;

{输出产生式A→β}

end

elseifaction[s,a]=acc

return

else

error();

endif;

endif;

endif;

endofwhile;

end;

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1