编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx

上传人:b****5 文档编号:19552241 上传时间:2023-01-07 格式:DOCX 页数:32 大小:25.04KB
下载 相关 举报
编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx_第1页
第1页 / 共32页
编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx_第2页
第2页 / 共32页
编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx_第3页
第3页 / 共32页
编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx_第4页
第4页 / 共32页
编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx

《编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx(32页珍藏版)》请在冰豆网上搜索。

编译原理课程设计LL文法分析器设计C++语言实现Word文档下载推荐.docx

A…,则称该文法是左递归的。

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

●直接左递归

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

消除直接左递归的方法:

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

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

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

A→βA′

A′→αA′|ε

●间接左递归

若文法中存在某一非终结符A,使得A?

A…至少需要两步推导,则称该文法是间接左递归的。

消除间接左递归的方法:

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

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

设有文法G10[S]:

S→Aα|β⑴

A→Sγ⑵

因为S?

Aα?

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

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

S→Sγα|β⑶

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

S→βS′

S′→γαS′|ε

2.计算First集

(1)若X∈VT,则First(X)={X}

(2)若X∈VN,且有产生式X→a…,a∈VT则First(X)={X}

(3)若X∈VN,且有产生式X→ε,则First(X)={X}

(4)若X,Y1,Y2,…,Yn都∈VN,而由产生式X→Y1Y2…Yn。

当Y1,Y2,…,Yi-1都能推导出ε时,(其中1≤i≤n),则First(Y1)-{ε},First(Y2)-{ε},…,First(Yi)都包含在First(X)中

(5)当(4)中所有Yi都能推导出ε,(i=1,2,…,n),则First(X)=First(Y1)∪First(Y2)∪…First(Yn)∪{ε}

反复使用上述步骤直到每个符合的First集合不再增大为止。

3.计算Follow集

对文法中的每个A∈VN,计算Follw(A):

(1)设S为文法的开始符合,把{#}加入Follow(S)中;

(2)若A→αBβ是一个产生式,则把First(β)的非空元素加入Follow(B)中,如果β能推导出ε,则把Follow(A)也加入(B)中;

(3)反复使用以上步骤直到每个非终结符号的Follow集不再增大为止。

4.预测分析方法

预测分析方法是自顶向下分析的另一种方法,一个预测分析器是由三个部分组成:

预测分析程序;

先进后出栈;

预测分析表。

预测分析程序的框图如下:

1系统分析1

1.1选题要求1

1.2预期目标1

2.程序流程图1

2.1总流程图1

2.2First集和Follow集2

2.3预测分析表流程3

3.代码编写3

3.1检查左递归3

3.2first集合5

3.3follow集合6

3.4分析表输出8

4.程序调试10

5.总结11

6.指导教师评语12

7.源码13

正文:

1.系统分析

1.1选题要求

根据某一文法编制调试LL

(1)文法语法分分析程序,以便对任意输入的符号串进行分析。

1.2预期目标

构造LL

(1)文法语法分析程序,任意输入一个文法符号串,并判断它是否为文法的一个句子。

程序要求为该文法构造预测分析表,并按照预测分析算法对输入串进行语法分析,判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。

2.程序流程图

2.1.总流程图

2.2.First集和Follow集的流程图

2.3.预测分析表流程:

3.代码编写

3.1检查左递归:

Parser&

Parser:

:

DelLeft(inti)

{

intn=StrNum(content[i]);

charc=RandChar();

charz=content[i][0];

ints=0;

for(intk=1;

k<

=n;

k++)

{

stringtmp=GetSub(k,content[i],'

|'

);

if(z==tmp[0])s=1;

}

if(s==0)return*this;

cout<

<

"

文法句"

content[i]<

含有直接左递归,"

;

while

(1)

if(Findchar(c,non)==-1)break;

elsec=RandChar();

随机产生非终结符为:

c<

endl;

non.append(1,c);

stringtemp;

temp+=z;

temp+="

->

stringnext;

next+=c;

next+="

stringt=GetSub(k,content[i],'

if(z==t[0])

t.erase(0,1);

t+=c;

next+=t;

next+='

else

if(t=="

^"

)t.clear();

temp+=t;

temp+='

^'

temp.erase(temp.size()-1,1);

content[i]=temp;

num=num+1;

content[num]=end;

for(intj=num-1;

j>

i;

j--)

content[j]=content[j-1];

content[i+1]=next;

return*this;

}

3.2first集合

stringParser:

First(charx)

stringch="

if(Findchar(x,ter)!

=-1)

{ch.append(1,x);

ch.append(1,'

'

elseif(Findchar(x,non)!

=-1)

inti=Findid(x);

if(i!

stringq=content[i];

unsignedintk=3;

while(k<

q.size())

if(q[k-1]=='

||k==3)

if(Findchar(q[k],ter)!

=-1||q[k]=='

ch.append(1,q[k]);

}else

if(k==3||q[k+1]=='

||k==q.size()-1)ch+=First(q[k]);

stringtemp=First(q[k-1]);

if(Findchar('

temp)!

=-1)ch+=First(q[k]);

k++;

}

elsek++;

returnch;

3.3follow集合

Follow(charx)

{

stringch;

if(Findchar(x,non)!

if(!

Findid(x))

ch+="

$"

ch+='

inti=0;

while(i<

num)

charc=content[i][0];

while(q[k]==x)

if(k<

q.size()-1&

&

q[k+1]!

='

stringtemp=Delchar('

First(q[k+1]));

if(ch.find(temp)==string:

npos)ch+=temp;

First(q[k+1]))!

{

stringfollow_c=Follow(c);

if(ch!

=follow_c&

ch.find(follow_c)==std:

string:

npos)

ch+=follow_c;

elseif(k==q.size()-1)

if(ch.find(follow_c)==std:

npos)ch+=follow_c;

i++;

3.4分析表输出

intParser:

Analysis()

stack.append("

charchose;

是否输入分析串(yorn):

cin>

>

chose;

while(chose=='

y'

stack+=non[0];

cout<

请输入分析串<

退出(q)>

cin>

instack;

if(instack=="

q"

)exit(0);

if(instack[instack.size()-1]!

$'

)instack+="

intk=1,flag=0;

charx=Top();

charc=Ip();

分析栈\t当前输入\t动作"

while(x!

{

x=Top();

c=Ip();

cout<

stack<

\t"

instack<

\t\t"

if(Findchar(x,ter)!

{

if(Mate(x,c))

{

k++;

cout<

匹配"

}

else

{

["

]出错(终结符不匹配)!

flag=1;

if(x=='

)'

)Pop();

elseinstack.erase(0,1);

}

elseif(Findchar(x,non)!

intidf=Findchar(x,non);

intidz=Findchar(c,ter);

if(idz==-1)idz=int(ter.size());

stringtemp=table[idf][idz];

if(temp.empty())

]出错("

不属于FIRST("

x<

))!

instack.erase(0,1);

Pop();

if(temp!

="

{

Push(temp);

cout<

temp<

}

elsecout<

elseif(x=='

c=='

if(flag==0)cout<

正确"

elsecout<

错误"

else

cout<

]出错(未能识别的字符)!

flag=1;

instack.erase(0,1);

}

4.程序调试

导入正确的文法:

符合文法的串

不符合文法的串

导入有左递归的文法:

串分析:

总结

通过这次课程设计,对于LL1文法的认识有了进一步的提升,特别是对于FIRST集合和FOLLOW集合的求取,前面对于求取者两个集合理解还不是很好,经过这次课程设计,逐渐理解了求解的过程,并且懂得了如何通过代码,自动生成某LL1文法的FIRST集合和FOLLOW集合,在刚开始做时,根本不知道求,通过网上查找资料,同学的请教,慢慢地懂得了如何做,最终正确地求出FIRST集合和FOLLOW集合。

并且能够使用者两个集合构建预测分析表以及对一段输入的串进行分析是否是该文法的串,出错的地方能够做出错处理,总的来说,完成了课程设计要求的大部分内容,对于GUI的使用没有能够实现,暴露了自身在这方面的不足,需要在以后的学习和工作中进行沉入学习提高。

在实现的功能中还有存在着,对于不含直接左递归的文法没法正确找出,提示错误。

在判断是否是LL1文法上还有很大的不足,没法使用代码实现当两个FIRST有存在交集判断不是LL1文法的功能,这点要求自己对于代码的编程能力有着必要的提高。

这次课程设计使用C++来实现LL1文法分析的功能,自己对于C++语言的使用有了很大的提高。

特别是对于一些C++的语法要求,有了很大的认识。

但存在的不足还是比较多的。

都是需要在今后的学习中认真总结,以使自己能更好地语言的使用,提升自身的技能。

这次课程设计总的收获是不少的。

每一次的实践都是提高自身能力的机会,在今后的生活中,要抓住实践的机会,实践是验证真理最好的途径。

对于一个计算机专业的学生来说,更应该注重实践的机会,只有实践多了,一些理论知识才能被自己正真的认识,不然,值懂理论,没有对于正确性进行验证,还是会有问题的,特别是计算机机器,总存在未知的错误,只有不断地探索,才能更好地去使用我们的工具。

指导教师评语

学号

姓名

班级

选题

名称

序号

评价内容

权重(%)

得分

1

考勤记录、学习态度、工作作风与表现。

5

2

自学情况:

上网检索机时数、文献阅读情况(笔记)。

10

3

论文选题是否先进,是否具有前沿性或前瞻性。

4

成果验收:

是否完成设计任务;

能否运行、可操作性如何等。

20

报告的格式规范程度、是否图文并茂、语言规范及流畅程度;

主题是否鲜明、重心是否突出、论述是否充分、结论是否正确;

是否提出了自己的独到见解。

30

6

文献引用是否合理、充分、真实。

7

答辩情况:

自我陈述、回答问题的正确性、用语准确性、逻辑思维、是否具有独到见解等。

25

合计

指导教师(签章):

年月日

源码:

LL1.h

#include<

iostream>

cstring>

cstdlib>

fstream>

usingnamespacestd;

classParser

public:

Parser();

Parser(constParser&

friendostream&

operator<

(ostream&

output,constParser&

rs);

friendistream&

operator>

(istream&

input,Parser&

intFindid(char);

intCheck();

stringCheckstr(string&

stringDelchar(char,string);

intFindchar(char,string);

intStrNum(conststring&

charRandChar();

stringGetSub(int,conststring&

char);

Parser&

DelLeft(int);

stringFirst(char);

stringFirst(conststring&

stringFollow(char);

FirstAndFollow();

CreateTable();

~Parser();

charPop();

intMate(char,char);

charTop();

charIp();

Push(conststring&

intAnalysis();

private:

intnum;

stringter,non,end,stack,instack;

string*content;

string*first;

string*follow;

string**table;

};

LL1.cpp

#include"

LL1.h"

Parser:

Parser()

content=newstring[255];

first=newstring[255];

follow=newstring[255];

table=newstring*[255];

Parser(constParser&

rs)

ter=rs.ter;

non=rs.non;

end=rs.end;

num=rs.num;

for(inti=0;

i<

=num;

i++)

content[i]=rs.content[i];

ostream&

output<

文法内容(共"

rs.num<

条):

rs.num)

output<

rs.content[i++]<

结终符:

rs.ter<

非结终符:

rs.non<

非终结符的FIRST集合"

for(unsignedintj=0;

j<

rs.non.size();

j++)

FIRST("

rs.non[j]<

)={"

rs.first[j]<

}\t"

非终结符的FOLLOW集合"

FOLLOW("

rs.follow[j]<

预测分析表:

endl<

rs.ter.size();

rs.ter[j]<

for(unsignedintk=0;

=rs.ter.size();

rs.table[j][k]<

returnoutput;

istream&

unsignedintj=0;

charfilename[255];

请输入文件名:

input>

filename;

ifstreaminfile(filename,ios:

in);

infile){

无法打开文件!

exit(0);

unsignedinti=0;

infile>

rs.end;

rs.content[j++]=rs.end;

if(infile.eof())break;

while(i<

rs.end.size())

if(rs.end[i]=='

||rs.end[i]=='

elseif(i==1||i==2)i++;

elseif(rs.end[i]>

A'

rs.end[i]<

Z'

){

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

当前位置:首页 > 工程科技 > 交通运输

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

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