您好,欢迎访问三七文档
#includeiostream#includestring#includestdio.h#includestring.h#includestdlib.h#includemapusingnamespacestd;/********************************************************************/PL0的编译程序C++版//词法分析语法分析符号表//词法分析过程中/遇到.号就立即结束,无论后面是否有内容都忽略/遇到非法字符,中断分析并给出错误报告/遇到超过14个字母的单词,截断成14个字母的,如果他不是数字再截断成10个字母的并给出错误报告/遇到数字开头的标识符中断分析并给出错误报告//语法分析过程中/利用词法分析的结果进行分析/严格按照PL0程序定义来编写//程序::=程序首部分程序./程序首部::=PROGRAM标识符;/分程序::=[常量说明部分][变量说明部分][过程说明部分]语句部分/常量说明部分::=CONST常量定义{,常量定义};/常量定义::=标识符=无符号整数/变量说明部分::=VAR标识符{,标识符};/过程说明部分::=过程首部;分程序;【原课件中没有最后的分号,经分析应该有分号】/过程首部::=PROCEDURE标识符/语句部分::=语句|复合语句/复合语句::=BEGIN语句{;语句}END【符合语句应该注意的是,END前距离END最近的那条语句一定没有分号,其他语句必须有分号】/语句::=赋值语句|条件语句|当型循环语句|过程调用语句|读语句|写语句|复合语句/赋值语句::=标识符:=表达式/读语句::=READ(标识符{,标识符})/写语句::=WRITE(表达式{,表达式})/过程调用语句::=CALL标识符【原课件中有分号,实际不应该有】/条件语句::=IF条件THEN语句/当型循环语句::=WHILE条件DO语句/因子::=标识符|常量|(表达式)/项::=因子{乘法运算符因子}/乘法运算符::=*|//表达式::=[+|-]项{加法运算符项}/加法运算符::=+|-/条件::=表达式关系运算符表达式|ODD表达式/关系运算符::=#|=||=||=//如果上述的任意一个步骤出了问题都会有错误提示,并指出是在源文件中的第几行,是哪一个定义出了问题/当一个语句【复合语句除外】判断成功之后,在词法分析的结果找到这个语句的开始和结束,并输出这个语句是什么语句/语法分析的实际操作类似一个走迷宫的搜索问题,找到一个可行的方向就前进,直到走到把所有单词都分析完,或者走不通了,一层层回溯返回FALSE给出错误信息//符号表/符号表的建立是在语法分析的深度优先搜索的基础上完成的/基于深度优先搜索的特点当一个过程分析完,直接就能得到它的层级/变量的LEVEL等于定义该变量的过程的LEVEL+1/每个过程的变量的ADR都重新从3开始递增/常量没有LEVEL,没有ADR,/变量和常量都没有SIZE/当程序的变量分析完就得到了符号表中最近插入的过程的SIZE【SIZE等于该过程的最后一个变量的ADR+1,若该过程没有变量则等于3】/*******************************************************************/typedefstructt{stringname,kind;intval,lev,adr,size;}Table;boolisChengXu(intlev);boolisFenChengXu(intlev);boolisChengXuShouBu();boolisChangLiangShuoMing();boolisBianLiangShuoMing();boolisGuoChengShuoMing(intlev);boolisYuJuBuFen();boolisChangLiangDingYi();boolisGuoChengShouBu(intlev);boolisYuJu();boolisFuHeYuJu();boolisFuZhiYuJu();boolisWhileDoYuJu();boolisIfYuJu();boolisCallYuJu();boolisWriteYuJu();boolisReadYuJu();boolisTiaoJian();boolisYinZi();boolisXiang();boolisBiaoDaShi();voidprintYuFa(intx,inty,stringstatement);//输出语法分析的结果voidaddtotable(stringname,stringkind,intval,intlev,intadr,intsize);//把记录加入符号表intstoi(strings);//字符串转化成数字stringitos(intn);//数字转化成字符串interror(inte,inteline);//指出在eline行有错误eboolisNumber(strings);//判断一个字符串是不是一个数字stringstrtoupper(strings);//把字符串转换为大写stringstrtolower(strings);//把字符串转换为小写intlvkongge(stringmSourse,int&i);//虑空格,遇到文件末尾结束,返回-1stringgetnext(stringmSourse,int&i);//从源文件中识别一个单词并返回boolcifafenxi(stringmSourse);//词法分析的主函数,执行虑空格操作,然后用getnext函数获取下一个单词进行分析,依次循环知道lvkongge函数返回-1voidinitmp();//初始化保留字界符的查找表,boolnexteql(strings);//从词法分析的结果顶部取出一个单词,判断s是否与之相等,不相等返回FALSE,相等返回TRUE并且顶部指针指向词法分析结果的下一个单词voidprintYuFa(intx,inty,stringstatement);//输出语句,在词法分析的结果数组中下标号从x到y是一个statement语句,遍历输出这个语句voidprinttable();//输出符号表voidprintErrors();//输出错误报告mapstring,stringwords;//保留字,界符等等,的对照表stringwQueue[200][2];//词法分析的最终结果,模拟成一个队列【wQueue[i][0]是第i个位置的单词,wQueue[i][1]是第i个单词的类别】intwhead=0,wtail=0;//队列的头,尾指针intwline[200]={0},line=1;//单词的行号,与wQueue对应stringname;//每一次调用nexteqls函数都会改变,具体看nexteqls函数stringerrors[100];//存储的错误信息intetop=0;Tabletable[100];inttabletop=0,padr=1,pradr=3,plev=-1,ltx=0;voidaddtotable(stringname,stringkind,intval,intlev,intadr,intsize){//添加一条信息到符号表table[tabletop].name=name;table[tabletop].kind=kind;table[tabletop].val=val;table[tabletop].lev=lev;table[tabletop].adr=adr;table[tabletop++].size=size;if(kind==PROCEDURE){plev=lev,pradr=3;if(tabletop0){table[ltx].size=table[tabletop-2].adr==-1?3:(1+table[tabletop-2].adr);}ltx=tabletop-1;}}stringfind(strings){inti=0;while(itabletop){if(table[i].name==s){returntable[i].kind;}i++;}return@_@;}intstoi(strings){//把字符串转换成整数inti=-1;intr=0;while(s[++i]){r*=10;r+=s[i]-'0';}returnr;}stringitos(intn){//把整数n转换成string型strings;charc[10]=;intl=8;c[9]=0;while(n=10){c[l--]=n%10+'0';n/=10;}c[l--]=n+'0';s=c+(++l);returns;}interror(inte,inteline){//错误处理switch(e){case0:{errors[etop++]=itos(e)+:+itos(eline)+行有非法字符;break;}case1:{errors[etop++]=itos(e)+:+itos(eline)+行有超过14个字母的单词;break;}case2:{errors[etop++]=itos(e)+:+itos(eline)+行有数字开头的标识符;break;}case3:{errors[etop++]=itos(e)+:+itos(eline)+行有超过10个字母的标识符;break;}case4:{errors[etop++]=itos(e)+:+itos(eline)+行程序结尾没有.;break;}case5:{errors[etop++]=itos(e)+:+itos(eline)+行程序首部标识符后面没有;;break;}case6:{errors[etop++]=itos(e)+:+itos(eline)+行程序首部PRAGRAM后面没有标识符;break;}case7:{errors[etop++]=itos(e)+:+itos(eline)+行没有程序首部;break;}case8:{errors[etop++]=itos(e)+:+itos(eline)+行分程序后缺少语句部分;break;}case9:{errors[etop++]=itos(e)+:+itos(eline)+行常量说明的,字符后面有错误;break;}case10:{errors[etop++]=itos(e)+:+itos(eline)+行常量说明后面没有;结尾;break;}case11:{errors[etop++]=itos(e)+:+itos(eline)+行常量定义有错误;break;}case12:{errors[etop++]=itos(e)+:+itos(eline)+行变量说明多了,;break;}case13:{errors[etop++]=itos(e)+:+itos(eline)+行变量说明没有;结尾;break;}case14:{errors[etop++]=itos(e)+:+itos(eline)+行VAR后面没有定义的标识符;break;}case15:{errors[etop++]=itos(e)+:+itos(eline)+行分程序后面没有;结尾;break;}case16:{errors[etop++]=itos(e)+:+itos(eline)+行过程说明后面没有分程序;break;}case17:{errors[etop++]=ito
本文标题:pl0语法分析
链接地址:https://www.777doc.com/doc-5621480 .html