1、北邮 编译原理 词法分析实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。实验内容:设计并实现C语言的词法分析程序,要求如下。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用
2、C/C+作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。算法思路: 首先通过遍历,统计行号和字符数,并记录所有的注释。其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。对于整行数据的处理,依靠空格将其分成单个单词再具体处理。对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。程序源代码:/假设源程序存在相对路径下 名为data.c/* Name: 词法分析程序 Author: 李睿 Date: 23/10/13 00:40 Description: 题目:词法分
3、析程序的设计与实现。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用C/C+作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。 */#include
4、 #include#include#include#include using namespace std;const int MAX_INPUT_BUFFER=512;/默认输入缓存区 ifstream file;/打开文件 vectorkeyword;/预先记录关键字 vectorcomment;/存储注释vectorid;/记录标示符 vectorpre;/预处理文件 int sum_char=0;/字符数 int sum_word=0;/单词数int sum_line=0;/行数 int current_line=0;/当前行数 bool in_comment=false;/标识 此行
5、是否在注释中 char bufferMAX_INPUT_BUFFER;/缓存区 int big_bracket=0;/大括号int small_bracket=0;/小括号 void init(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
6、(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_ba
7、ck(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_ba
8、ck(void); keyword.push_back(volatile); keyword.push_back(while);void sum(void)/计算字符数 行数 存注释 file.open(data.c); int state=0;/状态转换 0:正常 1:输入一个/ 2:输入/* char temp;/暂存 string temp_comment;/暂存注释 file.seekg(0);/文件指针回到头 while(!file.eof()/遍历全文 switch(state) case 0: file.get(temp); sum_char+;/增加字符 if(n=temp)
9、sum_line+;/增加行 if(/=temp) state = 1; break; case 1:/前一个字符是 / 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;/状态回归 else
10、if(*=temp)/多行注释 temp_comment.clear(); state = 2; else/不是注释 if(n=temp) sum_line+;/增加行 state = 0; /状态回归 break; case 2: 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,*)
11、; 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; void word_analyse(void) string temp_word;/暂存单词 char *p=buffer;/处理指针
12、while(in_comment)/处理多行注释问题 if(0=*p) return; if(*=*p)&(/=*(p+1) p+=2; in_comment = false; p+; while(0!=*p)/遍历整句 if( =*p)/当是空格时后移 p+; else if(isalpha(*p) | _=*p)/以字母或下划线开头,关键字和标识符 temp_word.clear(); while(isalnum(*p) | _=*p)/记录关键字 temp_word.append(1,*p); p+; /当为空格或别的符号时弹出 sum_word+;/单词+1 id.push_back(
13、temp_word);/存入标示符 int i; for(i=0; ikeyword.size(); i+)/遍历关键字表 if(keyword.at(i)=temp_word) break; if(ikeyword.size()/记号的形式输出每个单词符号 coutendl第sum_word个单词: 保留字: temp_wordendl; else coutendl第sum_word个单词: 标示符: temp_wordendl; else if(isdigit(*p)/无符号数 temp_word.clear(); while(isdigit(*p) temp_word.append(1,
14、*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_wo
15、rd.append(1,*p); p+; sum_word+; id.push_back(temp_word); coutendl第sum_word个单词: 无符号数: temp_wordendl; else if(#=*p)/预处理文件特殊处理 while(0!=*p) temp_word.append(1,*p); p+; /p指向换行,完成直接退出 pre.push_back(temp_word); else if(=*p)/字符串 temp_word.clear(); p+; while(!=*p) temp_word.append(1,*p); p+; p+; sum_word+;
16、coutendl第sum_word个单词: 字符串: temp_wordendl; else if(+=*p)/处理符号 temp_word.clear(); if(=*(p+1)/自加 temp_word = +=; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自加号: temp_wordendl; p+=2;/推进 else if(+=*(p+1)/自加1 temp_word = +; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自加1号: tem
17、p_wordendl; p+=2;/推进 else if(isdigit(*(p+1)/有符号数 temp_word=+; for(int j=1; isdigit(*(p+j);j+) temp_word.append(1,*(p+j); id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 有符号数: temp_wordendl; p+=2;/推进 else temp_word = +; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 加号: temp_word
18、endl; p+=2;/推进 else if(-=*p)/处理符号 temp_word.clear(); if(=*(p+1)/自减 temp_word = -=; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自减号: temp_wordendl; p+=2;/推进 else if(-=*(p+1)/自减1 temp_word = -; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自减1号: temp_wordendl; p+=2;/推进 else i
19、f(isdigit(*(p+1)/有符号数 temp_word=-; for(int j=1; isdigit(*(p+j);j+) temp_word.append(1,*(p+j); id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 有符号数: temp_wordendl; p+=2;/推进 else temp_word = -; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 减号: temp_wordendl; p+=2;/推进 else if(*=*p
20、)/处理符号 temp_word.clear(); if(=*(p+1)/自乘 temp_word = *=; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自乘号: temp_wordendl; p+=2;/推进 else temp_word = *; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 乘号: temp_wordendl; p+=2;/推进 else if(/=*p)/处理符号 temp_word.clear(); if(=*(p+1)/自除
21、 temp_word = *=; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 自除号: temp_wordendl; p+=2;/推进 else if(/=*(p+1)/行注释 return;/ 直接跳出 else if(*=*(p+1)/多行注释 in_comment=true; p+=2; while(0!=*p)/判断这行为止注释能不能结束 if(*=*p)&(/)=*(p+1) in_comment = false; break; p+; else temp_word = /; id.push_back(temp_
22、word); sum_word+; coutendl第sum_word个单词: 除号: temp_wordendl; p+=2;/推进 else if(=*p)/处理等号 temp_word.clear(); if(=*(p+1)/比较 temp_word = =; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 比较号: temp_wordendl; p+=2;/推进 else temp_word = =; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 赋
23、值号: temp_word=*p) temp_word.clear(); if(=*(p+1) temp_word = =; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 大于等于号: temp_word; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 大于号: temp_wordendl; p+=2;/推进 else if(=*p) temp_word.clear(); if(=*(p+1) temp_word = =; id.push_back(temp_word); sum_word+; coutendl第sum_word个单词: 小于等于号: temp_wordendl; p+=2;/推进 else temp_word = ;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2