北邮编译原理词法分析.docx_第1页
北邮编译原理词法分析.docx_第2页
北邮编译原理词法分析.docx_第3页
北邮编译原理词法分析.docx_第4页
北邮编译原理词法分析.docx_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。实验内容:设计并实现C语言的词法分析程序,要求如下。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用C/C+作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。算法思路: 首先通过遍历,统计行号和字符数,并记录所有的注释。其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。对于整行数据的处理,依靠空格将其分成单个单词再具体处理。对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。程序源代码:/假设源程序存在相对路径下 名为data.c/*Name: 词法分析程序 Author: 李睿 Date: 23/10/13 00:40Description:题目:词法分析程序的设计与实现。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用C/C+作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。 */#include #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;/标识 此行是否在注释中 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(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);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) 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;/状态回归 elseif(*=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,*);temp_comment.append(1,temp);if(n=temp)sum_line+; elseif(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;/处理指针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+;/单词+1 id.push_back(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;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; 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+; 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号: temp_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_wordendl; p+=2;/推进 elseif(-=*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 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_wordendl; p+=2;/推进 elseif(*=*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个单词: 乘号: temp_wordendl; p+=2;/推进 elseif(/=*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)/行注释 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_word); sum_word+; coutendl第sum_word个单词: 除号: temp_wordendl; p+=2;/推进 elseif(=*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个单词: 赋值号: 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;/推进 elseif(=*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个单词: 小于号: temp_wordendl; p+=2;/推进 elseif(!=*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个单词: 取反号: temp_wordendl; p+=2;/推进 elseif(:=*p | (=*p | )=*p | ;=*p | =*p| =*p | ,=*p|=*p|=*p|0=*p|n=*p)/标点不算单词 if(=*p)small_bracket+;/查错if()=*p)small_bracket-;/查错if(=*p)big_bracket+;/查错if(=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论