《编译原理》实验说明书Word文档格式.docx
《《编译原理》实验说明书Word文档格式.docx》由会员分享,可在线阅读,更多相关《《编译原理》实验说明书Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
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,”;
”)
(221,”=”)
(500,”1010”)
(201,”+”)
(500,”10100”)
(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();
end
Retract();
code:
=Reserve();
if(code=0)
begin
value:
=InsertId(strToken);
return($ID,value);
else
return(code,-);
end
elseif(IsDigit())
begin
while(IsDigit())
=InsertConst(strToken);
returnr($INT,value);
elseif(ch=‘=‘)retutn($ASSIGN,-);
elseif(ch=‘+’)return($PLUS,-);
elseif(ch=’*’)
GetChar();
If(ch=‘*’)return($POWER,-);
Retract();
return($STAR,-);
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;
elseif(M[x,a]==“x→y1y2…yk”)
把ykyk-1…y1依次入栈;
//即y1y2…yk逆序依次入栈
//若y1y2…yk=ε,则不进行入栈操作
实验二②语法分析器设计之二
――算符优先分析器
熟悉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]<
a)||(S[j]=a)){k=k+1;
S[k]=a;
}
//若栈顶S[j]<
a或=a则将a压栈
}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
使S是栈顶状态,a是ip指向的符号;
ifaction[s,a]=sjthen
Begin
将a和j压入分析栈,
修改ip,使其指向下一个输入符号;
end;
elseifaction[s,a]=rj(A→β)
从分析栈顶弹出2×
|β|个符号,
令S’是当前栈顶状态;
将A和goto[s’,A]压入分析栈;
{输出产生式A→β}
elseifaction[s,a]=acc
return
error();
endif;
endif;
endofwhile;
end;