资源描述
.wd.编译原理实验报告*PL0语言功能简单、构造清晰、可读性强,而又具备了一般高级程序设计语言的必须局部,因而PL0语言的编译程序能充分表达一个高级语言编译程序实现的 根本方法和技术。PL/0语言文法的EBNF表示如下::=. := :=CONST,; := := :=VAR , ; :=| :=; ; :=PROCEDURE ; :=| | :=:= :=BEGIN ; END := |ODD := +|- := := | () := +|- := *|/ := =|#|= := IF THEN := CALL 标识符 := WHILE DO := READ(,) := WRITE(,) := 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, * )(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)文法。程序在处理词法分析的过程就是不断通过getsym()这个函数来条用getch(),不断形成一个一个的词汇,供下面语法分析时使用。记录词汇类型的sym是一个枚举类型。使用起来会方便许多,比拟系统。其中还用到了文本输入输出的技巧,把读出的词汇保存起来。词法分析还是比拟简单,在编写代码的时候没有太大的阻碍。通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言例如C+语言直接编写此法分析程序。另外,也让我重新熟悉了C+语言的相关内容,加深了对C+语言的用途的理解。【实验二】语法分析【实验目的】给出PL/0文法标准,要求编写PL/0语言的语法分析程序。【实验内容】已给PL/0语言文法,构造表达式局部的语法分析器。【实验要求】1. 将实验一“词法分析的输出结果,作为表达式语法分析器的输入,进展语法解析,对于语法正确的表达式,报告“语法正确;对于语法错误的表达式,报告“语法错误,指出错误原因。2. 把语法分析器设计成一个独立一遍的过程。3. 语法分析器的编写方法采用递归子程序法。【输入输出】输入:PL/0表达式,用实验一的输出形式作为输入。例如: 对于PL/0表达式,a+15*b用以下形式作为输入:(ident, a)(plus, + )(number, 15)(times, * )(ident, b )输出:对于语法正确的表达式,报告“语法正确;对于语法错误的表达式,报告“语法错误, 指出错误原因。【实验结果】实验结果与实验要求一样,没有异议,对输入字符采取一个一个读入,对输入的一个语句进展判断,判断语法的正误,采用对算法的判断,假设全为数字则进展最后的计算【实验体会】通过语法分析可以判断当前输入语句是否正确,实验通过对数学式的处理来进展对语句的判断是否正确,假设正确则只要输入“语句正确即可,假设语句错误则需要根据错误的原因输出错误的理由,以方便编译员修改自己的代码。实现方法是通过对文本文件的输入,当前数据与即将输入的字符串进展匹配,假设不符合LL1文法则判定为错误,假设符合则继续向下完成语法分析。【源代码】#include #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,thensym,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+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,=comma;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,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(&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 )endl;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 )endl;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 , 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 ( 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( 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;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 ( 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()if(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)sym=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,=);getchdo;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 expression();/语法分析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!=minus&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(数字后没有跟上+-* 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!=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);printf(不能识别字符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();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;
展开阅读全文