哈尔滨理工大学软件学院哈尔滨理工大学软件学院《编译原理》项目实践报告题目:词法分析器班级:软件15-4班专业:软件工程姓名:吕小胜:学号:1514010414:指导教师:张春祥日期:2017年4月19日1目录一、需求分析.............................................................................................2二、系统设计.............................................................................................2(一)系统中的数据定义..................................................................2(二)系统的概要设计......................................................................3(三)系统的详细设计......................................................................3(四)系统的核心算法......................................................................4三、系统编码及运行................................................................................4(一)系统开发涉及的软件..............................................................4(二)系统运行界面及结果..............................................................5四、系统测试.............................................................................................6五、总结.....................................................................................................7附录(源代码)........................................................................................72一、需求分析词法分析(LexicalAnalysis)是编译的第一阶段。词法分析器的主要任务是读入源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列,每个词法单元对应一个词素。这个词法单元序列被输出到语法分析器进行语法分析。二、系统设计(一)系统中的数据定义本词法分析器演示的是C语言的一个子集,故字符集如下:(1)标识符:以字母开头的字母数字串。(2)常熟(3)保留字:auto,break,case,char,const,continue,default,do,double,else,enum,extern,float,for,goto,if,int,long,register,return,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile,while(4)运算符:+、-、*、/、%、、、=、!=、==、=、=、++、--、!、&、&&、||;(5)界符:[]{}():‘’“”#,单词分类号标识符1常数2保留字3界符4运算符53单词分类表(二)系统的概要设计(三)系统的详细设计1、TestLexer()2、voidwriteFile(Stringstr1,StringBuildernumber)3、booleanisDigit(charch)4、booleanisLetter(charch)45、booleanisKeyWord(StringBuilderstr)6、booleanisOperator(charch)7、booleanisSeparators(charch)(四)系统的核心算法TestLexer()程序入口StringBufferbuffer;文件读入缓冲区Char[]cs;字符变量,存放源程序字符StringBuildersb;字符串,存放切割出的字词booleanisLetter(charch)判断ch是否为字母booleanisDigit(charch)判断是否为数字booleanisKeyWord(String)判断是否为关键字booleanisOperator(char)判断是否为运算符booleanisSeparators(char)判断是否为分隔符voidwriteFile(Stringstr1,StringBuildernumber)按照二元式规则写入文件三、系统编码及运行(一)系统开发涉及的软件WPS文字、eclipse、5(二)系统运行界面及结果6四、系统测试7五、总结通过此次实验,让我了解到如何设计、编制并调试词法分析程序,熟悉了构造词法分析程序的手工方式的相关原理,加深了对编译原理词法分析的理解,本次使用java语言直接编写此法分析程序,也让我重新熟悉了java语言的相关内容,加深了对java语言的用途的理解。本程序的数据输入采取直接从文件中读取,而不是由键盘输入,因此在测试过程中,输入得到大大简化,但是本程序的关键字表只初始化了一部分关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字),而且程序的测试数据存在不足,程序可能存在未发现的漏洞,以上两点有待改善。附录importjava.io.File;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;8importjava.io.InputStream;publicclassTestLexer{//保留字集staticString[]keyWords={auto,break,case,char,const,continue,default,do,double,else,enum,extern,float,for,goto,if,int,long,register,return,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile,while};//运算符集staticchar[]operators={'+','-','*','/','%','=','','','!','&','|'};//界符集staticchar[]Separators={'[',']','{','}',9'(',')',':','\'','','#',';'};publicstaticvoidmain(String[]args)throwsException{//读取文件Filef=newFile(d:/aa.txt);FileReaderr=newFileReader(f);char[]cs=newchar[(int)f.length()];intlength=r.read(cs);System.out.println(cs);System.out.println(--------------------------------------------------------);intflag=0;StringBuildersb=newStringBuilder();for(inti=0;ics.length;i++){//如果是字母if(isLetter(cs[i])){10if(cs[i+1]!=''&&!isDigit(cs[i+1])&&!isOperator(cs[i+1])&&!isSeparator(cs[i+1])&&!isOperator(cs[i+1])){//如果后一个字符不是空格sb.append(cs[i]);continue;}else{sb.append(cs[i]);if(isKeyWord(sb)){writeFile(3,sb);sb=newStringBuilder();}else{writeFile(1,sb);sb=newStringBuilder();}continue;}}else{//如果是数字if(isDigit(cs[i])){if(isDigit(cs[i+1])){//如果前后都是数字的话11sb.append(cs[i]);continue;}else{sb.append(cs[i]);writeFile(2,sb);sb=newStringBuilder();continue;}}//如果是界符if(isSeparator(cs[i])){sb.append(cs[i]);writeFile(4,sb);sb=newStringBuilder();continue;}//如果是运算符if(isOperator(cs[i])){if(isOperator(cs[i+1])){sb.append(cs[i]);continue;}else{12sb.append(cs[i]);writeFile(5,sb);sb=newStringBuilder();continue;}}}}}//判断是否为数字publicstaticbooleanisDigit(charch){booleanresult=false;if(ch=57&&ch=48){result=true;}returnresult;}//判断是否为字母publicstaticbooleanisLetter(charch){booleanresult=false;13if((ch=65&&ch=90)||(ch=97&&ch=122)){result=true;}returnresult;}//判断是否为关键字publicstaticbooleanisKeyWord(StringBuilderstr){booleanresult=false;Stringstr1=newString(str);for(inti=0;ikeyWords.length;i++){if(keyWords[i].endsWith(str1)){result=true;}}returnresult;}//判断是否为运算符publicstaticbooleanisOperator(charch){14booleanresult=false;for(inti=0;ioperators.length;i++){if(operators[i]==ch){result=true;}}returnresult;}//判断是否为界符publicstaticbooleanisSeparator(charch){booleanresult=false;for(inti=0;iSeparators.length;i++){if(Separators[i]==ch){result=true;}}returnresult;}//按照二元式规则写入文件15publicstaticvoidwriteFile(Stringstr1,StringBuildernumber)throwsIOException{Stringstr=number+\t+(+str1+,+number+);if(str1.endsWith(1)){str=str+\t+\t+