实验一词法分析一.实验目的1、学会针对DFA转换图实现相应的高级语言源程序。2、深刻领会状态转换图的含义,逐步理解有限自动机。3、掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。二.实验内容TINY计算机语言的编译程序的词法分析部分实现。从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。为了简化程序的编写,有具体的要求如下:(1)数仅仅是整数。(2)空白符仅仅是空格、回车符、制表符。(3)代码是自由格式。(4)注释应放在花括号之内,并且不允许嵌套三.实验要求要求实现编译器的以下功能:(1)按规则拼单词,并转换成二元式形式(2)删除注释行(3)删除空白符(空格、回车符、制表符)(4)列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式(5)发现并定位错误,词法分析进行具体的要求:(1)记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性就是表示的字符串值。(2)词法分析的具体功能实现是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。这样配合语法分析程序的分析需要的记号及其属性,生成一个语法树。(3)标示符和保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果存在该表格中则是保留字,否则是一般标示符。源程序:/*注意:测试时把测试的源程序存入当前目录中,并改名为source.txt*/#includeiostream#includeiomanip#includectype.h#includefstream#includestringusingnamespacestd;enumWordType{WRONG,NUMBER,BIAOSHI,IF,THEN,ELSE,END,REPEAT,UNTIL,//9READ,WRITE,PLUS,SUBTRACT,MULTIPLY,DIVIDEY,EQUAL,LESSTHAN,COLON,//18ASSIGNMENT,LINE_FEED,SPACE,TAB,BRACKET_L,BRACKET_R};//24enumCharType{ALPHABET,OTHER};enumWrongType{ZERO,ALP_NUM,NUM_ALP,UNLEAGL_S,NO_MATCH,UNKNOW};char*Words[]={wrong,number,biaoshi,if,then,else,end,repeat,until,//9read,write,+,-,*,/,=,,:,//18:=,\n,,,{,}};//24typedefstruct{char*str;intwordtype;}Two;charArrayChar[100],cbuffer;inti=-1,numline=1,wordtype;stringLineChar;TwoT;ifstreamfp(source.txt,ios::in);intmain(){voidHandleAlphabet();voidHandleNumber();voidHandleOther();if(!fp)cout文件打开错误!!endl;else{coutsetiosflags(ios::left)setw(6)行数(;coutsetiosflags(ios::left)setw(10)类别编码,;coutsetiosflags(ios::left)setw(20)字符)endl;fp.get(cbuffer);while(!fp.eof()){if(cbuffer=='\n')//忽略换行符{cout第numline行所有字符:LineCharendl;numline++;LineChar=;fp.get(cbuffer);}elseif(cbuffer=='')//忽略空字符{LineChar+=;fp.get(cbuffer);}elseif(cbuffer=='')//忽略制表符{LineChar+=;fp.get(cbuffer);}elseif(isalpha(cbuffer))//判断是否是字母{HandleAlphabet();}elseif(isdigit(cbuffer))//判断是否是数字{HandleNumber();}else//其他字符HandleOther();i=-1;}}cout第numline行所有字符:LineCharendl;fp.close();system(pause);return0;}intMatch(charstr[],intchartype)//查找匹配的字符{inti;switch(chartype){caseALPHABET:for(i=IF;i=WRITE;i++){if(strcmp(Words[i],str)==0)returni;}caseOTHER:for(i=PLUS;i=ASSIGNMENT;i++){if(strcmp(Words[i],str)==0)returni;}}returnWRONG;}voidTypeWrong(intwrongtype,intline){switch(wrongtype){caseZERO:break;caseALP_NUM:cout字母后面不能紧跟数字!;break;caseNUM_ALP:cout数字后面不能紧跟字母!;break;caseUNLEAGL_S:cout非法特殊符号!;break;caseNO_MATCH:cout没有与第line行“{”匹配的“}”!;break;default:cout其它类型错误!;break;}}TwoConvertTwo(charstr[],intwordtype,intwrongtype,intnumline,intline)//进行二元转换{TwoT;T.wordtype=wordtype;T.str=str;coutsetiosflags(ios::left)setw(6)numline(;coutsetiosflags(ios::left)setw(10)T.wordtype,;coutsetiosflags(ios::left)setw(20)T.str);if(T.wordtype==WRONG)TypeWrong(wrongtype,line);coutendl;returnT;}voidHandleAlphabet()//首字符为字母时的处理{boolmark=true;while(!fp.eof()&&isalpha(cbuffer)){ArrayChar[++i]=cbuffer;fp.get(cbuffer);}if(isdigit(cbuffer)){mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))){ArrayChar[++i]=cbuffer;fp.get(cbuffer);}}ArrayChar[i+1]='\0';LineChar+=ArrayChar;if(mark){wordtype=Match(ArrayChar,ALPHABET);T=ConvertTwo(ArrayChar,(BIAOSHIwordtype?BIAOSHI:wordtype),ZERO,numline,numline);}elseT=ConvertTwo(ArrayChar,WRONG,ALP_NUM,numline,numline);}voidHandleNumber()//首字符为数字时的处理{boolmark=true;while(!fp.eof()&&isdigit(cbuffer)){ArrayChar[++i]=cbuffer;fp.get(cbuffer);}if(isalpha(cbuffer)){mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))){ArrayChar[++i]=cbuffer;fp.get(cbuffer);}}ArrayChar[i+1]='\0';LineChar+=ArrayChar;if(mark)T=ConvertTwo(ArrayChar,NUMBER,ZERO,numline,numline);elseT=ConvertTwo(ArrayChar,WRONG,NUM_ALP,numline,numline);}voidDeleteNote()//删除注释{intrecord=numline;while(!fp.eof()&&cbuffer!='}'){fp.get(cbuffer);while(!fp.eof()&&cbuffer!='}'){if(cbuffer=='\n'){ArrayChar[i+1]='\0';LineChar+=ArrayChar;cout第numline行所有字符:LineCharendl;LineChar=;numline++;i=-1;fp.get(cbuffer);}ArrayChar[++i]=cbuffer;fp.get(cbuffer);}ArrayChar[i+1]='\0';if(cbuffer=='}'){ArrayChar[++i]='}';ArrayChar[i+1]='\0';T=ConvertTwo(},BRACKET_R,ZERO,numline,numline);}else{T=ConvertTwo(,WRONG,NO_MATCH,numline,record);}}LineChar+=ArrayChar;fp.get(cbuffer);}voidHandleOther()//字符为特殊字符时的处理{ArrayChar[++i]=cbuffer;if(ArrayChar[i]=='{')//删除注释{ConvertTwo({,BRACKET_L,ZERO,numline,numline);DeleteNote();}else//其他字符{fp.get(cbuffer);while(!fp.eof()&&cbuffer!='\n'&&cbuffer!=''&&cbuffer!=''&&!isalpha(cbuffer)&&!isdigit(cbuffer)){ArrayChar[++i]=cbuffer;fp.get(cbuffer);}ArrayChar[i+1]='\0';wordtype=Match(ArrayChar,OTHER);LineChar+=ArrayChar;T=ConvertTwo(ArrayChar,wordtype,(wordtype0?0:UNLEAGL_S),numline,numline);}}实验结果: