C++源代码单词扫描程序(词法分析).doc_第1页
C++源代码单词扫描程序(词法分析).doc_第2页
C++源代码单词扫描程序(词法分析).doc_第3页
C++源代码单词扫描程序(词法分析).doc_第4页
C++源代码单词扫描程序(词法分析).doc_第5页
免费预览已结束,剩余8页可下载查看

下载本文档

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

文档简介

一、 需求分析1、 程序功能:C+源代码扫描程序识别C+记号。2、 C+记号:C+语言包含了几种类型的记号:标识符,关键字,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等。3、 界面要求:采用MFC界面实现。4、 文本压缩:为了提高C+源程序的可读性,C+程序在书写过程中加入了空行、空格、缩进、注释等。假设想牺牲可读性,以节省磁盘空间,那么可以存贮一个删除了所有不必要空格和注释的C+源程序的压缩文本。二、 概要设计1、 关键字(67个):asm,auto,bool,break,case,catch,char,class,const,continue,default,delete,do,double,else,enum,except,explicit,extern,false,finally,float,for,friend,goto,if,inline,int,long,mutable,namesapce,new,operator,private,protectde,public,register,return,short,signed,szieof,static,struct,string,switch,template,this,throw,true,try,typedef,typename,union,unsigned,using,virtual,void,while,main,std,cin,cout,endl,scanf,printf,include,define2、 一元运算符或分隔符(25个): , ; ( ) # ? : . + - * / % = = = != + - : += -= *= /= %= &= = -4、 程序流程图:(1) 主流程图:(2) 词法分析模块流程图: (3) 文本压缩模块流程图:三、 详细设计1、 词法分析模块:/函数功能:扫描一行字符串识别C+记号/函数参数:s表示C+源程序中的一行待分析的字符串/参数返回值:无void analyse(string s,LPVOID IParam)CScanDlg *q=(CScanDlg*)IParam; /获取对话框指针char str300; /用于存储识别出的C+记号CString St; /将上面str变量从char类型转换为CString类型int i=0; /记录s字符串的移动的当前位置int j; /记录str字符串的当前位置if(note_flag) /过滤掉存在/*.*/形式的屏蔽段while(si!=*&si!=0|si=*&si+1!=/) /不存在*/串或当前串还没结束则s字符串的当前指针继续后移i+;if(si!=0) /遇到*/,将标志note_flag置为falsei=i+2;note_flag=false;while(si!=0) /串没结束则循环扫描if(si= |si=t) /过滤空格和制表符i+;continue;if(si=m_list .InsertItem (count,St); /在列表控件中显示m_list .SetItemText(count,1,St);count+;j=0;i+;while(si!=&si!=)strj=si;j+;i+;strj=0;St.Format (%s,str);q-m_list .InsertItem (count,St); /在列表控件中显示头文件名St.Format (%s,关键字);q-m_list .SetItemText(count,1,St);count+;St.Format (%c,si);q-m_list .InsertItem (count,St); /在列表空间中显示字符或St.Format (%s,特殊符号);q-m_list .SetItemText(count,1,St);count+;i+; /是否是预处理串else if(si=/&si+1=/) /过滤形式为/的注释段i+;while(si!=0)i+; /是否是注释else if(si=/&si+1=*) /对第一次在串中以形式为/*开头的后续串的处理note_flag=true;i=i+2;while(si!=*&si!=0|si=*&si+1!=/) /扫描到*/或0则退出循环i+;if(si!=0)note_flag=false; /是否是注释else if(isalpha(si)|si=_) /对以字母、下划线开头的字符串的处理int flag=0;j=0;strj=si;i+;j+;while(isalpha(si)|isdigit(si)|si=_) /是字母、数字或下划线则继续循环strj=si;i+;j+;strj=0;for(int k=0;km_list .InsertItem (count,St); St.Format (%s,关键字); q-m_list .SetItemText(count,1,St);count+;flag=1;break;if(flag!=1) /不在关键字表中则是标识符St.Format (%s,str); q-m_list .InsertItem (count,St); St.Format (%s,标识符); q-m_list .SetItemText(count,1,St); count+; /是否是标识符或关键字else if(isdigit(si)|si=.&isdigit(si+1) /判断是否是数字(包括浮点数和整数,以及、浮点数的科学计数表示法和数的不同进制表示),但不考虑+/-号 j=0;strj=si;j+;i+;while(si!= &si!=t&si!=0&(!is_op1(si)|si=-|si=+|si=.)/遇到空格,制表符,串结束符或者不包括.的一元运算符则退出strj=si;i+;j+;strj=0;St.Format (%s,str);q-m_list .InsertItem (count,St);St.Format (%s,数字);q-m_list .SetItemText(count,1,St);count+; /是否是数字 else if(is_op1(si) /扫描到一元运算符str0=si;i+;str1=si;str2=0;if(is_op2(str) /根据最长子串原理匹配是否是二元运算符St.Format (%s,str); q-m_list .InsertItem (count,St); St.Format (%s,特殊符号); q-m_list .SetItemText(count,1,St);count+;else /是一元运算符i-;St.Format (%c,si); q-m_list .InsertItem (count,St); St.Format (%s,特殊符号); q-m_list .SetItemText(count,1,St);count+;i+; /是否是特殊符号else if(si=|si=) /判断是否字符或字符串j=0;strj=si;if(si=) /对字符的处理,包括转义字符i+;j+;while(si!=)strj=si;i+;j+;strj=si;if(si+1=)i+;j+;strj=si;j+;strj=0;St.Format (%s,str); q-m_list .InsertItem (count,St); St.Format (%s,字符); q-m_list .SetItemText(count,1,St);count+;i+;else /对字符串的处理i+;j+;while(si!=|si-1=)strj=si;i+;j+;strj=si;j+;strj=0;St.Format (%s,str); q-m_list .InsertItem (count,St); St.Format (%s,字符串); q-m_list .SetItemText(count,1,St);count+;i+;/while/函数功能:扫描函数,调用analyse函数对整个C+源代码进行扫描/函数参数:fileName表示C+源代码的路径名/参数返回值:无void scan(CString fileName,LPVOID IParam)ifstream infile; /不能作为全局变量使用infile.open (fileName,ios:in); char s300;while(!infile.eof() /指针没移到文件末尾infile.getline (s,300); /提取一行字符analyse(s,IParam); /调用analyse函数对提取的字符串进行分析infile.close ();2、 文本压缩模块:/函数功能:对一行C+源代码字符串进行去空格和注释处理/函数参数:s表示待处理的字符串/参数返回值:无void condense(string s) /过滤掉存在/*.*/形式的屏蔽段int i=0; char front; /如果一个字符的后一个字符为空格或制表符,则将当前字符保存在frontif(note_flag)while(si!=*&si!=0|si=*&si+1!=/) /不存在*/串或当前串还没结束则s字符串的当前指针继续后移i+;if(si!=0)i=i+2;note_flag=false;while(si!=0) /串没结束则循环扫描if(si= |si=t) /过滤空格和制表符i+;continue;if(si=#&si+1!=) /预处理指令单独占一行while(si!=0)outfilesi;i+;outfileendl;break;else if(si=/&si+1=/) /过滤形式为/的注释段i+;while(si!=0)i+;else if(si=/&si+1=*) /对第一次在串中以形式为/*开头的后续串的处理note_flag=true;i=i+2;while(si!=*&si!=0|si=*&si+1!=/) /扫描到*/或0则退出循环i+;if(si!=0)note_flag=false;else if(si=&si+1= &si+2=) /对字符(空格)的处理outfilesi si+2;i=i+3;else if(si=&si-1!=&si+1!=) /对字符串的处理(包含空格)outfilesi;i+;while(si!=|si-1=) outfilesi;i+;outfile1&(si-1= |si-1=t) /判断当前字符的前一个字符是否是空格或制表符 if(isalpha(front)|isdigit(front)&(isalpha(si)|isdigit(si)/如果中间被空格隔开的前后两个非空字符是数字或字母,则输出一个空格到文本 outfile ;outfilesi;if(isdigit(si)&si+1=0) /对数字在串的末尾的情况则输出一个空格outfile ;if(si+1= |si+1=t)front=si;i+;四、 调试分析1、 设计中遇到的问题及解决:1) 程序测试过程中发现注释符号/和/* */有时会扫描出错,并且小数扫描时有时也会出错,经过反复调试和检查源代码最后找出错误所在。原因是在写代码的时候有些情况考虑得不全面。2) 在做C+源文件的压缩文本时,由于起初只是考虑了去掉不必要的空格和注释,没考虑最后压缩出来的源文件是否可以编译运行,测试的时候发现了这个问题,进行了修改,最终使得问题得到解决,即压缩出来的文本可以编译运行。2、 调试总结:由于本程序的C+代码扫描都安排在了一个analyse函数中,没有先画出C+扫描程序的DFA图再进行算法的模块化分析,导致代码有点冗长,加深了调试的难度和读者的阅读理困难。但总体上还是实现了程序的功能要求,经过反复测试后,程序的健壮性也有一定的保证。五、 用户手册1、 本程序的运行环境为MFC界面,可执行文件为:scan.exe2、 用户打开程序即可看到如下主界面: 3、 按“浏览”按钮选择源文件,源文件必须是.cpp和.h后缀的,否则开始扫描时会提示文件类型错误。“开始扫描”按钮进行C+源程序的扫描,扫描结果输出在中间的列表中,“压缩文本”按钮将压缩后的源文件放在output.txt文本文件中,并打开它弹出。六、 测试结果1、 测

温馨提示

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

评论

0/150

提交评论