编译原理实验-词法语法分析-附源代码(共17页).docx

上传人:飞****2 文档编号:14507959 上传时间:2022-05-04 格式:DOCX 页数:17 大小:74.16KB
返回 下载 相关 举报
编译原理实验-词法语法分析-附源代码(共17页).docx_第1页
第1页 / 共17页
编译原理实验-词法语法分析-附源代码(共17页).docx_第2页
第2页 / 共17页
点击查看更多>>
资源描述

《编译原理实验-词法语法分析-附源代码(共17页).docx》由会员分享,可在线阅读,更多相关《编译原理实验-词法语法分析-附源代码(共17页).docx(17页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、精选优质文档-倾情为你奉上编译原理实验报告*PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。PL/0语言文法的EBNF表示如下::=. := :=CONST,; := := :=VAR , ; :=| :=; ; :=PROCEDURE ; :=| | :=:= :=BEGIN ; END := |ODD := +|- := := | () := +|- := *|/ := =|#|= := IF THEN := CALL 标识符 := WHILE DO := READ(,) := W

2、RITE(,) := a|b|X|Y|Z := 0|1|8|9【预处理】对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。【实验一】词法分析【实验目的】给出PL/0文法规范,要求编写PL/0语言的词法分析程序。【实验内容】已给PL/0语言文法,输出单词(关键字、专用符号以及其它标记)。【实验要求】1. 确定编译中使用的表格、标识符与关键字的区分方法等。2. 把词法分析器设计成一个独立一遍的过程。3. 词法分析器的输出形式采用二元式序列,例如:(ident, a)(plus, + )(number, 15)(times, *

3、 )(ident, b )【输入输出】输入:PL/0源程序。例: a+15*b输出:(ident, a)(plus, + )(number, 15)(times, * )(ident, b )【实验结果】实验结果与实验要求相同,没有异议,对输入字符采取一个一个读入,到达句柄时,则采取LL(1)文法进行规约。实验结果如下:实验结果用文本来进行输入输出,所以在工程目录下还会有一个文本输入,输出文件。分别为in.txt out.txt【实验体会】在编写这段代码的过程中,比较麻烦得还是之前的语法预处理阶段,将不满足ll(1)文法的语法转化为标准的ll(1)文法。程序在处理词法分析的过程就是不断通过ge

4、tsym()这个函数来条用getch(),不断形成一个一个的词汇,供下面语法分析时使用。记录词汇类型的sym是一个枚举类型。使用起来会方便许多,比较系统。其中还用到了文本输入输出的技巧,把读出的词汇保存起来。词法分析还是比较简单,在编写代码的时候没有太大的阻碍。通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C+语言)直接编写此法分析程序。另外,也让我重新熟悉了C+语言的相关内容,加深了对C+语言的用途的理解。【实验二】语法分析【实验目的】给出PL/0文法规范,要求编写PL/0语言的语法分析程

5、序。【实验内容】已给PL/0语言文法,构造表达式部分的语法分析器。【实验要求】1. 将实验一“词法分析”的输出结果,作为表达式语法分析器的输入,进行语法解析,对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”, 指出错误原因。2. 把语法分析器设计成一个独立一遍的过程。3. 语法分析器的编写方法采用递归子程序法。【输入输出】输入:PL/0表达式,用实验一的输出形式作为输入。例如: 对于PL/0表达式,a+15*b用下列形式作为输入:(ident, a)(plus, + )(number, 15) (times, * )(ident, b )输出:对于语法正确的表达式

6、,报告“语法正确”;对于语法错误的表达式,报告“语法错误”, 指出错误原因。【实验结果】实验结果与实验要求相同,没有异议,对输入字符采取一个一个读入,对输入的一个语句进行判断,判断语法的正误,采用对算法的判断,若全为数字则进行最后的计算【实验体会】通过语法分析可以判断当前输入语句是否正确,实验通过对数学式的处理来进行对语句的判断是否正确,若正确则只要输入“语句正确”即可,若语句错误则需要根据错误的原因输出错误的理由,以方便编译员修改自己的代码。实现方法是通过对文本文件的输入,当前数据与即将输入的字符串进行匹配,若不符合LL(1)文法则判定为错误,若符合则继续向下完成语法分析。【源代码】#inc

7、lude #include #include #include #include #include #include #include using namespace std;ifstream fin(in.txt);ofstream fout(out.txt);enum symbol /01 2 34 567nul,ident, number, plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,then

8、sym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym;#define symnum 32char symworksymnum10;/单符号#define norw 13 /key_word num#define al 10 /maxstr#define nmax 10/number longchar wordnorwal;/key wordchar ch;/bufferchar getch()enum symbol sym;char idal+1;/ identchar aal+1;/tempchar IDal+

9、1; int cc=0,ll=0,num;/当前在行的位置cc,行字符的长度ll,num数字的值int nn=0;char line81;int flg=0;/ 正数;/char line81;enum symbol ssym256;enum symbol wsymnorw;/int cc,ll;/chccint err;void init()int i;for(i=0;i=255;i+)ssymi=nul;/0ssym+=plus;ssym-=minus;ssym*=times;ssym/=slash;ssym(=lparen;ssym)=rparen;ssym=eql;ssym,=comm

10、a;ssym.=period;ssym#=neq;/not equalssym;=semicolon;strcpy(&symworkplus0,plus);strcpy(&symworkminus0,minus);strcpy(&symworktimes0,times);strcpy(&symworkslash0,slash);strcpy(&symworklparen0,lparen);strcpy(&symworkrparen0,rparen);strcpy(&symworkeql0,eql);strcpy(&symworkcomma0,comma);strcpy(&symworkneq0

11、,neq);strcpy(&symworkperiod0,period);strcpy(&symworksemicolon0,semicolon);strcpy(&word00,begin);/关键字小写字母strcpy(&word10,call);strcpy(&word20,const);strcpy(&word30,do);strcpy(&word40,end);strcpy(&word50,if);strcpy(&word60,odd);strcpy(&word70,procedure);strcpy(&word80,read);strcpy(&word90,then);strcpy(

12、&word100,var);strcpy(&word110,while);strcpy(&word120,write);wsym0=beginsym;wsym1=callsym;wsym2=constsym;wsym3=dosym;wsym4=endsym;wsym5=ifsym;wsym6=oddsym;wsym7=procsym;wsym8=readsym;wsym9=thensym;wsym10=varsym;wsym11=whilesym;wsym12=writesym;void WordAnalyse()switch(sym)case nul:/fout ( nul , ID )en

13、dl;break;case ident:fout ( ident , ID )endl;cout( ident , ID )endl;break;case number:fout ( number , num )endl;cout( number , num )endl;break;case plus:fout ( plus , ID )endl;cout( plus , ID )endl;break;case minus:fout ( minus , ID )endl;cout( minus , ID )endl;break;case times:fout ( times , ID )end

14、l;cout( times , ID )endl;break;case slash:fout ( slash , ID )endl;cout( slash , ID )endl;break;case oddsym:fout ( oddsym , ID )endl;cout( oddsym , ID )endl;break;case lss:fout ( lss , ID )endl;cout( lsst , ID )endl;break;case eql:fout ( eql , ID )endl;cout( eql , ID )endl;break;case neq:fout ( neq ,

15、 ID )endl;cout( neq , ID )endl;break;case leq:fout ( leq , ID )endl;cout( leq , ID )endl;break;case gtr:fout ( gtr , ID )endl;cout( gtr , ID )endl;break;case geq:fout ( geq , ID )endl;cout( geqt , ID )endl;break;case lparen:fout ( lparent , ID )endl;cout( lparent , ID )endl;break;case rparen:fout (

16、rparent , ID )endl;cout( rparent , ID )endl;break;case comma:fout ( comma , ID )endl;cout( comma , ID )endl;break;case semicolon:fout ( semicolon , ID )endl;cout( semicolon , ID )endl;break;case period:fout ( period , ID )endl;cout( period , ID )endl;break;case becomes:fout ( becomes , ID )endl;cout

17、( becomes , ID )endl;break;case beginsym:fout ( beginsym , ID )endl;cout( beginsym , ID )endl;break;case endsym:fout ( endsym , ID )endl;cout( endsym , ID )endl;break;case ifsym:fout ( ifsym , ID )endl;cout( ifsym , ID )endl;break;case thensym:fout ( thensym , ID )endl;cout( thensym , ID )endl;break

18、;case whilesym:fout ( whilesym , ID )endl;cout( whilesym , ID )endl;break;case writesym:fout ( writesym , ID )endl;cout( writesym , ID )endl;break;case readsym:fout ( readsym , ID )endl;cout( readsym , ID )endl;break;case dosym:fout ( dosym , ID )endl;cout( dosym , ID )endl;break;case callsym:fout (

19、 callsym , ID )endl;cout( callsym , ID )endl;break;case constsym:fout ( constsym , ID )endl;cout( constsym , ID )endl;strcpy(ID,);break;case varsym:fout ( varsym , ID )endl;cout( varsym , ID )endl;break;case procsym:fout ( procsym , ID )endl;cout( procsym , ID )endl;break;default :break;int getch()i

20、f(cc=ll) if(fin.eof()coutprogram incpmplete!endl;return -1;ll=cc=0;fin.getline(line,81);ll=strlen(line);ch= ;return 0;if(cc=0)cout lineendl;ch=linecc;coutch=a&ch=a&ch=0&ch=9)/名字或保留字以a.z 开头if(kal)IDk=ch;k+;getchdo;IDk=0;i=0;j=norw;do /* 搜索当前符号是否为保留字 */k=(i+j)/2;if(strcmp(ID,wordk)=0)i=k+1;while(ij)sy

21、m=wsymk; else sym=ident; /* 搜索失败,则是名字或数字 */elseif(ch=0&ch=0&chnmax)/error(30);elseif(ch=:)getchdo;if(ch=)sym=becomes;strcpy(ID,:=);getchdo;elsesym=nul;strcpy(ID,NULL);elseif(ch=)getchdo;if(ch=)sym=geq;strcpy(ID,=);getchdo;elsesym=gtr;strcpy(ID,);else if(ch=)getchdo;if(ch=)sym=leq;strcpy(ID,=);getchd

22、o;elsesym=lss;strcpy(ID,);elsesym=ssymch;strcpy(ID,&ch);/if(sym!=period)getchdo;return 1;/语法分析部分 实验2int lp=0;int rp=0;#define getsymdo if(-1=getsym() return -1#define expressiondo() if(-1=expression() return -1#define termdo() if(-1=term() return -1#define factordo() if(-1=factor() return -1int expr

23、ession();/语法分析int factor()if(sym!=ident &sym!=number&sym!=lparen) err+;if(err=1) printf(语法错误: n);printf(error-Factor Needs Ident or Number or Lparenn);if (sym = ident) | (sym = number) | (sym = lparen) if (sym = ident) WordAnalyse();if(getsym()=-1)return -1;if(sym!=times&sym!=slash&sym!=plus&sym!=mi

24、nus&sym!=rparen)err+;if(err=1) printf(语法错误: n);printf(变量后没有跟上+-* n);if(lp=0 & sym=rparen)err+;if(err=1) printf(语法错误: n);printf(没有左括号匹配n);else if (sym = number)WordAnalyse();if(getsym()=-1)return -1;if(sym!=times&sym!=slash&sym!=plus&sym!=minus&sym!=rparen)err+;if(err=1) printf(语法错误: n);printf(数字后没有跟

25、上+-* n);if(lp=0 & sym=rparen)err+;if(err=1) printf(语法错误: n);printf(没有左括号匹配n);else if (sym = lparen)WordAnalyse();lp+;if(getsym()=-1) lp-;err+;if(err=1) printf(语法错误: n);printf(error-Needs Rparen n);return -1;expressiondo();if (sym = rparen)WordAnalyse();lp-;if(getsym()=-1)return -1;if(sym!=times&sym!

26、=slash&sym!=plus&sym!=minus)err+;if(err=1) printf(语法错误: n);printf(括号后没有跟上+-* n);elseerr+;if(err=1) printf(语法错误: n);printf(error-Needs Rparen n);return 0;int term()factordo();if(sym!=times&sym!=slash&sym!=plus&sym!=minus&sym!=ident&sym!=number&sym!=lparen&sym!=rparen) err+;if(err=1) printf(语法错误: n);p

27、rintf(不能识别字符n);while (sym = times) | (sym = slash)WordAnalyse();if(getsym()=-1) err+;if(err=1) printf(语法错误: n);printf(* 后缺项n);return -1;factordo();return 0;int expression()if (sym = plus) | (sym = minus)/coutstrlen(ID)endl;if (sym=minus&2=strlen(ID)+1)flg=1;else flg=0;WordAnalyse();getsymdo;termdo()

28、;else/WordAnalyse();termdo();if(sym!=times&sym!=slash&sym!=plus&sym!=minus&sym!=ident&sym!=number&sym!=lparen&sym!=rparen) err+;if(err=1) printf(语法错误: n);printf(不能识别字符n);while (sym = plus) | (sym = minus)WordAnalyse();if(getsym()=-1) err+;if(err=1) printf(语法错误: n);printf(+ - 后缺项n);return -1;termdo();return 0;int main(int argc, char* argv)init();err=0;ifstream fin(in.txt);ofstream fout(out.txt);ch= ;lp=0;getsymdo;expression();if(err=0) cout语法正确endl;else cout语法错误,错误个数: errendl;专心-专注-专业

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com