还剩13页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
实验一词法分析有如下算术运算文法E-E+TE-E-TE-TT-T*FT-T/FT-FF-EF-II-十进制实数|十进制整数|十六进制实数|十六进制整数I八进制实数I八进制整数10十进制实数-0|1|2|3|4|5|6|7|8|90|1|2|3|4|5|6|7|8|9*.0|1|2|3|4|5|6|7|8|90|1|2|3|4|5|6|7|8|9*11八进制实数00|112|3|4|5|6|70|112|3|4|5|6|7*.0|1|2|3|4|5|6|70|1|2|3|4|5|6|7*12十六进制实数-0x0|l|2|3|4|5|6|7|8|9|a|b|c|d|e|f0|l|2|3|4|5|6|7|8|9|a|b|c|d|e|f*.0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f0|l|2|3|4|5|6|7|8|9|a|b|c|d|e|f*13十进制整数〉x=x*8+a[i]-48;fori=strlena-l;i=0a[i]!二.;i--y=y+a[i]-48/8;y=y+x;printf,zREAL8\t%f\n,zy;saveaidxy;return;}ifid==10{fori=2;ia_longa[i]I-/;i++换算x=x*16+a[i]-48;fori=strlena-l;i=0a[i]i--y=y+a[i]-48/16;y=y+x;printfz/REAL16\t%f\n,/y;saveaidxy;return;printf/zWrongEnter;return;0|l|2|3|4|5|6|7|8|90|l|2|3|4|5|6|7|8|9*14八进制整数-00|l|2|3|4|5|6|70|l|2|3|4|5|6|7*15十六进制整数-0x0|l|2|3|4|5|6|7|8|9|a|b|c|d|e|f0|l|2|3|4|5|6|7|8|9|a|b|c|d|e|f*单词分类运算符+-*/常数十进制实数十进制整数十六进制实数十六进制整数八进制实数八进制整数.实验目的实现一个词法分析程序,将输入字符串流分解成单词流供语法分析使用.实验要求输入算术运算式,输出分解后的单词流,例如输入
0124.3+0x35a.4f*12输出运算符(八进制实数
0124.3运算符+十六进制实数0x35a.4f运算符)运算符*十进制整数12注意•输入可以是键盘输入,也可以是文件输入•如果单词输入错误,必须有提示,例如输入12a+45*013468-0x23a3输出错误数据12a运算符+十进制整数45运算符*错误数据0123468运算符-十六进制整数0x23a3〃如
0124.3+0x35a.4f*12〃如a+45*013468-0x23a3#includestring.h#includestdio.h//#includestdafx.h〃unionchars{〃联合,可存储字符串,整型和浮点型charpro^char
[15];intpronumber;floatreal;;structdata{〃将每个单元用一个结构来存储,其内容包括类型,所属的具体类型,以及属性值charkind
[7];intid;unioncharspro;;intscanchar*a;〃对每个用空格打断的单元进行进一步的分析对其进行进一步的分类voidPrintschara
[15]intidinta_long;〃将分析后的每个token输出voidsavechar*aintidintx;〃将分析后的结果保存到一个结构数组中charnowChar
[15];〃临时的存储单元,用来存储被空格打断以后单元charkinds
[11]
[8]={〃〃,〃INT10〃,〃INT8〃,〃INT16〃,〃IDN〃,J〃,〃REAL10〃,〃REAL8〃,〃REAL16〃};//单词的不同种别structdatalink
[100];intlink_long=0;intscanchar*a{//intid;inta_long=0;intdoc=0;while*a!=NULL{nowChar
[0]=,\0,;ifnowChar
[0]=O*a二二x,||*a二二X〃如果第一个字符为0且第二个字符为x则为十六进制数nowChar[a_long]二*a;*a++;along++;while*a!=NULLCO=*a*a二9||a=*a*a二f||A=*a*a二F|*a==.{nowChar[a_long*a;〃一直将此十六进制数完全读入,若为浮点型的,则加以标记if*a二二.’doc=l;*a++;a_long++;}nowChar[a_long]=,\0>;〃判断输入的十六进制数是否合法ifalong==2{〃输入的只有x则输入错误PrintsnowChar7along;return0;ifdoc〃输入的十六进制数是浮点型的PrintsnowChar10a_long;〃则将其具体的类型属性定为else〃输入的十六进制数是整型的PrintsnowChar3a_long;〃则将其具体的类型属性定义为continue;〃对八进制的判断及处理ifnowChar
[0]==,00〈二*a*a<二7〃如果第一个字符为0且第二个字符0“7则为八进制数nowChar[a_long]二*a;*a++;along++;while*a!=NULLO<=*a*a<二7||*a二二.{nowChar[a_long]=*a;〃一直将此八进制数完全读入,若为浮点型的,则加以标记if*a=,doc=l;*a++;along++;nowChar[a_long]=,\0,;ifdoc〃输入的八进制数是浮点型的PrintsnowChar9a_long;〃则将其具体的类型属性定为else〃输入的十六进制数是整型的PrintsnowChar2a_long;〃则将其具体的类型属性定义为continue;〃对十进制数的判断及处理else{whi1e*a!=NULL*O〈=*a*a<二9||*a=.{nowChar[a」ong]二*a;〃一直将此十进制数完全读入,若为浮点型的,则加以标记ifdoc=l;*a++;a_long++;nowChar[a_long]=,\0;nowChar[a_long]二*a;*a++;a_long++;〃判断输入的字符是否为运算符或其他的分隔符switchnowChar
[0]{case+:case-:case,*:case/:case,:case’:case:case’:case=:case,:nowChar[a_long]=,\0,;PrintsnowChar5a_long;continue;default:break;if*a*=nowChar
[0]nowChar
[0]=,z*||,A=nowChar
[0]nowChar
[0]=,Z{whi1e*a!=NULLa,〈二*a*a=z,||,A,二*a*a〈二Z0〈二*a*a〈二||*a==,.,|I*a={〃一直将此字符串完全读入nowChar[along]=*a;*a++;a_long++;}nowChar[a_long]=,\0;〃判断输入的字符串是否为特殊的标识符,若是,则将其具体类型值定义为〃判断输入的字符串是否为特殊的字符串ififa_long==2strcmpnowChar{PrintsnowChar6along;continue;}〃判断输入的字符串是否为特殊的字符串thenifalong-4strcmpnowChar〃then〃=0{PrintsnowChar6a_long;continue;}〃判断输入的字符串是否为特殊的字符串elseifa_long==4strcmpnowChar〃else〃=0{PrintsnowChar6a_long;continue;}〃判断输入的字符串是否为特殊的字符串whileifalong==5strcmpnowCharz,whilez,=0{PrintsnowChar6along;continue;}〃判断输入的字符串是否为特殊的字符串doifalong==2strcmpnowChar〃do〃==0{PrintsnowChar6along;continue;}〃若输入的字符串不符合以上几种情况,则输入的为变量〃若输入的字符串为变量,则将其具体属性值定义为PrintsnowChar4along;continue;}〃如果输入的既不是数值也不是字符串,则输入错误,将其具体类型之定义为elsePrintsnowChar7along;return0;}return1;main{charbuf
[100];char*tokenPtr;intid=l;link_long=0;whileid{link_long=0;getsbuf;tokenPtr=strtokbuf,〃;whileid*tokenPtr!=NULL{id=scantokenPtr;tokenPtr=strtokNULLz,;}}printf〃\n\n〃;getchar;return0;voidsavechar*aintidintxfloaty{inti;iflink_long100{link[link_long].id=id;ifid=5{ifid=8{〃将具体的类型值存入//id=8910〃若为浮点型的数值,则将浮点型的y值转换后的存入其属性当中且存入单词的种别fori=0;i9kinds[id][i]!=\0;i++link[linklong].kind[i]=kinds[id][i];link[link_long].pro.realty;else{//id=567〃若为标识符,则将单词种别定为自身,属性值定为空fori=0;i15a[i]!=,\0J;i++link[link_long].kind[i]=a[i];link[link_long].pro.pro_char
[0]=,-;link[link_long].pro.pro_char
[1]=,\0;link_long++;}else{fori=0;i8kinds[id]Ei]!=,\0f;i++//id=l234link[link_long].kind[i]=kinds[id][i];//若分解后的token为变量或者整型数值则将其单词种别直接输出ifid==4{〃若token为变量,则将其属性值设为自身else其属性值fori=0;i15a[i]!=,\0*;i++linkElink_long].pro.pro_char;linkClink_long].pro.pro_char[i]=,\0;}〃若token为整型数值,则将其相应的十进制数值赋给link[linklong].pro.pro_number=x;}link_long++;}elseprintf/zFull100\n/z;〃继续存入下一个token〃结构数组已经存满return;〃将词法分析器分解后的结果输出出来voidPrintschara
[15]intidinta_long{inti;intx=0;floaty=0;ifid==l{fori=l;ia_longa[i]!=\0;i++x=x*10+a[i]-48;printfz/INT10\t%s\n/za;saveaidxy;//intfloatl;//char*c;〃若为十进制整数〃存入结构数组return;ifid==2{fori=l;i〈a」onga[i]!=\0;i++x=x*8+a[i]-48;printf,,INT8\t%d\n,/x;saveaidxy;return;ifid==3{fori=2;ia_longa[i]!=\0;i++{if,0=a[i]a[i],9x=x*16+a[i]-48;else{ifa=a[i]a[i]〈=felsex=x*16+a[i]-55;printfz,INT16\t%d\nz,x;saveaidxy;return;ifid==4{printf〃TDN\t%s\n〃,a;saveaidxy;return;ifid=5||id=6{ifelsewhilethendoprintf〃%s\t-\n〃a;saveaidxy;return;ifid==8{fori=0;ia_longa[i]i++x=x*10+a[i]-48;fori=strlena-l;i=0a[i]y=y+a[i]-48/10;y=y+x;printfz,REAL10\t%f\nz,y;saveaidxy;return;ifid=9{fori=l;ia_longa[i]i++〃若为八进制整数〃换算为十进制数〃存入结构数组〃若为十六进制整数〃换算为十进制数x=x*16+a[i]-87;〃存入结构数组〃若为变量〃存入结构数组〃若为标识符+「*/++以及〃存入结构数组〃若为十进制浮点型i—〃整数部分与小数部分换算后相加〃存入结构数组〃若为八进制浮点型。