编译原理课程设计.docx
《编译原理课程设计.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计.docx(21页珍藏版)》请在冰豆网上搜索。
![编译原理课程设计.docx](https://file1.bdocx.com/fileroot1/2022-11/30/ca31dce5-3302-46a7-a72d-6a6860d83140/ca31dce5-3302-46a7-a72d-6a6860d831401.gif)
编译原理课程设计
《编译原理》课程设计报告
C语言子集编译器设计
学院信息科学与工程学院专业计算机科学与技术
班级学号
学生姓名指导教师
课程成绩完成日期2012年12月29日
课程设计成绩评定
学院信息学院专业计算机科学与技术
班级学号
学生姓名指导教师
课程成绩完成日期2012年12月29日
指导教师对学生在课程设计中的评价
评分项目
优
良
中
及格
不及格
课程设计中的创造性成果
学生掌握课程内容的程度
课程设计完成情况
课程设计动手能力
文字表达
学习态度
规范要求
课程设计论文的质量
指导教师对课程设计的评定意见
综合成绩指导教师签字2012年月日
C语言子集编译器设计
学生姓名:
指导老师:
1、设计任务
1.1编译的语言
本编译器编译的语言为C语言子集,具体如下:
算术运算符:
+-*/
关系运算:
><>=<=!
====
逻辑运算&&||!
赋值运算=
数字0123456789
字符a…..zA…..Z
标示符的命名规则:
由字母和下划线组成,打头的只能是字母,区分大小写,不能和关键字重复。
注释:
单行注释//多行注释/**/
数据类型有整型int,字符型char
符合数据类型有数组inta[6]
程序由一个主函数组成
<主函数>→voidmain(){<复合语句>}
<复合语句>→<常量说明部分><变量定义部分><语句序列>
<常量定义>→int<标示符>=<整数>{,int<标示符>=<整数>}|
char<标示符>=<字符>{,char<标示符>=<字符>}|
变量定义:
inta;
inta,b;
inta=3,b;
<语句序列>→<语句>;<语句序列>
语句有赋值语句<标示符>=<表达式>
读语句:
scanf(“<标示符>”)
写语句:
printf(<字符串>);
条件语句:
if(条件){}else{}
If(条件){}
循环语句:
while(条件){}
For(i=1;i<=10;i++){}
1.2抽象文法
1.2.1构造LL1要解决的关键问题
本编译器采用LL1文法,设计LL1文法有两个关键点:
1、消除文法左递归:
左递归文法如:
E->E+E
E->id|num
可使用增加中间非终结符的方法消除左递归,消除后为:
E->T+E
E->T
T>id|num
2、消除分析表多重定义
上述文法仍不是LL1文法,采用提公因子的方法修改上述文法后可得LL1文法:
E->TE’
E-‘>+T|$
T>id|num
1.2.2C语言子集的LL1文法
[Terminal]:
mainprintfscanfvoidintcharboolidnumchifelsewhilefor;,(){}===!
=><+-*/&&||!
++--#(结束符)
[Nonerminal]:
S,B,A,C,,X,R,Z,Z’,U,U’,E,E’,H,H’,G,M,D,L,L’,T,T’,F,O,P,Q
[Starter]:
S
[Precept]:
1、文法开始:
(1)S->voidmain(){A}
2、声明:
(2)X->YZ;
(3)Y->int
(4)Y->char
(5)Y->bool
Z->UZ’
Z’->,Z|$
U->idU’
U’->=L|$
3、赋值:
R->id=L;
4、算术运算:
L->TL’
L’->+L|-L|$
T->FT’
T’->*T|/T|$
F->(L)
F->id|num
O->++|--|$
Q->idO|$
5、布尔运算
E->HE’
E’->&&E|$
H->GH’
H’->||H
H’->$
G->FDF
D-><|>|==|!
=
G->(E)
G->!
E
5、控制语句
B->if(E){A}else{A}
B->while(E){A}
B->for(YZ;G;Q){A}
6、功能函数
B->printf(P);
B->scanf(id);
P->id|ch|num
7、复合语句
A->CA
C->X|B|R
A->$
2、需求分析
为C语言子集设计一个简单编译器,要求有友好的图形界面,能够实现编译的词法分析,语法分析和语义分析功能,并具备一定的错误处理能力,给出总的出错报告,编译最终形成四元式的中间代码形式。
3、系统设计
4、详细设计
4.1构造LL1分析表
1、求个产生式的select集
注意:
一定要记得求空产生式A->$的select集
具体过程(略),结果可见LL1分析表
2、最终获得的LL1分析表
main
printf
scanf
void
int
char
bool
id
(自定义变量)
num(int常量)
ch(char
常量)
S
S>
void
main(){A}
A
A->CA
A->CA
A->CA
A->CA
A->CA
A->CA
B
B->
printf(P);
B->
scanf(id);
C
C->B
C->B
C->X
C->X
C->X
C->R
X
X->YZ
X->YZ
X->YZ
Y
Y->int
Y->char
Y->bool
Z
Z->UZ’
Z’
Z’->$
U
U->idU’
U’
R
R->id=L;
P
P->id
P->num
P->ch
E
E->HE’
E->HE’
E’
E’->$
H
H->GH’
H->GH’
G
G->FDM
G->FDM
H’
H’->$
H’->$
D
L
L->TL’
L->TL’
L’
L’->$
L’->$
T
T->FT’
T->FT’
T’
T’->$
T’->$
F
F->id
F->num
O
Q
Q->idO
if
else
while
for
;
(
)
{
}
=
==
S
A
A->CA
A->CA
A->CA
A->CA
B
B->
If(G){A}
else{A}
B->
while(G){A}
B->
for(YZ;G;Q)
{A}
C
C->B
C->B
C->B
C->B
X
Y
Z
Z’
Z’->,Z
U
U’
U’->$
U’->$
U’->=L
R
P
E
E->HE’
E’
H
H->GH’
G
G->(E)
H’
H’->$
D
D->==
L
L->TL’
L->TL’
L’
L’->$
T
T->FT’
T’
T’->$
F
F->(L)
O
!
=
>
<
+
-
*
/
&&
||
!
++
--
#
S
A
A->$
B
C
X
Y
Z
Z’
Z’->$
U
U’
U’->$
R
P
E
E’
E’->&&E
E’->$
H
G
G->!
E
H’
H’->||H
H’->$
H’->$
D
D->!
=
D->>
D-><
L
L’
L’->+L
L’->-L
L’->$
T
T’
T’->*T
T’->/T
T’->$
F
O
O->++
O->--
O->$
Q
Q->$
语法分析示例:
待分析源程序:
voidmain()
{
inta=2,b=3,c;
if(a>b)
{
c=1;
}
else{
c=0;
}
}
步骤
分析栈analyseStack
余留符号串
wordlist
待分析单词表的首单词,firstWord=wordlist.get(0)
产生式
下一步动作
0
$S
voidmain(){inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
void
S->
void
main(){A}
弹出S,{A}()mainvoid入栈
1
${A}()mainvoid
main(){inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
void
移进
弹出void,扫描指针后移一个符号
2
${A}()main
main(){inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
main
移进
弹出main,扫描指针后移一个符号
3
${A}()
(){inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
)
移进
弹出),扫描指针后移一个符号
4
${A}(
){inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
(
移进
弹出(,扫描指针后移一个符号
5
$}A{
{inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
{
移进
弹出{,扫描指针后移一个符号
6
$}A
inta=2,b=3,c;if(a>b){
c=1;}else{c=0;}}
A->CA
弹出A,CA逆序进栈
…
…
…
…
…
…
4.2构造LL1属性翻译文法及分析表
1、构造LL1属性翻译文法
构造LL1属性翻译文法即在原有LL1文法基础上加上动作符号,并给非终结符和终结符加上一定属性,给动作符号加上语义子程序。
对原有LL1文法改进的地方如下:
1、赋值:
产生式语义子程序
R->@ASS_Rid=L@EQ;@ASS{R.VAL=id并压入语义栈}
@EQ{RES=R.VAL,OP=’=’,ARG1=L.VAL,
newfourElement(OP,ARG1,/,RES)}
U->@ASS_UidU’{U.VAL=id并压入语义栈}
U’->=L|$@EQ{RES=U.VAL,OP=’=’,ARG1=L.VAL,newfourElement(OP,ARG1,/,RES)}
2、算术运算:
产生式语义子程序
L->TL’@ADD_SUB{If(OP!
=null)RES=NEWTEMP;L.VAL=RES,并压入语义栈;NewfourElement(OP,T.VAL;,L’VAL,RES),
}
L’->+L{OP=”+”}
L’->-L{OP=”-“}
L’->$
T->FT’@DIV_MUL{if(OP!
=null)RES=NEWTEMP;T.VAL=RES;
newFourElement(OP,F.VAL,ARG2,RES)
elseARG1=F.VAL;}
T’->/T@DIV{OP=/,ARG2=T.VAL}
T’->*T@MUL{OP=*,ARG2=T.VAL}
T’->$
F->@ASS_Fnum|id{F.VAL=num|id}
Q->idO|$
O->@SINGLE_OP++|--{OP=++|--}
3、布尔运算
产生式语义子程序
G->FDF@COMPARE{OP=D.VAL;ARG1=F
(1).VAL;ARG2=F
(2).VAL,RES=NEWTEMP;
NewfourElement(OP,F.VAL,ARG2,RES);G.VAL=RES并压入语义栈}
D->@COMPARE_OP<|>|==|!
={D.VAL=<|>|==|!
=,并压入语栈}
4、控制语句
产生式语义子程序
B->if(G)@IF_FJ{A}@IF_BACKPATCH_FJ@IF_RJelse{A}@IF_BACKPATCH_RJ
@IF_FJ{OP=”FJ”;ARG1=G.VAL;RES=if_fj,NewfourElement(OP,ARG1,/,RES),将其插入到四元式列表中第i个}
@IF_BACKPATCH_FJ{回填前面假出口跳转四元式的跳转序号,BACKPATCH(i,if_fj)}
B->while(G)@WHILE_FJ{A}@WHILE_RJ@WHILE_BACKPATCH_FJ{参照ifelse}
B->for(YZ;G@FOR_FJ;Q){A@SINGLE}@FOR_RJ@FOR_BACKPATCH_FJ{参照ifelse}
@SINGLE{ARG1=id;RES=NEWTEMP;NewfourElement(OP,ARG1,/,RES)}
说明:
(1)、R.VAL表示符号R的值,VAL是R的一个属性,其它类似。
(2)、NEWTEMP()函数:
每调用一次生成一个临时变量,依次为T1,T2,…Tn。
(3)、BACKPATCH(inti,intres):
回填函数,用res回填第i个四元式的跳转地址。
(4)、newfourElement(StringOP,StringARG1,StringARG2,StringRES):
生成一个四元式
(OP,ARG1,ARG2,RES)
3、构造LL1属性文法分析表(参照LL1分析表构造)
4.3数据结构设计
1、节点类
单词
publicclassWord{
intid;//单词序号
Stringvalue;//单词的值
Stringtype;//单词类型
intline;//单词所在行
booleanflag=true;//单词是否合法
}
分析栈节点
publicclassAnalyseNode{
Stringtype;//节点类型
Stringname;//节点名
Stringvalue;//节点值
}
错误
publicclassError{
intid;//错误序号;
Stringinfo;//错误信息;
intline;//错误所在行
Wordword;//错误的单词
}
四元式
publicclassFourElement{
intid;//四元式序号,为编程方便
Stringop;//操作符
Stringarg1;//第一个操作数
Stringarg2;//第二个操作数
Objectresult;//结果
}
2、表
单词表
ArrayListwordList=newArrayList();//单词表
错误信息表
ArrayListerrorList=newArrayList();//错误信息列表
四元式列表
ArrayListfourElemList=newArrayList();
3、栈
LL1分析栈
StackanalyseStack=newStack();//分析栈
语义栈
StacksemanticStack=newStack();//语义栈
Stackif_fj,if_rj,while_fj,while_rj,for_fj,for_rj;
//ifwhilefor跳转地址栈,用于实现控制语句嵌套
Stackfor_op=newStack();
//for(YZ;G;Q)中Q的操作符号栈,用于实现for的嵌套
4.4程序流程图
1、词法分析流程图
2、LL1翻译器流程图
6、测试报告
1、测试用例1(测试for语句嵌套)
源程序:
voidmain()
{
intsum=0,mul=1;
for(inti=1;i<11;i++){
for(intj=i;j>0;j--){
mul=mul*j;
}
sum=sum+mul;
}
}
词法分析结果:
语法分析结果:
生成的四元式:
参考资料
[1]陈意云编译原理和技术人民邮电出版社
[2]姜文清编译技术原理科学出版社
[3]迟忠先编译方法清华大学出版社
[4]郭浩志程序设计语言概论西安电子科技大学出版社
[5]杜淑敏编程程序设计原理人民邮电出版社
[6]王冰山形式语言高等教育出版社
[7]易文涛Java手册机械工业出版社
[8]董士海计算机软件工程环境和软件工具北京科学出版社