天津理工大学编译实验语法分析.docx

上传人:b****4 文档编号:11533098 上传时间:2023-03-18 格式:DOCX 页数:22 大小:64.67KB
下载 相关 举报
天津理工大学编译实验语法分析.docx_第1页
第1页 / 共22页
天津理工大学编译实验语法分析.docx_第2页
第2页 / 共22页
天津理工大学编译实验语法分析.docx_第3页
第3页 / 共22页
天津理工大学编译实验语法分析.docx_第4页
第4页 / 共22页
天津理工大学编译实验语法分析.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

天津理工大学编译实验语法分析.docx

《天津理工大学编译实验语法分析.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译实验语法分析.docx(22页珍藏版)》请在冰豆网上搜索。

天津理工大学编译实验语法分析.docx

天津理工大学编译实验语法分析

实验报告

学院(系)名称:

计算机与通信工程学院

姓名

*****

学号

*****

专业

计算机科学与技术

班级

2011级*班

实验项目

实验二:

语法分析

课程名称

编译原理

课程代码

0668056

实验时间

2014年4月18日第5、8节

2011年4月25日第7、8节

实验地点

计算机软件实验室7-215

批改意见

成绩

 

教师签字:

实验内容:

可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法分析器:

(1)E→E+T|E-T|T

(2)T→T*F|T/F|F

(3)F→P^F|P

(4)P→(E)|i

实验目的:

1.掌握语法分析的基本概念和基本方法;

2.正确理解LL1分析法、算符优先分析法、LR分析法的设计与使用方法。

实验要求:

1.按要求设计实现能识别上述文法所表示语言的语法分析器,并要求输出全部分析过程;

2.要求详细描述所选分析方法针对上述文法的分析表构造过程;

3.完成对所设计语法分析器的功能测试,并给出测试数据和实验结果;

4.为增加程序可读性,请在程序中进行适当注释说明;

5.整理上机步骤,总结经验和体会;

6.认真完成并按时提交实验报告。

【实验过程记录(源程序、测试用例、测试结果及心得体会等)】

#include

#include

#include

typedefstruct

{

charR;

charr;

intflag;

}array;

typedefstruct

{

charE;

chare;

}charLode;

typedefstruct

{

charLode*base;

inttop;

}charstack;

charstr[80][80],arr[80][80],brr[80][80];

arrayF[20];

intm,kk,p,ppp,FF=1;

charr[10];

intcrr[20][20],FLAG=0;

charccrr1[1][20],ccrr2[20][1];

 

voidInitstack(charstack&s)//定义栈

{

s.base=newcharLode[20];

s.top=-1;

}

voidpush(charstack&s,charLodew)//入栈

{

s.top++;

s.base[s.top].E=w.E;

s.base[s.top].e=w.e;

}

voidpop(charstack&s,charLode&w)//出栈

{

w.E=s.base[s.top].E;

w.e=s.base[s.top].e;

s.top--;

}

intIsEmpty(charstacks)//判断是否到栈顶

{

if(s.top==-1)

return1;

else

return0;

}

intIsLetter(charch)//判断是不是大写字母(非终结符)

{

if(ch>='A'&&ch<='Z')

return1;

else

return0;

}

//judge1判断是否是算符文法

intjudge1(intn)

{

intj=3,flag=0;

for(inti=0;i<=n;i++)

while(str[i][j]!

='\0')

{

chara=str[i][j];

charb=str[i][j+1];

if(IsLetter(a)&&IsLetter(b))//两个非终结符相连,不是算符文法

{

flag=1;

break;

}

else

j++;

}

if(flag==1)//根据flag设定返回值

return0;

else

return1;

}

//judge2是判断文法G是否为算符优先文法

voidjudge2(intn)

{

for(inti=0;i<=n;i++)

if(str[i][3]=='~'||FLAG==1)//'~'代表空

{

cout<<"文法G不是算符优先文法!

"<

FF=0;

break;

}

if(i>n)

cout<<"文法G是算符优先文法!

"<

}

//search1是查看存放终结符的数组r中是否含有重复的终结符

intsearch1(charr[],intkk,chara)

{

for(inti=0;i

if(r[i]==a)

break;

if(i==kk)

return0;

else

return1;

}

//createF函数是用F数组存放每个终结符与非终结符和组合

voidcreateF(intn)

{

intk=0,i=1;charg;

chart[10];//t数组用来存放非终结符

t[0]=str[0][0];

while(i<=n)

{

if(t[k]!

=str[i][0])

{

k++;

t[k]=str[i][0];

g=t[k];

i++;

}

elsei++;

}

kk=0;

charc;

for(i=0;i<=n;i++)

{

intj=3;

while(str[i][j]!

='\0')

{

c=str[i][j];

if(IsLetter(c)==0)

{

if(!

search1(r,kk,c))

r[kk]=c;

kk++;//r数组用来存放终结符

}

j++;

}

}

m=0;

for(i=0;i

for(intj=0;j

{

F[m].R=t[i];

F[m].r=r[j];

F[m].flag=0;

m++;

}

}

//search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1

voidsearch(charLodew)

{

for(inti=0;i

if(F[i].R==w.E&&F[i].r==w.e)

{

F[i].flag=1;break;

}

}

voidFirstVT(intn)//求FirstVT

{

charstacksta;

charLodew;

inti=0;

Initstack(sta);

while(i<=n)

{

intk=3;

w.E=str[i][0];

chara=str[i][k];

charb=str[i][k+1];

if(!

IsLetter(a))//产生式的后选式的第一个字符就是终结符的情况

{

w.e=a;

push(sta,w);

search(w);

i++;

}

elseif(IsLetter(a)&&b!

='\0'&&!

IsLetter(b))

//产生式的后选式的第一个字符是非终结符的情况

{

w.e=b;

push(sta,w);

search(w);

i++;

}

elsei++;

}

charLodeww;

while(!

IsEmpty(sta))

{

pop(sta,ww);

for(i=0;i<=n;i++)

{

w.E=str[i][0];

if(str[i][3]==ww.E&&str[i][4]=='\0')

{

w.e=ww.e;

push(sta,w);

search(w);

break;

}

}

}

p=0;intk=1;i=1;

while(i

{

if(F[i-1].flag==1)

{

arr[p][0]=F[i-1].R;

arr[p][k]=F[i-1].r;

}

while(F[i].flag==0&&i

i++;

if(F[i].flag==1)

{

if(F[i].R==arr[p][0])

k++;

else{arr[p][k+1]='\0';p++;k=1;}

i++;

}

}

}

voidLastVT(intn)//求LastVT

{

charstacksta;

charLodew;

for(inti=0;i

F[i].flag=0;

i=0;

Initstack(sta);

while(i<=n)

{

intk=strlen(str[i]);

w.E=str[i][0];

chara=str[i][k-1];

charb=str[i][k-2];

if(!

IsLetter(a))

{

w.e=a;

push(sta,w);

search(w);

i++;

}

elseif(IsLetter(a)&&!

IsLetter(b))

{

w.e=b;

push(sta,w);

search(w);

i++;

}

elsei++;

}

charLodeee;

while(!

IsEmpty(sta))

{

pop(sta,ee);

for(i=0;i<=n;i++)

{

w.E=str[i][0];

if(str[i][3]==ee.E&&str[i][4]=='\0')

{

w.e=ee.e;

push(sta,w);

search(w);

}

}

}

intk=1;i=1;

ppp=0;

while(i

{

if(F[i-1].flag==1)

{

brr[ppp][0]=F[i-1].R;

brr[ppp][k]=F[i-1].r;

}

while(F[i].flag==0&&i

i++;

if(F[i].flag==1)

{

if(F[i].R==arr[ppp][0])

k++;

else{brr[ppp][k+1]='\0';ppp++;k=1;}

i++;

}

}

}

voidcreateYXB(intn)//构造优先表

{

inti,j;

for(j=1;j<=kk;j++)

ccrr1[0][j]=r[j-1];

for(i=1;i<=kk;i++)

ccrr2[i][0]=r[i-1];

for(i=1;i<=kk;i++)

for(j=1;j<=kk;j++)

crr[i][j]=0;

intI=0,J=3;

while(I<=n)

{

if(str[I][J+1]=='\0')//扫描右部

{

I++;

J=3;

}

else

{

while(str[I][J+1]!

='\0')

{

charaa=str[I][J];

charbb=str[I][J+1];

if(!

IsLetter(aa)&&!

IsLetter(bb))//优先及等于的情况,用1值表示等于

{

for(i=1;i<=kk;i++)

{

if(ccrr2[i][0]==aa)

break;

}

for(j=1;j<=kk;j++)

{

if(ccrr1[0][j]==bb)

break;

}

if(crr[i][j]==0)

crr[i][j]=1;

else{

FLAG=1;

I=n+1;

}

J++;

}

if(!

IsLetter(aa)&&IsLetter(bb)&&str[I][J+2]!

='\0'&&!

IsLetter(str[I][J+2]))

//优先及等于的情况

{

for(i=1;i<=kk;i++)

{

if(ccrr2[i][0]==aa)

break;

}

for(intj=1;j<=kk;j++)

{

if(ccrr1[0][j]==str[I][J+2])

break;

}

if(crr[i][j]==0)

crr[i][j]=1;

else

{

FLAG=1;

I=n+1;

}

}

if(!

IsLetter(aa)&&IsLetter(bb))

//优先及小于的情况,用2值表示小于

{

for(i=1;i<=kk;i++)

{

if(aa==ccrr2[i][0])

break;

}

for(j=0;j<=p;j++)

{

if(bb==arr[j][0])

break;

}

for(intmm=1;arr[j][mm]!

='\0';mm++)

{

for(intpp=1;pp<=kk;pp++)

{

if(ccrr1[0][pp]==arr[j][mm])

break;

}

if(crr[i][pp]==0)

crr[i][pp]=2;

else{

FLAG=1;I=n+1;

}

}

J++;

}

if(IsLetter(aa)&&!

IsLetter(bb))

//优先及大于的情况,用3值表示大于

{

for(i=1;i<=kk;i++)

{

if(ccrr1[0][i]==bb)

break;

}

for(j=0;j<=ppp;j++)

{

if(aa==brr[j][0])

break;

}

for(intmm=1;brr[j][mm]!

='\0';mm++)

{

for(intpp=1;pp<=kk;pp++)

{

if(ccrr2[pp][0]==brr[j][mm])

break;

}

if(crr[pp][i]==0)

crr[pp][i]=3;

else{FLAG=1;I=n+1;}

}

J++;

}

}

}

}

}

 

//judge3是用来返回在归约过程中两个非终结符相比较的值

intjudge3(chars,chara)

{

inti=1,j=1;

while(ccrr2[i][0]!

=s)

i++;

while(ccrr1[0][j]!

=a)

j++;

if(crr[i][j]==3)

return3;

else

if(crr[i][j]==2)

return2;

else

if(crr[i][j]==1)

return1;

else

return0;

}

voidprint(chars[],charSTR[][20],intq,intu,intii,intk)//打印归约的过程

{

cout<

for(inti=0;i<=k;i++)

cout<

cout<<"";

for(i=q;i<=ii;i++)

cout<

cout<<"";

}

voidprocess(charSTR[][20],intii)//对输入的字符串进行归约的过程

{

//cout<<"步骤"<<""<<"符号栈"<<""<<"输入串"<<""<<"动作"<

intk=0,q=0,u=0,b,i,j;

chars[40],a;

s[k]='#';

print(s,STR,q,u,ii,k);

cout<<"预备"<

k++;

u++;

s[k]=STR[0][q];

q++;

print(s,STR,q,u,ii,k);

cout<<"移进"<

while(q<=ii)

{

a=STR[0][q];

if(!

IsLetter(s[k]))j=k;

elsej=k-1;

b=judge3(s[j],a);

if(b==3)//大于的情况进行归约

{

while(IsLetter(s[j-1]))

j--;

for(i=j;i<=k;i++)

s[i]='\0';

k=j;

s[k]='N';

u++;

print(s,STR,q,u,ii,k);

cout<<"归约"<

}

elseif(b==2||b==1)//小于或等于的情况移进

{

k++;

s[k]=a;

u++;

q++;

print(s,STR,q,u,ii,k);

if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')

cout<<"接受"<

elsecout<<"移进"<

}

else

{

cout<<"出错"<

break;

}

}

if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')

cout<<"归约成功"<

elsecout<<"归约失败"<

}

voidmain()

{

intn,i,j;

cout<<"输入定义的文法G的产生式的个数n:

";

cin>>n;

cout<<"输入文法产生式:

"<

for(i=0;i

{

gets(str[i]);

j=strlen(str[i]);

str[i][j]='\0';

}

str[i][0]='Q';//最末行添加扩展

str[i][1]='-';

str[i][2]='>';

str[i][3]='#';

str[i][4]=str[0][0];

str[i][5]='#';

cout<<"你定义的产生式如下:

"<

str[i][6]='\0';

for(i=0;i<=n;i++)

cout<

if(judge1(n)==0)//判断文法G是否为算符文法

cout<<"文法G不是算符文法!

"<

if(judge1(n)==1)

{

cout<<"文法G是算符文法!

"<

}

createF(n);

FirstVT(n);

LastVT(n);

createYXB(n);

for(i=0;i<=p;i++)//打印FirstVT

{

cout<<"FirstVT("<

for(intl=1;arr[i][l+1]!

='\0';l++)

cout<

cout<

}

cout<<"FirstVT(Q)={#}"<

for(i=0;i<=ppp;i++)//打印LastVT

{

cout<<"LastVT("<

for(intl=1;brr[i][l+1]!

='\0';l++)

cout<

cout<

}

cout<<"LastVT(Q)={#}"<

cout<<"算符优先表如下:

"<

for(i=1;i

{

cout<<"";

cout<

}

cout<

for(i=1;i

{

cout<

for(j=1;j

{

if(crr[i][j]==0)

cout<<"";

elseif(crr[i][j]==1)

cout<<"=";

elseif(crr[i][j]==2)

cout<<"<";

elseif(crr[i][j]==3)

cout<<">";

cout<<"";

}

cout<

}

judge2(n);//判断文法G是否为算符优先文法

if(FF==1)

{

charSTR[1][20];

cout<<"请输入要规约的字符串:

"<

gets(STR[0]);

intii=strlen(STR[0]);

STR[0][ii]='#';

cout<<"语法分析过程如下:

"<

process(STR,ii);

}

}

你定义的文法产生式如下:

算符优先分析表如下:

语法分析过程如下:

 

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

当前位置:首页 > 经管营销 > 经济市场

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

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