ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:26.41KB ,
资源ID:4386441      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4386441.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(编译原理之OPG实验报告.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

编译原理之OPG实验报告.docx

1、编译原理之OPG实验报告编译原理之算符优先文法分析*学院1105班安雨雅 班级:11* 学号:11*实验 语法分析实验报告1、实验题目 算符优先文法分析程序2、实验内容及要求(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕和文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:(OPG文件中还有其他文法可作为测试)BBoT|TTTaF|FFnF|(B)|t|f(4)分析的句子为: ntofat#3、设计思想之重点:v 构造算符优先表:求FirstVT集和LastV

2、T集判断是否是算符文法判断是否是算符优先文法v 算符优先分析: 、求最左素短语、根据算符优先分析表分析 (“”时归约)4、程序源代码(C语言)#include stdio.h#include string.h#include stdlib.h#define STR_MAX 80 /串的最大长度#define MAX_NUM 100 /符号的最大个数#define MAX 32767 /文件中符号的最大个数#define N 20 /栈的长度class stack /符号栈 private: char sN; int top; public: stack(); void push(char);

3、void pop(); int TOP(); /返回top的值 char *S(); /返回s的值;stack:stack() top=-1; void stack:push(char ch) /进栈操作 s+top=ch; stop+1=0; void stack:pop() /出栈操作 top-; int stack:TOP() /返回top的值 return top; char * stack:S() /返回s的值 return s; char MMAX_NUMMAX_NUM;struct PRO /产生式类型 char left; char rightSTR_MAX;struct VN

4、stru char vn; char firstVTMAX_NUM; char lastVTMAX_NUM;char SOURSTR_MAX; /源文件名char OBJSTR_MAX; /目标文件名char ERRSTR_MAX; /错误信息文件名FILE *INF; /源程序文件指针FILE *OUTF; /分析结果文件指针FILE *ERRF; /错误信息文件指针char OGMAX; /存放上下文无关文法int OGlen; /上下文无关文法长度VNstru VNMAX_NUM; /非终结符数组int VN_CNT; /非终结符个数char VTMAX_NUM; /终结符数组int V

5、T_CNT; /终结符个数char S0; /开始符号PRO PMAX_NUM; /产生式数组int P_CNT; /产生式个数bool isIN(char ch,VNstru arr); /判别符号ch是否在arr数组中int isVN(char ch); /判别符号ch是否在VN数组中,存在则返回下标,否则返回-1int isVT(char ch); /判别符号ch是否在VT数组中,存在则返回下标,否则返回-1void getOG(); /从源文件取得OG文法串void getVN_VT_S_P(); /从OG文法提取VN,VT,S,Pvoid FirstVT(char ch,char f

6、irstVT); /求FirstVT集firstVTvoid LastVT(char ch,char lastVT); /求LastVT集lastVTbool O_G(); /判别是否是OG文法bool O_P_G(); /判别是否是OPG文法void leftphase(char str,char substr,char a); /求最左素短语substrvoid left_str(char w,char subw,int ip); /求剩余输入串subw bool isIN(char ch,VNstru arr) /判别符号ch是否在arr数组中 for(int i=0;iVN_CNT;i

7、+) if(ch=arri.vn) return 1; return 0;int isVN(char ch) /判别符号ch是否在VN数组中,存在则返回下标,否则返回-1 for(int i=0;iVN_CNT;i+) if(ch=VNi.vn) return i; return -1;int isVT(char ch) /判别符号ch是否在VT数组中,存在则返回下标,否则返回-1 for(int i=0;iVT_CNT;i+) if(ch=VTi) return i; return -1;void getOG() /从源文件取得OG文法串 OGlen=0; char ch; while(!f

8、eof(INF) ch=fgetc(INF); if(ch!= ) OGOGlen+=ch; OGOGlen=0; printf(The Grammar is :n); /将文法输出到屏幕 puts(OG); fprintf(OUTF,The Grammar is :n); fputs(OG,OUTF); /将文法输出到文件void getVN_VT_S_P() /从OG文法提取VN,VT,S,P VN_CNT=0; VT_CNT=0; P_CNT=0; int newPF=0; /是否进入新产生式的标志 int rightLen=0; char prech,ch,nextch; for(in

9、t i=0;iOGlen;i+) if(i!=0) prech=OGi-1; /取文法文件中的前一个符号 ch=OGi; /取文法文件中的当前符号 nextch=OGi+1; /取文法文件中的下一个符号 if(nextch=) /下一个符号是,代表箭头 if(isVN(ch)=-1) /当前符号不是已经识别到的VN VNVN_CNT.vn=ch; /加入VN VN_CNT+; PP_CNT.left=ch; /记入新产生式的左部 if(P_CNT=0) S0=ch; /第一条产生式的左部是开始符号 i+; /跳过 if(prech=|prech=|) newPF=1; /进入新的产生式 rig

10、htLen=0; if(newPF=1) PP_CNT.rightrightLen+=ch; if(nextch=n|nextch=|) newPF=0; /一条产生式结束 P_CNT+; /产生式个数加1 PP_CNT.left=PP_CNT-1.left; i+; /跳过回车和 | for(int j=0;jOGlen;j+) ch=OGj; if(ch!=&ch!=|&ch!=n&isVN(ch)=-1&isVT(ch)=-1&ch!= ) VTVT_CNT+=ch; VTVT_CNT+=#; VTVT_CNT=0; /输出VN printf(nVN:t); fprintf(OUTF,n

11、VN:t); for(int x=0;xVN_CNT;x+) printf(%c,VNx.vn); fprintf(OUTF,%c,VNx.vn); /输出VT printf(nVT:t%sn,VT); fprintf(OUTF,nVT:t%sn,VT); /输出S printf(S0:t%cnn,S0); fprintf(OUTF,S0:%cnn,S0); /输出P for(int k=0;k%sn,k,Pk.left,Pk.right); fprintf(OUTF,P%d:t%c-%sn,k,Pk.left,Pk.right); printf(n); fprintf(OUTF,n);/()

12、或 int f=0; void FirstVT(char ch,char firstVT)/求非终结符的FirstVT集,存至firstVT中 if(isIN(ch,VN) for(int i=0;ib. if(isVT(a)!=-1) firstVTf+=a; firstVTf=0; /B-Cb. if(isVN(a)!=-1 & isVT(Pi.rightj+1)!=-1) firstVTf+=Pi.rightj+1; firstVTf=0; /B-C,C-b.|Db. if(isVN(a)!=-1 & strlen(Pi.right)=1) FirstVT(a,firstVT); f=0

13、; /f清零,便于重复调用此函数/()或 int l=0; void LastVT(char ch,char lastVT) /求非终结符的LastVT集,存放至lastVT中 if(isIN(ch,VN) for(int i=0;i.a; if(isVT(a)!=-1) lastVTl+=a; lastVTl=0; /B-.aC; if(isVN(a)!=-1 & isVT(Pi.rightj-1)!=-1) lastVTl+=Pi.rightj-1; lastVTl=0; /B-C,C-.a|.aD; if(isVN(a)!=-1 & j=0) LastVT(a,lastVT); l=0;

14、 /l清零,便于重复调用此函数 bool O_G() /判别是否是OG文法 没有两个连续的非终结符,即形如A-.BC.的产生式 /求所有非终结符的firstVT集 for(int i=0;iVN_CNT;i+) char fvtSTR_MAX; FirstVT(VNi.vn,fvt); strcpy(VNi.firstVT,fvt); printf(FirstVT(%c)= ,VNi); fprintf(OUTF,FirstVT(%c)= ,VNi); for(int j=0;j(int)strlen(fvt);j+) printf(%c ,fvtj); fprintf(OUTF,%c ,fv

15、tj); printf(n); fprintf(OUTF,n); printf(n); fprintf(OUTF,n); /求所有非终结符的lastVT集 for(i=0;iVN_CNT;i+) char lvtSTR_MAX; LastVT(VNi.vn,lvt); strcpy(VNi.lastVT,lvt); printf(LastVT(%c)= ,VNi); fprintf(OUTF,LastVT(%c)= ,VNi); for(int j=0;j(int)strlen(lvt);j+) printf(%c ,lvtj); fprintf(OUTF,%c ,lvtj); printf(

16、n); fprintf(OUTF,n); /判别是否是OG文法 for(i=0;iP_CNT;i+) int j=0; while(Pi.rightj+1!=0) char ch=Pi.rightj; char nextch=Pi.rightj+1; if(isVN(ch)!=-1 & isVN(nextch)!=-1) return 0; else j+; return 1;bool O_P_G() /判别是否是OPG文法 不含空产生式或任意两个终结符a,b之间至多有一种(,=)关系 for(int m=0;mMAX_NUM;m+) /初始化M数组 for(int n=0;nMAX_NUM;

17、n+) Mmn= ; for(int i=0;i.ab. (a=b) if(MisVT(ch)isVT(nextch)= ) /当M为空时赋号 MisVT(ch)isVT(nextch)=; j+; continue; else /当有a,b有两种关系时返回 printf(n%c,%c有两种关系!,ch,nextch); fprintf(ERRF,n%c,%c有两种关系!,ch,nextch); return 0; if(isVT(ch)!=-1 & isVN(nextch)!=-1) /A-.aB. (aFirstVTB) FirstVT(nextch,VNisVN(nextch).firs

18、tVT); for(int m=0;VNisVN(nextch).firstVTm!=0;m+) if(MisVT(ch)isVT(VNisVN(nextch).firstVTm)= ) MisVT(ch)isVT(VNisVN(nextch).firstVTm)=.aBb. (a=b) if(MisVT(prech)isVT(nextch)= ) MisVT(prech)isVT(nextch)=; else printf(n%c,%c有两种关系!,prech,nextch); fprintf(ERRF,n%c,%c有两种关系!,prech,nextch); return 0; if(isV

19、N(ch)!=-1 & isVT(nextch)!=-1) /A-.Bb.(LastVTBb) LastVT(ch,VNisVN(ch).lastVT); for(int m=0;VNisVN(ch).lastVTm!=0;m+) if(MisVT(VNisVN(ch).lastVTm)isVT(nextch)= ) MisVT(VNisVN(ch).lastVTm)isVT(nextch)=; else /当有a,b有两种关系时返回 printf(n%c,%c有两种关系!,VNisVN(ch).lastVTm,nextch); fprintf(ERRF,n%c,%c有两种关系!,VNisVN

20、(ch).lastVTm,nextch); return 0; j+; continue; else j+; /(while) /(for) MVT_CNT-1VT_CNT-1=; /#=# for(int x=0;x(int)strlen(VNisVN(S0).firstVT);x+) /# FirstVT(S0); MVT_CNT-1isVT(VNisVN(S0).firstVTx)=; for(x=0;x # MisVT(VNisVN(S0).lastVTx)VT_CNT-1=; return 1;void leftphase(char str,char substr,char a) /

21、求最左素短语,用substr储存 int slen=strlen(str); int begin,end=slen-1; for(int i=slen-1;i0;i-) if(MisVT(stri)isVT(a)=) if(MisVT(stri-1)isVT(stri)=) begin=i; else begin=i-1; continue; if(isVN(stri) continue; int j=0;int b=begin; /必须将begin的值记录,因为while的循环条件与begin有关,否则会影响素短语的取值。 while(jend-begin+1) /将素短语存放至substr中 substrj+=strb+; substrj=0; void left_str(char w,char subw,int ip) /求剩余输入串subw int j=0,begin; for(begin=ip+1;begin(int)strlen(w);begin+) subwj=wbegin; j+; subwj=0;#include OG & OPG.cpp#include stack.cppvoi

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

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