编译技术课程设计盛利.docx
《编译技术课程设计盛利.docx》由会员分享,可在线阅读,更多相关《编译技术课程设计盛利.docx(17页珍藏版)》请在冰豆网上搜索。
![编译技术课程设计盛利.docx](https://file1.bdocx.com/fileroot1/2022-12/30/e0c23a2e-69f5-4ad3-800d-40490c0faf72/e0c23a2e-69f5-4ad3-800d-40490c0faf721.gif)
编译技术课程设计盛利
课程设计报告
(2010——2011年度第一学期)
课程名称:
编译技术课程设计
题目:
正则式到有限自动机的转换
院系:
控制与计算机工程学院
班级:
软件0801
学号:
1081250115
学生姓名:
盛利
指导教师:
齐林海
设计周数:
1周
成绩:
日期:
2011年1月1日
摘要
用c语言实现的从正规式到有穷自动机的转化,包括正规式转化成NFA,NFA转化成DFA,DFA的最小化。
从文件读入正规式,NFA或DFA。
如果读入正规式,则先将其转换为NFA,再将此NFA转换为DFA并最小化。
如果读入NFA,则将其转化为DFA并最小化。
如果读入DFA,则直接将其最小化。
通过编程实现正规式到有穷自动机的转化,让我们对课本上的转化过程更加清楚,明了。
关键字:
正规式NFADFA有穷自动机转化
ABSTRACT
Clanguagefromregulartypetotherealizationofthetransformationoffiniteautomaton,includingregulartypeintoNFA,NFAintoDFA,DFAminimization.Fromthedocumentintonormaltype,NFAorDFA.Ifreadinformaltype,thefirstconverttoNFA,thentheNFAconvertedtoDFAandminimized.IfreadNFA,thenconvertittoDFAandminimized.IfreadDFA,isdirectlyminimize.Throughtheprogrammingformaltypetothefiniteautomatontransformation,letusintheprocessoftransformationofthetextbook,moreclearlyunderstood.
Keyword:
Formaltype,NFA,DFA,finiteautomaton,transformation
目录
一、课程设计的目的5
二、课程设计的要求5
三、系统设计5
1.算法设计说明5
2.数据结构设计说明6
四、系统实现8
1.程序流程图8
2.重要编码实现说明8
五、课程设计总结及结论13
六、参考文献14
附录14
一、
课程设计的目的
本次课程设计的时间为1周,目的是通过实际的题目如:
词法分析、语法分析、代码优化等,使学生了解和掌握编译程序的工作原理,同时培养学生用相关的程序设计语言进行程序设计,实现编译的功能,从而提高学生的综合能力。
二、课程设计的要求
自己选一正规式;将其转换为DFA;编程实现此DFA;
任意输入一串符号判断是否符合。
三、系统设计
1.算法设计说明
程序可以以文件方式读取文法或自动机。
NFA的确定化
子集法
1.先把DFAM’中的Q’和F’置为空集;
2.M’的开始状态q0’=[q0],把[q0]置为未标记后加入到Q’中;
3.如果Q’中存在未标记的状态[q1,q2,…,qi],则对每个a∈∑定义:
δ’([q1,q2,…,qi],a)=[p1,p2,…,pi]当且仅当δ({q1,q2,…,qi},a)={p1,p2,…,pi}。
如果[q1,q2,…,qi]不在Q’中,则把它置为为标记后加入到Q’中;如果p1,p2,…,pi中至少有一个是M的终态,则同时把[p1,p2,…,pi]加入到F’中;然后给Q’中所有的状态都标记为止;
4.重复执行(3),直到不能向Q’中加入新状态,并且Q’中所有的状态都有标记为止;
5.重新命名Q’中的状态,最后获得等价的DFAM’
q1Qqq0Q0Q0q0
q1,qf
2.数据结构设计说明
constintOP=0;//操作符
constintOP_D=1;//操作数
typedefclass_EDGE
{
public:
intstart;
charinput;
intend;
friendbooloperator==(const_EDGE&a,const_EDGE&b)
{
return(a.start==b.start)&&(a.input==b.input)&&(a.end==b.end);
}
}EDGE;//自动机的边
typedefstruct_NFA
{
intstart;
intend;
}NFA;//
classREManage
{
public:
REManage();
REManage(stringre);
virtual~REManage();
//处理新的输入
voidProcess();
//测试输入字符串,判断能否由生成的DFA识别
boolTestString(stringstr);
//设置正规式
voidsetRE(stringre);
//设置NFA
voidsetNFA(vectoredge,vectorstart,vectorend);
//设置DFA
voidsetDFA(vectoredge,intstart,vectorend);
private:
//清空所有容器变量
voidclear();
//输出处理结果
voidOutputResult();
四、系统实现
1.程序流程图
2.重要编码实现说明
/********************分析RE函数**********************/
/*正规式到NFA的转换*/
voidProcessREToNFA();
intstate;//计数状态
inttype(charre);//判断输入字符的类型:
OP,OP_D
RE到NFA转换有关函数
/*对单个输入字符构造相应的NFA*/
voidMakeNFA_S(charinput,NFA*n,vector&edge);
/*构造某个NFA的闭包*/
voidMakeNFA_CL(NFA*result,NFA*op,vector&edge);
/*构造两个NFA的或运算*/
voidMakeNFA_OR(NFA*result,NFA*left,NFA*right,vector&edge);
/*构造两个NFA的与运算*/
voidMakeNFA_AND(NFA*result,NFA*left,NFA*right,vector&edge);
/*****************NFA到DFA转换有关函数***********/
/*NFA到DFA的转换*/
voidProcessNFAToDFA();
/*找到集合input的$闭包,结果保存在集合output中*/
VoidFind_NULL_Closure(vectorinput,vector&output,vectoredge);
/*计算集合input在输入为in时的所能达到的状态集合result*/
voidMove(vectorinput,charin,vector&result,vectoredge);
/****************DFA最小化有关函数*****************/
/*最小化DFA*/
voidMinimizeDFA();
/*在DFA中当初态为start,输入为input时,返回终态*/
intMovdDFA(intstart,charinput);
/*找到输入终态end所在的集合*/
intFindGather(intend,vector>gather);
/*消除DFA中的无用状态*/
voidRemoveFutility();
/*合并DFA中的等价状态*/
voidCombineEquality();
/*************************************End**********************************/
ofstreamout;
//正规式对应的变量
stringre;//输入的正规式
vectorREInput;//正规式的输入符
boolisREUpdate;//正规式是否已更新
//NFA对应的变量
vectorNFAInput;//NFA的输入符
vectorstartNFA;//NFA的起始状态集
vectorendNFA;//NFA的终态集
vectorNFA_EDGE;//构造出的NFA的所有边的集合
boolisNFAUpdate;//NFA是否已更新
//DFA对应的变量
vectorDFAInput;//DFA的输入符
intstartDFA;//DFA的起始状态
vectorendDFA;//DFA的终态集
vectornonEndDFA;//DFA的非终态集
vectorDFA_EDGE;//由NFA所构造成的DFA的边的集合
vector>DFAStateGather;//DFA中各个状态对应于NFA中的状态集
boolisDFAUpdate;//DFA是否已更新
//DFA最小化后对应的变量
vectorminiDFAInput;//最小化后DFA的输入符
intminiStartDFA;//最小化后DFA的起始状态
vectorminiEndDFA;//最小化后DFA的终态集
vectorminiNonEndDFA;//最小化后DFA的非终态集
vectorMiniDFA_EDGE;//最小化后DFA中的边的集合
vector>miniStateGather;//最小化后DFA中各个状态对应于初始DFA中的状态集
1.程序运行效果截图说明
五、课程设计总结及结论
编译原理是一门很重要的课程。
我们平常写小的C语言程序会感到困难,而编译原理则是关于编写编译器的技术,难度之大可想而知。
编译器的编写一直被认为是十分困难的事情,难怪第一Fortran的编译器据说花了18年的时间才完成。
当然编译原理和编译技术并不是相同的,编译原理更注重理论方面的知识,编译技术更注重实际编写编译器过程中用到的技术。
以前我不重视数学的学习,现在发现好的数学基础对整个计算机的学习都是极有帮助的。
数学分析能力强的同学,对编译原理中的各种算法,各种理论理解起来就要容易些。
因为它们之间的许多东西是相通的,只是表现形式不一样而已。
还有好的语言功底也是很重要的,在编程序的过程中,有时会和一个小小的错误叫上半天的劲,等到最后才发现只是由于语法用的不正确,算法是可行的。
这样在一个小小的语法错误上浪费许多时间是很不值得,所以在今后的语言学习中,我会重视语法的细节。
另外在程序设计上,以前自己倾向于直接写程序,很少使用流程图。
后来发现先设计出流程图,那么程序的结构就会清晰的多,编写的时候也会更节省时间。
六、参考文献
1.陈意云,马万里编著。
编译原理与技术。
中国科学技术大学出版社,1989
2.肖军模编著。
程序设计语言编译方法(第三版)。
大连理工大学出版社,2000
3.蒋宗礼,姜守旭。
形式语言与自动机理论。
清华大学出版社,2002
4.郑阿奇,丁有和。
VisualC++教程。
机械工业出版社,2005
5.张素琴,吕映芝。
编译原理(第二版)清华大学出版社,2004.
附录(设计流程图、程序、表格、数据、运行结果等)
main.cpp
#pragmawarning(disable:
4786)
#include
#include
#include
#include
usingnamespacestd;
#include"REManage.h"
voidwaitForInput()
{
cout<cout<<"输入完毕后,请按任意键开始处理...";
cout<getch();
HWNDnote=FindWindow("notepad",NULL);
:
:
SendMessage(note,WM_CLOSE,0,0);
}
voidReadRE(string&re)
{
ifstreamin("RE.txt");
in>>re;
}
voidReadTestString(vector&str)
{
ifstreamin("TestString.txt");
stringtemp;
for(;getline(in,temp),temp.size()>0;)
{
str.push_back(temp);
}
}
voidReadNFA(vector&edgeGather,vector&start,vector&end)
{
ifstreaminNFA("NFA.txt");
EDGEedge;
intedgeNum,startNum,endNum,temp;
edgeGather.clear();
start.clear();
end.clear();
inNFA>>edgeNum;
for(inti=0;i{
inNFA>>edge.start>>edge.input>>edge.end;
edgeGather.push_back(edge);
}
inNFA>>startNum;
for(i=0;i{
inNFA>>temp;
start.push_back(temp);
}
inNFA>>endNum;
for(i=0;i{
inNFA>>temp;
end.push_back(temp);
}
}
voidReadDFA(vector&edgeGather,intstart,vector&end)
{
ifstreaminDFA("DFA.txt");
EDGEedge;
intedgeNum,startNum,endNum,temp;
edgeGather.clear();
end.clear();
inDFA>>edgeNum;
for(inti=0;i{
inDFA>>edge.start>>edge.input>>edge.end;
edgeGather.push_back(edge);
}
inDFA>>startNum;
inDFA>>start;
inDFA>>endNum;
for(i=0;i{
inDFA>>temp;
end.push_back(temp);
}
}
voidOutTestResult(vectorstr,vectorisPass)
{
ofstreamout("TestResult.txt");
for(inti=0;i{
out<if(isPass[i])
out<<"PASS"<else
out<<"FAILE"<}
}
voidmain()
{
REManagetest;
ShellExecute(NULL,"open","instructions.txt",NULL,NULL,SW_SHOWNORMAL);
cout<<"说明:
详见instructions.txt"<cout<<"请阅读后按任意键开始...";
getch();
HWNDnote=FindWindow("notepad",NULL);
:
:
SendMessage(note,WM_CLOSE,0,0);
cout<stringre;//regularexpression
vectorstringGather;//teststringgather
vectoredgeGather;//edgegatherforbothNFAandDFA
intstartDFA=0;//startstateforDFA
vectorstartNFA;//startstategatherforNFA
vectorend;//endstategatherforbothNFAandDFA
vectorisPass;
for(;;)
{
stringGather.clear();
edgeGather.clear();
startNFA.clear();
end.clear();
isPass.clear();
intchoice=0;
cout<<"选择你的输入方式:
"<cout<<"1.输入正规式"<cout<<"2.输入NFA"<cout<<"3.输入DFA"<cout<<"0.退出"<cout<<"输入你的选择(1~4):
";
cin>>choice;
switch(choice)
{
case1:
ShellExecute(NULL,"open","RE.txt",NULL,NULL,SW_SHOWNORMAL);
waitForInput();
ReadRE(re);
test.setRE(re);
test.Process();
break;
case2:
ShellExecute(NULL,"open","NFA.txt",NULL,NULL,SW_SHOWNORMAL);
waitForInput();
ReadNFA(edgeGather,startNFA,end);
test.setNFA(edgeGather,startNFA,end);
test.Process();
break;
case3:
ShellExecute(NULL,"open","DFA.txt",NULL,NULL,SW_SHOWNORMAL);
waitForInput();
ReadDFA(edgeGather,startDFA,end);
test.setDFA(edgeGather,startDFA,end);
test.Process();
break;
case0:
exit(0);
default:
cout<<"输入错误!
"<exit
(1);
}
for(;;)
{
isPass.clear();
stringGather.clear();
cout<<"结果已经生成,请选择:
"<cout<<"1.测试生成串"<cout<<"2.完成"<cout<<"请输入你的选择:
";
cin>>choice;
if(choice==1)
{
ShellExecute(NULL,"open","TestString.txt",NULL,NULL,SW_SHOWNORMAL);
waitForInput();
ReadTestString(stringGather);
for(inti=0;i{
isPass.push_back(test.TestString(stringGather[i]));
}
OutTestResult(stringGather,isPass);
ShellExecute(NULL,"open","TestResult.txt",NULL,NULL,SW_SHOWNORMAL);
}
else
{
HWNDnote=FindWindow("notepad",NULL);
:
:
SendMessage(note,WM_CLOSE,0,0);
break;
}
}
HWNDnote=FindWindow("notepad",NULL);
:
:
SendMessage(note,WM_CLOSE,0,0);
cout<}
}