编译原理课程设计Word格式.docx

上传人:b****5 文档编号:17234663 上传时间:2022-11-29 格式:DOCX 页数:41 大小:153.22KB
下载 相关 举报
编译原理课程设计Word格式.docx_第1页
第1页 / 共41页
编译原理课程设计Word格式.docx_第2页
第2页 / 共41页
编译原理课程设计Word格式.docx_第3页
第3页 / 共41页
编译原理课程设计Word格式.docx_第4页
第4页 / 共41页
编译原理课程设计Word格式.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

编译原理课程设计Word格式.docx

《编译原理课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计Word格式.docx(41页珍藏版)》请在冰豆网上搜索。

编译原理课程设计Word格式.docx

递归下降程序分析和LL

(1)分析一般地都要求计算先行集合,它们分别称作First集合和Follow集合。

由于无需显式地构造出这些集合就可以构造出简单的自顶向下的分析程序。

1、LL

(1)文法

LL

(1)文法是一类可以进行确定的自顶向下语法分析的文法。

就是要求描述语言的文法是无左递归的和无回溯的。

根据LL

(1)文法的定义,对于同一非终结符A的任意两个产生式A:

=a和A:

=b,都要满足:

SELECT(A:

=a)∩SELECT(A:

=b)=Ø

这样,当前非终结符A面临输入符a时,如果a∈SELECT(A:

=a),则可以选择产生式A:

=a去准确匹配。

如本程序中举例说明的a.txt的文法就是一个LL

(1)文法:

S:

=aBc|bAB

A:

=aAb|b

B:

=b|0

2、文法的左递归

当一个文法是左递归文法时,采用自顶向下分析法会使分析过程进入无穷循环之中。

所以采用自顶向下语法分析需要消除文法的左递归性。

文法的左递归是指若文法中对任一非终结符A有推导A⇒A…,则称该文法是左递归的。

左递归又可以分为直接左递归和间接左递归。

3、直接左递归

若文法中的某一产生式形如A→Aα,α∈V*,则称该文法是直接左递归的。

消除直接左递归的方法:

设有产生式是关于非终结符A的直接左递归:

A→Aα|β(α,β∈V*,且β不以A开头)

对A引入一个新的非终结符A′,把上式改写为:

A→βA′

A′→αA′|ε

4、间接左递归

若文法中存在某一非终结符A,使得A⇒A…至少需要两步推导,则称该文法是间接左递归的。

消除间接左递归的方法:

【方法一】采用代入法把间接左递归变成直接左递归。

【方法二】直接改写文法:

设有文法G10[S]:

S→Aα|β⑴

A→Sγ⑵

因为S⇒Aα⇒Sγα,所以S是一个间接递归的非终结符。

为了消除这种间接左递归,将⑵式代入⑴式,即可得到与原文法等价的文法(可以证明):

S→Sγα|β⑶

⑶式是直接左递归的,可以采用前面介绍的消除直接左递归的方法,对文法进行改写后可得文法:

S→βS′

S′→γαS′|ε

4系统实现

系统流程图

5使用说明

5.1程序运行平台

VisualC++6.0

WindowsXPSP2

5.2程序中所有定义的函数

classSyntax_analysis

{

public:

charstotax[30][20];

//存放文法规则

charsoudocu[1000];

//用于存放打开的文件内容

intsto_tax;

//存放产生式总数

charfirstchars[30];

//某个串的first集(可能有重复)

intfirst_num;

//first集长度

charfollowchars[1000];

//存放某个非终结符的follow集(如果有(间接)右递归,可能有较大重复)

intfollow_num;

//follow集长度

intfollownumkey;

//用于判断右递归或间接右递归

charfollowkey;

charselectchars[30][30];

//存放每条产生式的select集

charcolec0[30];

//存入所有能推导出0的非终结符

intcolec0num;

//能推导出0的非终结符个数

charcapital;

//第一个未被使用的大写字母

charpreanatab[130][130][20];

//存放预测分析表,分别为非终结符(将字母转化为数字)、终结符(将字母转化为数字)、产生式

char_stotax[30][20];

//临时的stotax备份

int_sto_tax;

//临时的_sto_tax备份

charstartchar;

//开始文法符号

charkeylr;

charsave[1000];

//保存结果到外存储器

charlie[20];

intli;

charhang[20];

inthan;

intll_key;

intinput_key;

Syntax_analysis(){}

voidopenfile()//打开文件

voidgetin()//对读取出来的文件内容,推导式分解并保存在stotax数组中

voiddisp()//显示方法推导式

voidget_in()//输入推导式,并保存stotax数组中

voidsave_p[])//保存到外存储器

voidDelpare()//消除左递归

voidfindcapital()//查找未被使用的大写字母,把第一个未被使用的大写字母保存在capital中

voidFirst_Collection(charp[])//求字符串p的first集,把结果保存在数组firstchars[30]中

voidFollow_Collection(charp)//求字符p的follow集,把结果保存在数组followchars中

voidSelect_Collection()//求每条产生式的select集,存放在数组selectchars[30][30]中

voidEstab_preanatab()//创建预测分析表

voiddispselect()//显示选择

voidbase_()

voiddisp_table()//打印预测分析表

voidAnalyse_course()//分析过程

voiddeduce0_colec()//将所有能推导出0的非终符放在数组colec0[30]中

voiddispfirst()//显示First集

voiddispfollow()

}

5.3文档说明

文档

文法

句子

a.txt

LL

(1)文法

baabbb#、baaabbbb#....

b.txt

直接左递归

abbbbb(可以任意多少个b)

c.txt

间接左递归

d.txt

maebn#...

5.4调试分析

程序运行说明:

适应的文法类型:

1、一切LL

(1)文法

2、含有直接左递归但可以转化为LL

(1)文法的文法

3、含有间接左递归但可以转化为LL

(1)文法的文法

说明:

1、文法表达方式

例如:

S:

=Aa|Bb,其中空串用数字0代替,每输入一个表达式换行写下一表达式

2、文法输入结束后,换行再按‘#’结束

3、需要输入命令来执行所需要的功能

命令说明:

Cmd命令

功能

open

从外存储器打开某文法

input

从键盘输入文法

lltab

查看预测分析表

select

查看每条产生式的SELECT集

first

求所输串的FIRST集

follow

求所输非终结符的FOLLOW集

ll

对某个输入句子进行分析

exit

退出程序

程序运行主界面:

(1)open:

打开文件

打开附带文档a.txt

a.txt文档中的文法为LL

(1)文法:

(2)input:

输入文法

输入文法过程中“ε”应用“0”代替使用

每输入一条新文法需重新另起一行

文法输入结束后换行以“#”结束

输入文法后若要保存文件,请按“y”键,并按提示输入备份文件的路径和名称。

若没有输入备份路径,文法则保存在默认路径(程序所在文件夹)中;

若不进行保存,则键入除“y”键外的任意键退出当前命令。

打开a.bck.txt文档,可以看到文法:

(3)lltab:

预测分析表

打开文件a.txt,对文档中语法进行分析:

(4)select:

打开文件a.txt,求文档中语法的SELECT集

(5)first:

打开文件a.txt,求文档中语法的FIRST集

若需要继续求FIRST集,则按“y”键继续;

若想退出当前命令,则键入除“y”键外的任意键退出当前命令。

(6)follow:

打开文件a.txt,求文档中语法的FOLLOW集

若需要继续求FOLLOW集,则按“y”键继续;

(7)ll:

打开文件a.txt,输入要分析的字符串进行分析

(8)exit:

推出程序

输入exit命令退出

6课程设计总结

在三周的课程设计中,我设计了一个自顶向下的语法分析器。

由于涉及大量的编译原理知识,且编程过程复杂,代码量大,完成的功能并不是很多,而且也不是很完善,设计过程难免出现或多或少的错误。

由于时间有限,无法对程序进行很好的测试,只发现其中的一些小错误并加以改进和完善,对其他未发现的BUG,只能尽量避免其出现。

倘若有足够多的时间,我相信我可以做出需求分析中要求的功能,使其满足人民的要求,减少人工操作,减少运算时间,避免由于人工计算出现的错误,最终加快人们对语法的分析,减少人们的工作量。

虽然三周的课程设计时间短,但却使我受益匪浅,通过这次课程设计我把课本中的理论转化成实际运用,从中加深了理论认识,为以后的后续学习奠定基础;

并且在编程过程的资料查找和程序编制中掌握了编程的一些基本思路和构想,为以后的程序设计奠定了基础。

参考文献

1、陈火旺,刘春林.《程序设计语言编译原理》(第3版).国防工业出版社.2000年

2、李建中,姜守旭.《编译原理》.机械工业出版社.2003年年12月.

3、(美)阿佩尔,(美)金斯伯格.《现代编译原理:

C语言描述》.人民邮电出版社.2005年09月.

附录:

重要代码

#include"

stdio.h"

string.h"

iostream.h"

ctype.h"

fstream.h"

//存放某个非终结符的follow集(如果有(间接)右递归,可能有较大重复)

charfollowkey;

//第一个未被使用的大写字母

//存放预测分析表,分别为非终结符(将字母转化为数字)、终结符(将字母转化为数字)、产生式

//临时的stotax备份

//临时的_sto_tax备份

//开始文法符号

charkeylr;

charlie[20];

intli;

charhang[20];

inthan;

intll_key;

intinput_key;

Syntax_analysis(){}

voidopenfile()//打开文件

{

input_key=0;

inti=0;

ifstreaminfile;

charpath[255];

cin>

>

path;

in(path);

if(in())

{

while(in())

soudocu[i++]=(char)in();

in();

soudocu[i]='

#'

;

}

else

cout<

<

"

Erroropeningfile"

}

voidgetin()//对读取出来的文件内容,推导式分解并保存在stotax数组中

intcout=0;

charc;

charinterim[50];

inti=0;

sto_tax=0;

again:

c=soudocu[cout++];

while(c!

='

{

if(c!

\n'

{//把一行内容存放在interim数组里

if(c!

'

)interim[i++]=c;

c=soudocu[cout++];

}

else

{

if(!

isupper(interim[0])||interim[1]!

:

'

||interim[2]!

{//如果行首不是以大写字母:

=这种格式,则输出错误信息

printf("

TheSyntaxiswrong!

pleaseenteragain:

\n"

);

i=0;

gotoagain;

}

else

{

//字符数组加结束符

interim[i]='

\0'

intm=0;

for(intj=0;

j<

strlen(interim);

j++)

{//把后选式进行分解成一个个产生式

//如A:

=a|b分解成A:

=a,A:

=b

if(interim[j]!

|'

{

stotax[sto_tax][m++]=interim[j];

continue;

}

else

stotax[sto_tax][m]='

sto_tax++;

stotax[sto_tax][0]=stotax[sto_tax-1][0];

stotax[sto_tax][1]=stotax[sto_tax-1][1];

stotax[sto_tax][2]=stotax[sto_tax-1][2];

m=3;

}

stotax[sto_tax][m]='

sto_tax++;

c=soudocu[cout++];

}

startchar=stotax[0][0];

voiddisp()//显示方法推导式

for(inti=0;

i<

sto_tax;

i++)

cout<

stotax[i]<

endl;

voidget_in()//输入推导式,并保存stotax数组中

if(input_key==0)c=getchar();

input_key=1;

c=getchar();

c=getchar();

{

{

c=getchar();

startchar=stotax[0][0];

intsav=0;

save[sav]='

printf("

saveit?

press'

y'

tosaveorothertocontinue\n"

charcommand[30];

cin>

command;

if(!

strcmp(command,"

y"

))

for(inti=0;

strcat(save,stotax[i]);

sav=strlen(save);

save[sav]='

save[sav+1]='

save_);

charg;

g=getchar();

voidsave_p[])//保存到外存储器

char[30];

Pleaseenterthepathand"

ofstreamofs();

ofs.write(p,strlen(p));

ofs.close();

voidDelpare()//消除左递归

ll_key=0;

keylr=0;

//复制推导式数组

i++)strcpy(_stotax[i],stotax[i]);

_sto_tax=sto_tax;

intkey;

charp[30];

charkey_c;

for(i=0;

_sto_tax;

{//消除直接左递归

key_c=_stotax[i][0];

if(_stotax[i][0]==_stotax[i][3])

{//如果存在直接左递归,则消除

//查找未被使用的大写之母

findcapital();

for(intj=0;

if(_stotax[j][0]==key_c)

keylr=1;

if(_stotax[j][3]==_stotax[j][0])

strcpy(&

_

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

当前位置:首页 > 高中教育 > 数学

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

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