完整版编译原理毕业课程设计C语言编译器的实现文档格式.docx
《完整版编译原理毕业课程设计C语言编译器的实现文档格式.docx》由会员分享,可在线阅读,更多相关《完整版编译原理毕业课程设计C语言编译器的实现文档格式.docx(46页珍藏版)》请在冰豆网上搜索。
6
23
lettet(letter|digit)*
10
24
dightdight*
11
25
+
13
;
26
—
14
(
27
*
15
)
28
16
#
详细设计:
4.1界面导入设计
(1)一共三个选项:
(2)界面演示
图一
图二
图三
4.2词法分析程序
(1)流程图设计
(2)具体功能的具体设计
1、cifafenxi()
首先设置prog[n]来接收输入的语句,以‘#’来结束;
调用扫描子程序scaner1(),每一次得到一个类型码;
用switch判别相应输出;
直到syn1=0为止。
首先设置3个变量:
①token1用来存放构成单词符号的字符串;
②sum1用来存放整型单词;
③syn1用来存放单词符号的类型码。
有关scaner1()中关键点解析:
①
while((ch=='
'
)||(ch=='
\n'
))ch=prog[p++];
;
忽略空格
②
if(((ch<
='
z'
)&
&
(ch>
a'
))||((ch<
Z'
A'
)))
{while(((ch<
))||((ch>
0'
(ch<
9'
{token[m++]=ch;
ch=prog[p++];
};
判别标识符
③
for(n=0;
n<
6;
n++)
if(strcmp(token,rwtab[n])==0)
{syn=n+1;
break;
};
标识符是否是关键字
④
if((ch>
))
{while((ch>
{sum=sum*10+ch-'
;
}}
判别整数
(3)词法分析的运行结果
输入
beginx:
=1;
y:
=1+2;
end#
输出
4.3语法分析程序
(1)具体功能的具体设计
给出算术表达式文法,进行适当的文法变换
输入——表达式;
输出——表达式语法是否正确。
2.子程序的功能描述
(3)语法分析的运行结果
分析成功图
分析失败图
4.4中间代码生成程序
(1)总体描述
采用递归下降(自上而下)的语法制导翻译法。
在前两次试验的基础上改进。
词法分析程序语法分析程序语义分析程序编译器。
不断完善,
不断改进。
渐变的过程。
单词符号及种别表
种别编码
单词值
main
int
float
double
char
if
else
7
8
while
9
l(l|d)*
内部字符串
(+|-|ε)d*(.dd*|ε)(e(+|-|ε)dd*|ε)
二进制数值表示
-
*
{
}
29
30
31
32
33
34
35
==
36
!
37
(2)程序结构描述
(3)程序的功能描述
从文件中读入表达式,输出其四元式的结果序列
递归下降示意图
(4)详细功能描述
voidscanner();
扫描
voidlrparser();
voidstaBlock(int*nChain);
语句块
voidstaString(int*nChain);
语句串
voidsta(int*nChain);
语句
voidfuzhi();
赋值语句
voidtiaojian(int*nChain);
条件语句
voidxunhuan();
循环语句
char*E();
Expresiion表达式
char*T();
Term项
char*F();
Factor因子
char*newTemp();
自动生成临时变量
voidbackpatch(intp,intt);
回填
intmerge(intp1,intp2);
合并p1和p2
voidemit(char*res,char*num1,char*op,char*num2);
生成四元式
voidemit(char*res,char*num1,char*op,char*num2)
该函数的功能是生成一个三地址语句送到四式表中
char*newTemp()
该函数的功能是会动一个新的临时变量,临时变量名产生的顺序是T1,T2,T3,….
intmerge(intp1,intp2)
该函数的功能是将以P1,P2为链首的两条链合并成一条链,返回时的函数值作为合并后的链首。
voidbackpatch(intp,intt)
该函数的功能是把P所链接的每个四元式的第四区段(result段)都回填t。
voidfuzhi()
该函数的功能是对赋值语句进行分析。
voidtiaojian(int*nChain)
该函数的功能是对条件语句进行分析。
voidxunhuan()
该函数的功能是对循环语句进行分析。
(4)结果演示
图一简单语句生成四元式
图二if语句的四元式生成
图三循环语句四元式生成
(5)汇编生成
if(strcmp(fourCom[i].opera,"
="
)==0)
{
printf("
MoveAX,%1s\n"
fourCom[i].arg1);
Move%5s,Ax\n"
fourCom[i].result);
+"
MovAX,%1s\n"
ADDAx,%1s\n"
fourCom[i].arg2);
printf("
Mov%1s,Ax\n"
-"
SUBAx,%1s\n"
*"
MovAL,%1s\n"
MUL%1s\n"
"
DIv%1s\n"
Mov%1s,AL\n"
goto"
jmpL%1s\n"
i);
结果演示
五、课程设计的体会与总结
经过一个星期的编译原理课程设计,本人在陈宏建老师的指导下,顺利完成该课程设计。
通过该课程设计,收获颇多。
词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
通过本试验的完成,更加加深了对词法分析原理的理解。
通过本次试验,了解了语法分析的运行过程,主程序大致流程为:
“置初值”调用scaner函数读下一个单词符号调用IrParse结束。
递归下降分析的大致流程为:
“先判断是否为begin”不是则“出错处理”,若是则“调用scaner函数”调用语句串分析函数“判断是否为end”不是则“出错处理”,若是则调用scaner函数“判断syn=0&
kk=0是否成立”成立则说明分析成功打印出来。
不成立则“出错处理”。
一、对实验原理有更深的理解
通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的。
通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。
二、对该理论在实践中的应用有深刻的理解
通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。
三、激发了学习的积极性
通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现方法。
把死板的课本知识变得生动有趣,激发了学习的积极性。
把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。
以前对与计算机操
在这次课程设计中,我就是按照实验指导的思想来完成。
加深了理解文件系统的内部功能及内部实现,培养实践动手能力和程序开发能力的目的。
附录-----程序清单
#include<
math."
"
if"
then"
while"
do"
end"
};
intr1;
charprog[80];
存放所有输入字符
chartoken[8];
存放词组
charch;
单个字符
intsyn,p,m,n,i;
syn:
种别编码
doublesum;
intcount;
intisSignal;
是否带正负号(0不带,1负号,2正号)
intisError;
intisDecimal;
是否是小数
doubledecimal;
小数
intisExp;
是否是指数
intindex;
指数幂
intisNegative;
是否带负号
doubletemp;
inttemp2;
intrepeat;
是否连续出现+,-
intnextq;
intkk;
临时变量的标号
intntc,nfc,nnc,nnb,nna;
char*rwtab[9]={"
main"
int"
float"
double"
char"
else"
struct{
charresult[10];
字符串(字符数组)
chararg1[10];
charopera[10];
chararg2[10];
}fourCom[20];
结构体数组
cifafenxi();
yufafenxi();
zhongjiandaima();
scaner1();
voide();
voide1();
voidt();
voidt1();
voidf();
voidlrparser()
intnChain;
nfc=ntc=1;
nextq=1;
if(syn==1)main
scanner();
if(syn==26)(
{
scanner();
if(syn==27))
{
scanner();
staBlock(&
nChain);
}
else
printf("
缺少右括号\n"
);
}
else
printf("
缺少左括号\n"
}
else
printf("
缺少main\n"
语句块>
:
:
='
{'
语句串>
'
}'
voidstaBlock(int*nChain)语句块
if(syn==28){
staString(nChain);
backpatch(*nChain,nextq);
if(syn==29)}
读下一个
else
缺少}号\n"
缺少{号\n"
=<
语句>
{;
voidstaString(int*nChain)语句串
sta(nChain);
backpatch(*nChain,nextq);
while(syn==31);
sta(nChain);
backpatch(*nChain,nextq-1);
voidsta(int*nChain)语句
if(syn==10)
fuzhi();
*nChain=0;
elseif(syn==6)if
tiaojian(nChain);
elseif(syn==8)do
xunhuan();
条件语句>
->
if(<
条件>
)<
charres[10],num1[10],num2[10],op[10];
intnChainTemp;
<
表达式>
关系运算符>
if(syn==6)if
strcpy(num1,E());
strcpy(num1,E());
if((syn<
=37)&
(syn>
=32))
switch(syn)
{
case32:
strcpy(op,"
break;
case33:
case34:
case35:
case36:
=="
case37:
default:
printf("
error"
}
strcpy(num2,E());
strcat(num1,op);
strcat(num1,num2);
nfc=nextq+1;
ntc=nextq;
记住if语句位置
emit("
0"
num1,"
nfc=nextq;
if中表达式为假
第一个0已回填
backpatch(ntc,nextq);
ntc链接的所有四元式都回填nextq
}
if(syn==27))
staBlock(&
nChainTemp);
*nChain=merge(nChainTemp,nfc);
循环语句>
=do<
while<
if(syn==8)do
nnc=nextq;
记住if语句位置,emit之后nextq就变了
emit("
if(syn==9)while
if(syn==26)(
strcpy(num1,E());
if((syn<
switch(syn)
{
case32:
strcpy(op,"
break;
case33:
case34:
case35:
case36:
case37:
default:
printf("
}
strcpy(num2,E());
strcat(num1,op);
strcat(num1,num2);
nnb=nextq;
emit("
backpatch(nnb,nnc);
nna=nextq;
backpatch(nna,nextq);
voidfuzhi()赋值语句只有1个操作数
charres[10],num[10];
num操作数
if(syn==10)字符串
strcpy(res,token);
结果
if(syn==21)=
strcpy(num,E());
emit(res,num,"
缺少=号\n"
char*E()Expression表达式
char*res,*num1,*op,*num2;
res=(char*)malloc(10);
num1=(char*)malloc(10);
op=(char*)malloc(10);
num2=(char*)malloc(10);
strcpy(num1,T());
while((syn==22)||(syn==23))+-
if(syn==22)+
strcpy(op,"