《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx

上传人:b****5 文档编号:11812588 上传时间:2023-04-02 格式:DOCX 页数:24 大小:151.08KB
下载 相关 举报
《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx_第1页
第1页 / 共24页
《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx_第2页
第2页 / 共24页
《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx_第3页
第3页 / 共24页
《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx_第4页
第4页 / 共24页
《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx

《《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx》由会员分享,可在线阅读,更多相关《《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx(24页珍藏版)》请在冰豆网上搜索。

《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示.docx

《编译原理》课程设计DOWHILE循环语句的翻译程序设计LL1法输出三地址表示

学号:

0121310870516

课程设计

 

题目

编译原理

学院

计算机科学与技术

专业

计算机科学与技术

班级

姓名

指导教师

 

2015

12

7

课程设计任务书

学生姓名:

专业班级:

指导教师:

工作单位:

题目:

while循环语句的翻译程序设计(LL

(1)法、输出三地址表示)

初始条件:

理论:

学完编译课程,掌握一种计算机高级语言的使用。

实践:

计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码三地址表示的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:

1系统描述(问题域描述);

2文法及属性文法的描述;

3语法分析方法描述及语法分析表设计;

4按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;

5编译系统的概要设计;

6详细的算法描述(流程图或伪代码);

7软件的测试方法和测试结果;

8研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);

9参考文献(按公开发表的规范书写)。

时间安排:

设计安排一周:

周1、周2:

完成系统分析及设计。

周3、周4:

完成程序调试及测试。

周5:

撰写课程设计报告。

设计验收安排:

设计周的星期五第1节课开始到实验室进行上机验收。

设计报告书收取时间:

设计周的次周星期一上午10点。

 

指导教师签名:

2011年12月23日

系主任(或责任教师)签名:

2011年12月23日

WHILE语句的翻译程序设计

(LL

(1)文法、输出三地址表达式)

1课设的描述

1.1课设要求

首先按照课程设计的要求,写一个能识别while循环语句的文法,并使它符合LL

(1)法的要求,按照这个文法编写一个程序,该程序能识别输入的语句是否符合while语句的文法,或者通过文法的开始符号能判断是否能推导出该语句。

程序应该包括词法分析器,能对输入的语句进行词法分析,对输入的源程序从左到右进行扫描并将其分解为一个个的单词符号。

然后再对结果进行语法分析。

词法分析器应能识别关键字,标识符,常量,操作符等。

该程序的语法分析器能对输入的语法进行分析,判断输入语句能否满足while循环语句的文法,如果不是则提示错误,如果满足while循环语句文法,判断是否符合LL

(1)法,运用最左推导对其进行分析,看能否通过开始符号推导出来。

将语法和语义分析的结果用输出三地址形式表示出来。

1.2课设中所用概念

1)词法分析:

输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词符号:

关键字(do,while)、标识符、常量、操作符等。

2)语法分析:

在词法分析的基础上,根据语法规则,把单词符号串分解成各类语法单位。

3)语义分析与中间代码产生:

对语法分析所识别出的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)。

4)LL

(1)文法:

LL

(1)文法是一种自上而下的语法分析方法。

第一个L是自上而下的分析,第二个L是从最左单词开始分析,1代表只通过下1个单词分析需要用到的语法。

5)预测分析程序:

实现LL

(1)法分析的一种有效方法,使用一张预测分析表和一个栈进行联合控制。

预测分析程序就是属于这种类型的LL

(1)分析器。

2文法的描述

2.1While语句文法描述

K->dLwSL->SP

P->;SPP->ε

S->iQEE->TG

G->+TGG->-TG

G->εT->FR

R->*FRR->/FR

R->εF->(E)

F->IQ->=

Q->>

非终结符集VN{K,L,P,S,G,R,E,F,Q,T}

终结符集V*{do,while,(,),ε,+,-,*,/,i,>,=,<,;}

 

预测分析表

i

=

<

>

+

-

*

/

do

ε

;

while

K

dLwS

L

SP

P

ε

;SP

S

iQE

E

-TG

TG

G

+TG

-TG

ε

ε

ε

T

FR

FR

R

ε

ε

*FR

/FR

ε

ε

ε

F

i

(E)

Q

=

<

>

 

3语法分析方法及中间代码形式的描述

3.1语法分析方法描述

LL

(1)文法的定义:

First集:

设G={VT,VN,S,P}是上下文无关文法

First(α)={a|α=>aβ,a∈VT,α,β∈V*}

若a=>ε,则规定ε∈First(α),称为First(α)为α的开始符号集或首符号集。

FOLLOW集:

设G={VT,VN,S,P}是上下文无关文法

FOLLOW(A)={a|S=>μAβ且a∈VT,a∈First(β),μ∈V*T,β∈V+}

若S=>μAβ,且β=>ε,则#∈FOLLOW(A)

SELECT集:

给定上下文无关文法的产生式A-->αA∈VN,α∈V*,若α≠>ε,则SELECT(A-->α)=First(α)

如果α=>ε,则SELECT(A-->α)=(First(α)-{ε})UFOLLOW(A).

LL

(1)文法:

一个上下文无关文法是LL

(1)文法的充分必要条件是,对每个非终结符A的两个不同的产生式,A-->αA-->β,满足

SELECT(A-->α)∩SELECT(A-->β)=ф

其中α,β不能同时推导出空.

3.2中间代码形式

三地址码是由下面一般形式的语句构成的序列:

x:

=yopz

其中,xyz为名字、常数或临时变量;op代表运算符号。

每个语句中只能有一个运算符。

三地址码类似于汇编语言代码。

语句可以带有符号标号,而且存在各种控制流语句,本程序输出中用到了:

复制语句x:

=y

条件转移语句ifxrelopygotoL//L为带标号L的三地址语句

无条件转移语句gotoL//转移到标号为L的三地址语句。

4简要的分析与概要设计

4.1基本框架

输入while语句词法分析语法语义分析输出三地址代码

4.2构成图

4.2.1主函数构成

词法分析

语法语义分析

Main()

控制输出三地址码

 

4.3各个部分构成

整个工程分为四个部分,词法分析部分,和语法分析部分,具体函数执行部分,以及语义分析部分(最终部分在main函数中执行的)

lexical()-----程序的入口点,读入输入的待分析的字符串后,把其装入一给定数组,先进行词法分析,然后输出生成的词法分析结果。

syntax()-----语法分析阶段,利用Wordanalyze()中分析出的词法,进行语法分析.如果不是LL

(1)文法则输出语法出错,仅对LL

(1)文法的输入进行分析.

具体函数执行部分-----定义了各种操作函数以方便调用,入读入输入的句字的函数,提

取字符函数,判断字符函数等等

语义分析式部分-------主函数中进行的输出,形式为给定句子的三地址表达式

 

5算法描述

5.1词法分析的主要算法

voidlexical()//词法分析

{

inti,j,d;

charch;

j=d=0;

for(i=0;var[i]!

='#';i++)//判断关键字

{

ch=var[i];

if(ch=='d'&&var[i+1]=='o')

{

cout<<"do"<<'\t'<<"关键字"<

queue[j++]='d';i+=1;

}

elseif(ch=='w')

{

ch=var[i+1];

if(ch=='h')

{

ch=var[i+2];

if(ch=='i')

{

ch=var[i+3];

if(ch=='l')

{

ch=var[i+4];

if(ch=='e')

{

ch=var[i+5];

}

}

}

}

cout<<"while"<<'\t'<<"关键字"<

queue[j++]='w';i+=4;

}

elseif(index(ch,VT)<=0)//判断标示符分隔符运算符

{

if(ch!

='{'&&ch!

='}'&&ch!

='('&&ch!

=')')

{

cout<

arr_i[d-1]=ch;

queue[j++]='i';

}

elsecout<

}

elseif(index(ch,VT)>0)

{

cout<

queue[j++]=ch;

}

}

queue[j]='#';

for(i=0;queue[i]!

='#';i++)cout<

cout<

}

语法分析主要算法

voidsyntax()//语法分析

{

intn;

count++;

print();

X=stack[sp];

a=queue[front];

if(X=='#'&&a=='#')f=4;

if(X<'A'||X>'Z')

{

if(X==a)

{

sp--;

front++;

if(a!

='i')

{

if(a!

='d'&&a!

='w'&&a!

=';'&&a!

='#')

{

opr=index(a,VT);

}

elseif(a==';'||a=='w'||a=='#')

{

opr=-2;

}

cout<<'\t'<<'\''<

}

else

{

opd=c;

cout<<'\t'<<'\''<

}

}

elsef=1;//字符不匹配,转去出错处理

}

else

{

inttx=index(X,VN);

intta=index(a,VT);

n=M[tx][ta];

td[t++]=M[tx][ta];

if(ta==-1)

{

f=2;cout<

}//字符没有出现在产生式终结符集VT中,转去出错处理

elseif(n==-1)f=3;//没有找到合适的候选产生式来做进一步推导,转去出错处理

else

{//用产生式M[tx][ta]来做进一步推导

sp--;

cout<<'\t'<";

if(len(p[n])!

=0)

{

for(inti=len(p[n])-1;i>=0;i--)

{

stack[++sp]=p[n][i];

cout<

}

cout<

}

elsecout<<"空串"<

}

}

if(f==0)syntax();

else

{

td[t]='-1';

err(f);

}

}

具体执行函数:

len求字符串长度

index查找字符串中是否有ch返回ch位置

err输出错误和错误原因

print打印

6上机测试

6.1测试方法

在visualc++6.0下调试并通过.输入不同的语句进行测试,测试的主要目的是看程序能否正确判断条件语句是否正确,赋值语句的格式有没有错误以及最后结果输出的三地址是否正确。

6.2测试过程和结果

现用一下用例来测试本程序:

测试1:

输入一个最简单的dowhile循环语句,正确输入看能否得出正确结果,程序运行结果如下:

 

 

测试2:

输入一错误语句查看结果:

如下

程序不能认出so所以程序不能编译。

7结果

7.1研制过程

这次课程设计要求我用LL

(1)分析法来翻译while循环语句,这就要求对编译原理语法分析方面有一定的了解,熟悉各种语法分析的方法,特别是本题中所要求的LL

(1)法,需要弄清楚LL

(1)法的概念,过程,需要注意的地方等。

另外还需要对编程语言联系,才能编出符合要求的程序。

看到题目以后,首先将编译原理书上相关知识仔细看了一遍,不清楚的地方搞清楚特别是关系程序设计的部分。

然后参阅了编译程序构造方面的书籍,对编译程序的实现有了一定的了解。

最后是从编程语言方面,根据编译原理方面的知识,找出实现课程设计要求的解决方式,然后编写程序来实现。

编好以后,对其测试,找出其中存在的问题,不过程序不能像c++一样很好的实现对while的翻译,有些复杂的输入还是不能识别。

7.2本次课程设计的缺点

这个对while的编译程序不能像C++那样完美的编译,不能识别太过复杂的语句,循环的嵌套,带小括号的运算是这次课程设计的缺点。

7.3本次课程设计的收获

课程设计是不同于上机实验的一种更考验学生能力的方式,由于每个人的课设题目都不一样所以很大程度的消除了学生的依赖感。

本次课设我学到了很多。

首先,巩固了编译原理的知识。

为了做好这次课程设计,要求我必须重新复习一遍编译的课本,特别是需要实现的那部分原理。

除此之外,还有上网查询一些编译资料,和一些实际问题实现的例子,通过看别人实现的过程,学习实现的一些基本思路。

这次课程设计的题目是用LL

(1)进行while循环语句的语法分析,并输出三地址表达式.设计的特点是利用定义每个终极符和非终极符之间优先关系,来进行符号的移进与规约,如果栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或等于读入符号,则找句柄进行归约,找不到句柄就继续读入。

这样使得程序简化,只需定义一个栈用来存放移进的字符,然后用栈顶指针指向它后与待移进字符比较优先级即可,设计简单.此设计的严重不足是只能进行一个固定句子的词法与语法分析,因为在定义优先关系时已固定了DO,和WHILE的每个字符之间的优先关系,且赋值表达式和条件式也已固定,所以只能进行本程序已约定好的语句.最大的收获是在提出一个难题以后,如果能比较顺手的解决的话,那是一件比较开心的事。

只是有些时候越想问题就会越多,也越难解决,那就得慢慢调试,慢慢推导了。

相信只要想得出,就能调得出,当然耐心是很重要的,花在上面的时间也是要多一点的。

其次,通过本次课程设计检验了我的数据结构的知识。

因为在语法分析中需要用到数据结构的一些知识,这就敦促我去重新温习数据结构中相关的知识。

8参考文献

(1)编译原理(第2版)清华大学出版社张素琴吕映芝等人著

 

本科生课程设计成绩评定表

班级:

 姓名:

 学号:

序号

评分项目

满分

实得分

1

学习态度认真、遵守纪律

10

2

设计分析合理性

10

3

设计方案正确性、可行性、创造性

20

4

设计结果正确性

40

5

设计报告的规范性

10

6

设计验收

10

总得分/等级

评语:

 

注:

最终成绩以五级分制记。

优(90-100分)、良(80-89分)、中(70-79分)、

及格(60-69分)、60分以下为不及格

 

指导教师签名:

2012年1月 日

源代码

#include

#defineMAX100

charX,a;

charVN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};

charVT[15]={'i','=','<','>','+','-','*','/','(',')','d','w',';','#','\0'};

charp[18][6]={"dLwS\0","SP\0",";SP\0","\0","iQE\0","TG\0","+TG\0","-TG\0","\0","FR\0",

"*FR\0","/FR\0","\0","(E)\0","i\0","=\0","<\0",">\0"};

charstack[MAX];

charqueue[MAX];

intsp,front;

intM[10][14]={{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1},

{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,-1},

{4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{5,-1,-1,-1,-1,-1,-1,-1,5,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,6,7,-1,-1,-1,-1,-1,8,8,8},

{9,-1,-1,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,12,12,10,11,-1,-1,-1,12,12,12},

{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},

{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

};

intf=0;

intcount=0;

intc=0;

chararr_i[MAX];

charvar[MAX];

inttd[MAX];//输出产生式序列

intt=0;

intopd=-1;

intopr=-1;

intid=0;

intd=0;

chararr[MAX][10];//存放待输出的三地址

intlen(charstr[])//求字符串长度

{

inti=0;

while(str[i]!

='\0')i++;

returni;

}

intindex(charch,charstr[])//查找字符串中是否有ch返回ch位置

{

inti=0;

while(str[i]!

='\0')

{

if(ch!

=str[i])i++;

elsebreak;

}

if(str[i]=='\0')return-1;

returni;

}

voiderr(intn)//输出错误和错误原因

{

if(n==1)

cout<<"字符不匹配"<

elseif(n==2)

cout<<"字符没有出现在产生式终结符集VT中"<

elseif(n==3)

cout<<"没有找到合适的候选产生式来做进一步推导"<

else

cout<<"该句子是文法语言的句子!

"<

}

voidprint()

{

cout<<"(";

if(count<10)cout<<'0';

cout<

inti;

for(i=0;i<=sp;i++)cout<

for(;i<=20;i++)cout<<"";

for(i=0;i

for(;queue[i]!

='#';i++)cout<

cout<

for(;i<=20;i++)cout<<"";

}

voidsemantic()

{

intj=0,k;

while(var[j]!

='\0')

{

if(var[j]=='=')

{

k=0;

for(j=j-1;(var[j]!

=';')&&(var[j]!

='}');j++,k++)

{arr[d][k]=var[j];}

arr[d][k]='\0';

d++;

j--;

}

if(var[j]=='<'||var[j]=='>')

{

k=0;

for(j=j-1;var[j]!

='}';j++,k++)

arr[d][k]=var[j];

arr[d][k]='\0';

d++;

j--;

}

j++;

}

}

 

voidsyntax()//语法分析

{

intn;

count++;

print();

X=stack[sp];

a=queue[front];

if(X=='#'&&a=='#')f=4;

if(X<'A'||X>'Z')

{

if(X==a)

{

sp--;

front++;

if(a!

='i')

{

if(a!

='d'&&a!

='w'&&a!

=';'&&a!

='#')

{

opr=index(a,VT);

}

elseif(a==';'||a=='w'||a=='#')

{

opr=-2;

}

cout<<'\t'<<'\''<

}

else

{

opd=c;

cout<<'\t'<<'\''<

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 生产经营管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1