编译原理 语法分析报告2.docx
- 文档编号:10598439
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:25
- 大小:51.77KB
编译原理 语法分析报告2.docx
《编译原理 语法分析报告2.docx》由会员分享,可在线阅读,更多相关《编译原理 语法分析报告2.docx(25页珍藏版)》请在冰豆网上搜索。
编译原理语法分析报告2
昆明理工大学信息工程与自动化学院学生实验报告
(2012—2013学年第一学期)
课程名称:
编译原理开课实验室:
信自楼444年月日
年级
学号
姓名
成绩
实验项目名称
语法分析
指导教师
李亚
教师评语
教师签名:
年月日
一、实验目的:
编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。
二、实验要求:
在上机
(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。
要求编译后能检查出语法错误。
三、实验环境:
vc6.0
四、源代码:
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include
typedefstruct
{
charR;
charr;
intflag;
}array;
arrayF[30];
typedefstruct
{
charE;
chare;
}charLode;
typedefstruct
{
charLode*base;
inttop;
}charstack;
charstr[80][80],arr[80][80],brr[80][80];
intm,kk,p,ppp,FF=1;
charr[20];
intcrr[30][30],FLAG=0;
charccrr1[1][30],ccrr2[30][1];
voidInitstack(charstack*s)
{
s->base=(charLode*)malloc(30*sizeof(charLode));
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;
}
intjudge1(intn)
{
intj=3,flag=1,i;
for(i=0;i<=n;i++)
while(str[i][j]!
='\0')
{
chara=str[i][j];
charb=str[i][j+1];
if(IsLetter(a)&&IsLetter(b))
{
flag=0;
break;
}
else
j++;
}
returnflag;
}
voidjudge2(intn)
{
inti;
for(i=0;i<=n;i++)
if(str[i][3]=='~'||judge1(n)==0||FLAG==1)
{
printf("语法G不是操作符优先级的语法!
\n");
FF=0;
break;
}
if(i>n)
printf("语法G是操作符优先级的语法!
\n");
}
intsearch1(charr[],intkk,chara)
{
inti;
for(i=0;i if(r[i]==a) break; if(i==kk) return0; else return1; } voidcreateF(intn) { intk=0,i=1; charc; intj; chart[10]; t[0]=str[0][0]; while(i<=n) { if(t[k]! =str[i][0]) { k++; t[k]=str[i][0]; i++; } else i++; } kk=0; for(i=0;i<=n;i++) { j=3; while(str[i][j]! ='\0') { c=str[i][j]; if(IsLetter(c)==0) { if(! search1(r,kk,c)) r[kk]=c; kk++; } j++; } } m=0; for(i=0;i for(j=0;j { F[m].R=t[i]; F[m].r=r[j]; F[m].flag=0; m++; } } voidsearch(charLodew) { inti; for(i=0;i if(F[i].R==w.E&&F[i].r==w.e) { F[i].flag=1; break; } } voidFirstVT(intn) { charstacksta; charLodeww; charLodew; inti=0,k; chara,b; Initstack(&sta); while(i<=n) { k=3; w.E=str[i][0]; a=str[i][k]; b=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++; } else i++; } 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; } elseif(str[i][3]==ww.E&&w.E! =ww.E) { w.e=ww.e; push(&sta,w); search(w); break; } } } p=0; k=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) { charstacksta; charLodew; charLodeee; chara,b; intk,i; for(i=0;i F[i].flag=0; i=0; Initstack(&sta); while(i<=n) { intk=strlen(str[i]); w.E=str[i][0]; a=str[i][k-1]; b=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++; } else i++; } 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); } } } k=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; intI,mm,pp,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; I=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)) { 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(j=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)) { 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(mm=1;arr[j][mm]! ='\0';mm++) { for(pp=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)) { 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(mm=1;brr[j][mm]! ='\0';mm++) { for(pp=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++; } } } } } 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; elseif(crr[i][j]==2) return2; elseif(crr[i][j]==1) return1; elsereturn0; } voidprint(chars[],charSTR[][20],intq,intu,intii,intk) { inti; printf("%d\t\t",u); for(i=0;i<=k;i++) printf("%c",s[i]); printf("\t\t"); for(i=q;i<=ii;i++) printf("%c",STR[0][i]); printf("\t\t"); } voidprocess(charSTR[][20],intii) { intk=0,q=0,u=0,b,i,j; chars[40],a; printf("step\t\tcharstack\tinputstring\tAction\n"); s[k]='#'; print(s,STR,q,u,ii,k); printf("ready\n"); k++; u++; s[k]=STR[0][q]; q++; print(s,STR,q,u,ii,k); printf("shift\n"); while(q<=ii) { a=STR[0][q]; if(! IsLetter(s[k])) j=k; else j=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]='G';u++; print(s,STR,q,u,ii,k); printf("减小\n"); } 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]=='#') printf("shift\n"); else printf("接受\n"); } else { printf("错误\n"); break; } } if(s[0]=='#'&&s[1]=='N'&&s[2]=='#') printf("还原成功\n"); else printf("还原失败\n"); } voidmain() { intn,i,j,o; intii; printf("请输入定义的语法G的数量: "); scanf("%d",&n); printf("请输入语法G"); printf("\n"); for(i=0;i { scanf("%s",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]='#'; str[i][6]='\0'; printf("你定义的风格如下: \n"); for(i=0;i<=n;i++) printf("%s\n",str[i]); if(judge1(n)==0) printf(语法G不是操作符语法! \n"); if(judge1(n)==1) { printf("语法G是操作符优先级语法! \n"); createF(n); FirstVT(n); LastVT(n); createYXB(n); } judge2(n); if(FLAG==0) { for(i=0;i<=p;i++) { printf("FirstVT(%c)={",arr[i][0]); for(o=1;arr[i][o+1]! ='\0';o++) printf("%c,",arr[i][o]); printf("%c}\n",arr[i][o]); } } printf("FirstVT(Q)={#}\n"); for(i=0;i<=ppp;i++) { printf("LastVT(%c)={",arr[i][0]); for(o=1;brr[i][o+1]! ='\0';o++) printf("%c,",brr[i][o]); printf("%c}\n",brr[i][o]); } printf("LastVT(Q)={#}\n"); printf("优先表如下: \n"); for(i=1;i { printf(""); printf("%c",ccrr1[0][i]); } printf("\n"); for(i=1;i { printf("%c",ccrr2[i][0]); for(j=1;j { if(crr[i][j]==0) printf(""); elseif(crr[i][j]==1) printf("="); elseif(crr[i][j]==2) printf("<"); elseif(crr[i][j]==3) printf(">"); printf(""); } printf("\n"); } if(FF==1) { charSTR[1][20]; printf("请输入字符串的法令: \n"); scanf("%s",STR[0]); //getchar(); //gets(STR[0]); ii=strlen(STR[0]); STR[0][ii]='#'; printf("分析如下: \n"); process(STR,ii); } } 五、实验内容(算法及运行结果的截图) 六、实验总结(程序的优缺点,不足和改进的过程) 用预先分析法进行语法分析,基本思路是: (1)首先初始化分析栈和输入单词指示器(即读取当前输入串中的第一个单词); (2)然后查看当前分析栈的栈顶符号: ①如果是终结符号,则查看是否与当前输入单词匹配,若匹配则将之出栈,输入指示器指向下一个单词,进行下一轮扫描,若不匹配则报错,②如果是非终结符号,则根据当前输入单词查找分析表,若查到,则将当前栈顶符号出栈,并将查到的产生式逆序入栈,进入下一轮扫描,若没有查到,则报错;(3)最后,若分析栈和输入单词同时为结束符(#)时,表示语法分析成功,程序结束。 对语法分析中的错误处理和识别有很多问题,如某些错误可能导致程序进入死循环,因此在语法错误处理方面仍有待改进程序中对文件的操作仍一些不足之处,如: 若关闭输入文件时失败,则会导致输出文件也无法关闭,占用系统资源。 另外,此程序只是对语法分析过程的一个演示,当真正进编译程序的编制时,需要配合专门的语法错误处理程序和中间代码转换程序等进行编译。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理 语法分析报告2 编译 原理 语法分析 报告