编译原理课程设计教案由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“编译原理课程设计”。
黄冈师范学院
《编译原理课程设计》教案
(2011·春)
授 课 教 师: 张 瑞 红
授 课 班 级: 计科2008级
授 课 时 间: 2010-2011 二
课题一 有限自动机的运行
一、设计题目:有限自动机的运行
二、设计目的:
1、理解有限自动机的作用
2、利用转态图和状态表表示有限自动机
3、以程序实现有限自动机的运行过程
三、设计内容:(注:题目详细要求)
利用状态表和有限自动机的运行原理编制程序,使得程序能够识别一个输入串是否为一个有效的符号串,具体可以选择下面之一:无符号定点实数、自然数、整数、十六进制数或其它自己定义的符号串。
四、设计思想:(注:算法思想、程序流程图、不要写代码)
本程序实现对无符号定点实数的判断,正确接受,否则不接受。
本程序的关键在状态表和缓冲区的运用。首先定义了一个布尔型函数ReadALine把输入的字符串送到缓冲区中;然后定义了布尔型函数Run 和Getchar实现对输入字符串的正确性判断,更改Run函数可以改变程序功能:如可将状态表改变成识别“偶数”的有限自动机的状态表。
程序流程图如下:(学生自己画)
五、运行结果与数据分析:
六、设计总结体会:(学生自己写,此处可参考)
通过这次课程设计,我对程序的编译和运行过程有了更进一步的了解,对程序的底层设计、代码优化也有了初步的认识,而且知道了如何从根本上来提高程序运行的速度。附录:(完整代码)#include #include //状态表相关存储信息:
#define STATE_NUMBER 4 //状态数目
#define CHAR_NUMBER 2 //输入字符的种类: d 和.#define DIGIT 0 //输入数字在状态表中位于第0列
//State[][]为状态表,以整数组形式存放,0,1,2,3表示状态,-1表示没有此状态 int State[STATE_NUMBER][CHAR_NUMBER]= {{1,-1},{1,2}, {3,-1}, {3,-1}};int Q[STATE_NUMBER] = {0,1,0,1};//终态标志:0非终态,1终态。//缓冲区:
//输入缓冲区:由专门函数操作(ReadALine(),GetChar())#define BUFFER_SIZE 1000 //表达式缓冲区大小
char Buffer[BUFFER_SIZE];//表达式缓冲区,以' '表示结束 int ipBuffer = 0;//表达式缓冲区当前位置序号 char ch;//存放取得的一个字符 //函数声明:
bool Run();//对存储在缓冲区的一行字符串(以'#'结束)进行运行 void Init();//全局初始化
bool ReadALine();//从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中 char GetChar();//从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中 //主程序: void main(){ Init();while(ReadALine())//读一行成功,对它进行判断
{ if(Run())//对该行进行运行,看是否能被接受? printf(“接受nn”);else printf(“不接受nn”);} } //对存储在缓冲区的一行字符串(以'#'结束)进行运行 //返回:如果是无符号定点实数,返回true;否则返回:false bool Run(){ int S=0;//S存放运行时的当前状态,目前为初态 while(GetChar()!='#'){ if(ch >= '0'&&ch
printf(“程序功能:输入一个字符串,判断它是否是a。n”);printf(“========nn”);} //从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中,以'#'结束,并置ipBuffer=0; //读到非空字符串:返回 true;读到单独的“#”:返回 false bool ReadALine(){ int l;printf(“请输入以”#“号结束的无空格字符串:”);scanf(“%s”,Buffer);l = strlen(Buffer);//读入的字符串的长度
if(l == 0)return ReadALine();//输入了空字符串,重新输入 if(Buffer[0] == '#')return false;//输入单独的'#'表示不再输入 Buffer[l] = '#';//最后一个字符用结束标记'#'代替(本来是' ')ipBuffer = 0;//初始化缓冲区指针 return true;} //从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中 //成功:返回字符;不成功:返回'#' char GetChar(){ if((ch = Buffer[ipBuffer])!= '#')ipBuffer ++;return ch;}
五、运行结果与数据分析:
六、设计总结体会:
课题二:简单词法分析器设计(C或C++)
一、设计题目:简单词法分析器设计(C或C++)
二、设计目的要求:
1、目的:通过设计、编程、调试出一个具体词法分析程序,加深对词法分析原理的理解,掌握其设计方法。
2、要求:
1)整理出所有单词符号及内部表示
分类:各关键字、标识符、运算符、分界符、常数 2)画出状态转换图
3)编程。要求用自动机的方法进行编程。
① 预处理,去除注释、多余空格、回车换行符等。② 词法分析程序能通过实例数据的测试。
备注:设计词法分析程序时,应考虑能为语法分析程序调用。
4)写出设计报告,内容为:状态转换图、单词符号及内部表示、符号表、出错处理、编程方法等。
三、实验内容:
选择一个词法分析方法,编写一个的词法分析器,对下面的实例进行测试。测试用例:
program testexample;{读入一组整数,统计并输出:其中非负整数之和,整组数的10倍平均值 } var k, sum1, sum2, x : int;const num=20, times=10;begin sum1:= 0;sum2:= 0;k :=num;while k>=1 do begin read(x);if x>=0 then sum1 := sum1 + x;sum2 := sum2 + x;k := k-1;end;write(sum1, times*sum2/ num);end.四、设计思想:(注:算法思想、程序流程图、不要写代码)
利用单词的构成规则,对输入的字符串进行分析再归类即可。(流程图学生自己画)
五、运行结果与数据分析:
六、设计总结体会: 课题三:语法分析器的设计
一、设计题目:语法分析器的设计
二、设计目的要求:
通过设计、编程、调试出一个具体语法分析程序,能调用词法分析程序为其提供单词符号串,进行语法分析,掌握语法分析方法和程序设计方法。
三、设计内容:
任选一种语法分析方法进行程序设计,语法分析程序能通过实例数据的测试。写出设计报告,内容为:所选的语法分析方法、算法、改写的文法、符号表、出错处理、编程方法等。SPL语言的文法
::= ::= program;* ::= ┃ * ::= a┃b┃┅┃ y ┃z * ::= ┃┃ ┃ * ::= 0┃ * ::= 1┃┅┃ 8 ┃9 ::= var :int;┃const;┃var :int;const;::= ┃, ::= = ┃ = , * ::= ┃ * ::= ┃ ::= begin end.::= ┃;::= ┃┃┃┃┃ ::= := ::= + ┃| * | / ::= = |
2、递归文法:
S-> while(B)S | i=E B-> E relop E relop-> E->(E)F | iF | nF F-> +EF |-EF | *EF | /EF | ε
3、语法分析方法描述:
按照递归下降分析技术,递归下降识别程序是由一组子程序组成,每个子程序对应于一个非终结符号。该子程序处理相应句型中相对于此非终结符号的产生式。在定义文法时,是递归定义的,所以这些子程序也是递归的。当一个子程序调用另一个子程序时,总是先执行被调用的子程序,然后再执行后继的程序。
4、三地址代码
在本程序中用到了三地址语句的输出包括以下的种类: 赋值语句:x:= y op z 复制语句:x:= y 条件转移语句:if x relop y goto L 例如:本程序中语句while(B)S ,可以输出三地址代码为:if B goto L else goto Lnext;而E->(E)F可以输出三地址代码为:E1:=(E2)F。
5、Getsymbol()子程序的算法描述 Int Getsymbol(){sym=fgetc(intput);//取当前文件指针指向的字符 While(sym不为空){if(sym是a-z的字符){将该字符保存在token1数组中;继续取下一个是a-z的字符保存在数组中;当sym不是字符时,则判断该数组中的符号串是不是关键字,是就返回16(while的机内码);不是就返回13(变量的机内码); } Else if(sym是0-9之间的数字)
{将该数字保存在token2数组中;继续取下一为0-9的数字,并保存到数组中去;当sym不是数字是,就返回12(常数的机内码); } Else if(sym是+)返回4;
Else if(sym是-)返回3;
Else if(sym是*)返回2; Else if(sym是/)返回1; Else if(sym是
Else if(sym是=)返回10;
Else if(sym是>)返回9; Else if(sym是;)返回20;
} 该程序就是对输入串进行分析,分析到不同的数据类型就相应返回它的机内码,这样方便在语法分析中进行分析。本程序还保存了变量和常量在结构数组中,方便在语义分析的时候使用。S()子程序的算法描述 void S(){re=Getsymbol();//取下一个字符的机内码 if(re==关键字)//执行S->while(B)S {re=Getsymbol();//取下一个字符的机内码 If(re==左括号){调用B();
re=Getsymbol();//取下一个字符的机内码 if(re==右括号)调用S();}} Else if(re==变量)//执行S->i = E { re=Getsymbol();//取下一个字符的机内码 If(re==等号)调用E();} Else ERROR(); } 该程序就是对通过Getsymbol()词法分析程序得到的单词,进行不同的程序语句执行。当得到了while是就分析下一个是不是(,是的话就调用B();否则就出错。取下一个单词,是)就调用S();否则也出错。当得到的是变量i时,去下一个单词,如果是=就调用E()。B()和relop()子程序的算法描述
在B()子程序中,不用判断任何的单词,就依次调用E(),relop(),E(),执行B->E relop E Void relop(){ re=Getsymbol();//取下一个字符的机内码 If(sym==大于号); //执行relop->= Else if(syn==小于号); //执行relop->> Else ERROR(); } 在relop程序中就主要上判断当前取得的单词是不是条件运算符。E()子程序的算法描述 Void E(){ re=Getsymbol();//取下一个字符的机内码 if(re==左括号)//执行E->(E)F { E();
re=Getsymbol();//取下一个字符的机内码 if(re==右括号)F(); } Else if(re==变量)//执行E->iF F();
Else if(re==常量)//执行E->nF F(); } F()子程序算法描述 Void F(){ re=Getsymbol();//取下一个字符的机内码 If(re==加号)//执行F->+EF { E();F();} Else if(re==减号)//执行F->-EF { E();F();} Else if(re==乘号)//执行F->*EF { E();F();} Else if(re==除号)//执行F->/EF { E();F();} } 这个子程序和E()合起来就是一个完整的可递归的算术操作运算,但由于递归下降分析方法不能含有左递归文法,所以消去左递归后就成了两个子程序。
五、运行结果与数据分析:
六、设计总结体会: