实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。实验内容:设计并实现C语言的词法分析程序,要求如下。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。对于整行数据的处理,依靠空格将其分成单个单词再具体处理。对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。程序源代码://假设源程序存在相对路径下名为data.c/*Name:词法分析程序Author:李睿Date:23/10/1300:40Description:题目:词法分析程序的设计与实现。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。*/#includeiostream#includefstream#includevector#includestring#includecctypeusingnamespacestd;constintMAX_INPUT_BUFFER=512;//默认输入缓存区ifstreamfile;//打开文件vectorstringkeyword;//预先记录关键字vectorstringcomment;//存储注释vectorstringid;//记录标示符vectorstringpre;//预处理文件intsum_char=0;//字符数intsum_word=0;//单词数intsum_line=0;//行数intcurrent_line=0;//当前行数boolin_comment=false;//标识此行是否在注释中charbuffer[MAX_INPUT_BUFFER];//缓存区intbig_bracket=0;//大括号intsmall_bracket=0;//小括号voidinit(void)//初始化关键字{keyword.clear();keyword.push_back(auto);keyword.push_back(break);keyword.push_back(case);keyword.push_back(char);keyword.push_back(const);keyword.push_back(continue);keyword.push_back(default);keyword.push_back(do);keyword.push_back(double);keyword.push_back(else);keyword.push_back(enum);keyword.push_back(extern);keyword.push_back(float);keyword.push_back(for);keyword.push_back(goto);keyword.push_back(if);keyword.push_back(int);keyword.push_back(long);keyword.push_back(register);keyword.push_back(return);keyword.push_back(short);keyword.push_back(signed);keyword.push_back(static);keyword.push_back(sizeof);keyword.push_back(struct);keyword.push_back(switch);keyword.push_back(typedef);keyword.push_back(union);keyword.push_back(unsigned);keyword.push_back(void);keyword.push_back(volatile);keyword.push_back(while);}voidsum(void)//计算字符数行数存注释{file.open(data.c);intstate=0;//状态转换0:正常1:输入一个/2:输入/*chartemp;//暂存stringtemp_comment;//暂存注释file.seekg(0);//文件指针回到头while(!file.eof())//遍历全文{switch(state){case0:file.get(temp);sum_char++;//增加字符if('\n'==temp)sum_line++;//增加行if('/'==temp)state=1;break;case1://前一个字符是/file.get(temp);sum_char++;//增加字符if('/'==temp)//单行注释{temp_comment.clear();//清空注释缓存while('\n'!=temp)//输完整行{file.get(temp);sum_char++;//增加字符temp_comment.append(1,temp);//添加注释}sum_line++;//行增加comment.push_back(temp_comment);//添加到注释记录表state=0;//状态回归}elseif('*'==temp)//多行注释{temp_comment.clear();state=2;}else//不是注释{if('\n'==temp)sum_line++;//增加行state=0;//状态回归}break;case2:file.get(temp);sum_char++;//增加字符if('*'==temp){file.get(temp);//再取一个sum_char++;//增加字符if('/'==temp)//结束多行注释{comment.push_back(temp_comment);//存入注释表state=0;}else//还在注释中{temp_comment.append(1,'*');temp_comment.append(1,temp);if('\n'==temp)sum_line++;}}else{if(file.eof())//当注释到尾时{if(!temp_comment.empty())//不为空时存入最后一个注释{comment.push_back(temp_comment);return;}}if('\n'==temp)sum_line++;temp_comment.append(1,temp);}break;default:break;}}}voidword_analyse(void){stringtemp_word;//暂存单词char*p=buffer;//处理指针while(in_comment)//处理多行注释问题{if('\0'==*p)return;if(('*'==*p)&&('/'==*(p+1))){p+=2;in_comment=false;}p++;}while('\0'!=*p)//遍历整句{if(''==*p)//当是空格时后移p++;elseif(isalpha(*p)||'_'==*p)//以字母或下划线开头,关键字和标识符{temp_word.clear();while(isalnum(*p)||'_'==*p)//记录关键字{temp_word.append(1,*p);p++;}//当为空格或别的符号时弹出sum_word++;//单词+1id.push_back(temp_word);//存入标示符inti;for(i=0;ikeyword.size();i++)//遍历关键字表if(keyword.at(i)==temp_word)break;if(ikeyword.size())//记号的形式输出每个单词符号coutendl第sum_word个单词:保留字:temp_wordendl;elsecoutendl第sum_word个单词:标示符:temp_wordendl;}elseif(isdigit(*p))//无符号数{temp_word.clear();while(isdigit(*p)){temp_word.append(1,*p);p++;}if(isalpha(*p)||'_'==*p)//非法字符{while(''!=*p&&'\0'!=*p){temp_word.append(1,*p);p++;}sum_word++;id.push_back(temp_word);coutendl第sum_word个单词:非法字符:temp_wordendl;couterror:在第current_line行,单词temp_word命名非法!endl;}else{if('.'==*p||'E'==*p||'e'==*p)//小数和指数形式{temp_word.append(1,*p);p++;while(isdigit(*p)){temp_word.append(1,*p);p++;}}sum_word++;id.push_back(temp_word);coutendl第sum_word个单词:无符号数:temp_wordendl;}}elseif('#'==*p)//预处理文件特殊处理{while('\0'!=*p){temp_word.append(1,*p);p++;}//p指向换行,完成直接退出pre.push_back(temp_word);}elseif(''==*p)//字符串{temp_word.clear();p++;while(''!=*p){temp_word.append(1,*p);p++;}p++;sum_word++;coutendl第sum_word个单词:字符串:temp_wordendl;}elseif('+'==*p)//处理符号{temp_word.clear();if('='==*(p+1))//自加{temp_word=+=;id.push_back(temp_word);sum_word++;coutendl第sum_word个单词:自加号:temp_wordendl;p+=2;//推进}elseif('+'==*(p+1))//自加1{temp_word=++;id.push_back(temp_word);sum_word++;coutendl第sum_word个单词:自加1号:temp_wordendl;p+=2;//推进}els