编译原理词法分析器课程设计.docx
- 文档编号:23969263
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:14
- 大小:52.30KB
编译原理词法分析器课程设计.docx
《编译原理词法分析器课程设计.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器课程设计.docx(14页珍藏版)》请在冰豆网上搜索。
编译原理词法分析器课程设计
2009-2010学年第二学期
《编译原理》课程设计报告
学院(系):
计算机科学与技术学院
班级:
09计科专升本二班
******
学号:
*********
*******
时间:
2010年6月
目 录
第1章概述
1.1编译原理概述
编译原理是介绍编译器构造的一般原理和实现方法的课程,其中包括词法分析、语法分析、语义分析、中间代码生成、目标代码生成优化、独立于机器的优化和依赖于机器的优化等。
编译器技术的发展,特别是计算机体系结构的发展对编译技术的推动,使其成为计算机专业人士所必需具备的基础知识之一。
1.1.1词法分析器概述
词法分析器是通过词法分析程序对构成源程序的字符串从左到右的扫描,逐个字符地读入源程序字符并按照构词规则切分成一个一个具有独立意义的单词。
并确定其属性(如保留字、标识符、运算符、界限符和常量等)。
再把它们转换称长度统一的标准形式——属性字(TOKEN)。
而词法分析器的功能是输入源程序,输出单词符号,并且词法分析器有两种处理结构:
一种是把词法分析器作为主程序;另一种是把词法分析器作为语法分析程序调用的子程序。
下面我所要介绍的词法分析器是第一种把它作为主程序。
第2章词法分析器课程设计
2.1课程设计目的
通过课程设计进一步理解高级语言在计算机中的执行过程,加深对编译原理中重点算法和编译技术的理解,提高自己的编程能力,培养好的程序设计风格。
同时通过某种可视化编程语言的应用,具备初步的Windows环境下的编程思想
2.2课程设计要求及内容
2.2.1词法分析器设计内容及要求
(1)设计内容:
运用所学习的编程工具编写词法分析器,本次设计我采用C++编写实现其输入输出功能。
(2)设计要求及说明:
完成下述文法所描述的单词符号的词法分析程序。
<标识符>--><字母>|<标识符><字母>|<标识符><数字>
<无符号整数>--><数字>|<无符号整数><数字>
<分界符>-->+|-|*|/|;|(|)|{|}|<|<=|=|!
=|>=|>|=|<空格>
<字母>-->a|…|z|A|…|Z
<数字>-->0|…|9
<空格>-->’’
说明:
1>假定该语言对字母的大小写不敏感,由指定文件读入预分析的源程序,分析结果再写入指定文件;
2>语言关键字为:
"if","else","then","for","while","do";
第3章问题分析及相关原理介绍
3.1设计思想及算法
(1)主要算法的设计:
该词法分析器首先扫描文件,识别出一系列具有独立意义的基本语法单位——单词,包括关键字、保留字、标识符、各种常数、各种运算符及界符等。
由于我们规定的c++语言程序语句中涉及单词较少,所以在词法分析阶段忽略了单词输入错误的检查,并在扫描后输出单词符号。
规定输出的单词符号格式为如下的二元式:
(单词种别,单词自身的值)。
c++语言中定义了属于这五种类型的大量的单词,但是由于预编译器只识别我们自定义的注释,因此预编译器处理的单词集只是c++语言中定义的单词集的一个真子集。
(2)算法实现
<1>fopen()打开源文件,读入字符,对文件进行扫描,把读入的字符放入缓冲区中,然后对该字符进行判断。
<2>若是字母开头,则可能是关键字或者标识符,因此进入letterprocess()进行识别。
识别的过程为:
将以字母开头的字母数字串放入charletter[30]中,然后进行识别。
识别的过程是先让它与保留关键字表中的所有关键字进行匹配,若获得成功则说明它是关键字,则输出其二元式;否则说明其为标识符,这时,将它与标识符表char*label[20]中的元素进行匹配,如没有与之相匹配的,则为其申请空间,将其放入标识符表中。
并输出其二元式。
<3>若是数字开头,则可能是常量,因此进入numberprocess()进行识别。
识别的过程为:
将其与常量表charnum[20]中的元素进行匹配,如没有与之相匹配的,则为其申请空间,将其放入标识符表中。
并输出其二元式。
<4>否则进入otherprocess()识别当前是其它字符。
在识别关系运算符的时候,有可能是两个字符为一个关系运算符,所以在识别的时候要判断连续的两个是否为一个关系运算符。
3.2算法实现及模拟
3.1.1数据结构
(1)关键字:
char*keyword[6]={"if","else","then","for","while","do"};
(2)运算符和界符
char*operatornum[16]={"+","-","*","/","<","<=",">",">=","!
","=","{","}",
";","(",")"};//运算符和界符
(3)常量表和标识符表
char*num[20]:
用于存放文件中的常量;
char*label[20]:
用于存放文件中的标识符。
3.1.2数据模块及功能及说明
(1)search():
查找并识别当前单词类别,并给定单词类别二元式码,决定给定字符串类别码(即单词种别)和记录次序码。
(2)letterprocess():
识别当前是数组、保留字、标识符。
(3)numprocess():
识别当前是常整数、小数、负小数。
(4)otherprocess():
识别当前是其它(标点符号等)。
(5)fopen():
在默认路径下打开分析程序并读入字符串。
第4章设计思路及关键问题的解决方法
4.1设计流程图
画出总控流程图以及取符号、取字符、查找关键字表等子程序的控制流图。
第5章运行结果及测试分析
5.1运行结果及功能说明
……
心得体会
本次课程设计初步培养设计者对编译器设计的思想的了解,加深对编译原理和应用程序的理解。
通过设计调试词法分析程序,实现了从程序中分出各种单词的方法,从而加深了对该知识的理解,提高了词法分析的实践能力。
程序的关键点在于对对给出一段程序中的各种单词的分离。
在每段程序中,单词种类可以分为:
关键字,分界符,算术运算符,关系运算符,标识符和常数。
关键字的判断则是通过与已知数组中列出的元素进行对比,得出该单词是否为关键字;分解符,算术运算符,关系运算符的判断与接受到的字符进行比较,得出该字符是否为分解符,算术运算符或者为关系运算符。
同时在编写程序过程中也遇到了许多问题,如在vc++6.0中运行是出现了错误或是运行结果没有达到预期的效果,而出现了中断等其他的问题,在不断解决问题和发现问题的过程中,我学到了很多,我体会到实践和理论的巨大差别,并且也有所成长。
参考文献
[1]《编译原理》(第2版)陈意云、张昱等编著,高等教育出版社
[2]c++语言语言程序设计(第三版)郑莉,董渊,张瑞丰编著,清华大学出版社
[3]c++程序设计(第二版)谭浩强编著,清华大学出版社
附 录源程序
源程序代码:
//Lex.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
usingnamespacestd;
#defineNULL0
FILE*fp;
charch;
char*keyword[6]={"if","else","then","for","while","do"};//关键字
char*operatornum[16]={"+","-","*","/","<","<=",">",">=","!
=","=","{","}",";","(",")","#"};//运算符和界符
boolsearch(charsearchstr[],intwordtype){//查找是否是系统关键字或运算符或界符
inti;
switch(wordtype){
case1:
for(i=0;i<=5;i++){//判断是否是关键字
if(strcmp(keyword[i],searchstr)==0)
returntrue;
}
case2:
for(i=0;i<=15;i++){//判断是否是运算符或界符
if(strcmp(operatornum[i],searchstr)==0)
returntrue;
}
}
returnfalse;
}
/*******************************************************************/
charletterprocess(charch)//字母处理程序
{
inti=-1;
charletter[30];//定义一个字符串最大长度为30
while(isalnum(ch)!
=0)//判断是否为数字或字母,从文件中获得一个字符串
{
letter[++i]=ch;
ch=fgetc(fp);
};
letter[i+1]='\0';//字符串结束
if(search(letter,1))//调用search方法,判断是否是系统关键字
{
if(strcmp(keyword[0],letter)==0)
cout<<"(1,"< elseif(strcmp(keyword[1],letter)==0) cout<<"(2,"< elseif(strcmp(keyword[2],letter)==0) cout<<"(3,"< elseif(strcmp(keyword[3],letter)==0) cout<<"(4,"< elseif(strcmp(keyword[4],letter)==0) cout<<"(5,"< elseif(strcmp(keyword[5],letter)==0) cout<<"(6,"< } else//若不是关键字,则为一般字符串 { cout<<"(10,'"< } return(ch); } /***********************************************************************************/ charnumberprocess(charch)//数字处理程序 { inti=-1; charnum[20]; while(isdigit(ch)! =0) { num[++i]=ch; ch=fgetc(fp); } if(isalpha(ch)! =0)//判断是否为字母 { while(isspace(ch)==0)//判断是否为空格之类的,如/t,/n,/r等 { num[++i]=ch; ch=fgetc(fp); } num[i+1]='\0'; cout<<"错误! 非法标识符: "< gotou; } num[i+1]='\0';//数字结束 cout<<"(11,"< u: return(ch); } /************************************************************************************/ charotherprocess(charch)//运算符和界符处理程序 { inti=-1; charother[20]; if(isspace(ch)! =0)//判断是否为空格之类的,如/t,/n,/r等 { ch=fgetc(fp); gotou;//若是,就返回该字符 } while((isspace(ch)==0)&&(isalnum(ch)==0))//判断字符串是否结束 { other[++i]=ch; ch=fgetc(fp); } other[i+1]='\0';//标示符结束 if(search(other,2)){//调用search方法,判断是否是运算符或界符 if(strcmp(operatornum[0],other)==0) cout<<"(13,"< elseif(strcmp(operatornum[1],other)==0) cout<<"(14,"< elseif(strcmp(operatornum[2],other)==0) cout<<"(15,"< elseif(strcmp(operatornum[3],other)==0) cout<<"(16,"< elseif(strcmp(operatornum[4],other)==0) cout<<"(20,"< elseif(strcmp(operatornum[5],other)==0) cout<<"(22,"< elseif(strcmp(operatornum[6],other)==0) cout<<"(23,"< elseif(strcmp(operatornum[7],other)==0) cout<<"(24,"< elseif(strcmp(operatornum[8],other)==0) cout<<"(21,"< elseif(strcmp(operatornum[9],other)==0) cout<<"(25,"< elseif(strcmp(operatornum[10],other)==0) cout<<"(17,"< elseif(strcmp(operatornum[11],other)==0) cout<<"(18,"< elseif(strcmp(operatornum[12],other)==0) cout<<"(26,"< elseif(strcmp(operatornum[13],other)==0) cout<<"(27,"< elseif(strcmp(operatornum[14],other)==0) cout<<"(28,"< elseif(strcmp(operatornum[15],other)==0) cout<<"(0,"< }else{ cout<<"错误! 非法标示符: "< } u: return(ch); } /***********************************************************************************/ int_tmain(intargc,_TCHAR*argv[]) { charstr; cout<<"**********************************************************************\n"; cout<<"**\n"; cout<<"*词法分析器*\n"; cout<<"**\n"; cout<<"**********************************************************************\n"; if((fp=fopen("lex.txt","r"))==NULL) cout<<"源程序无法打开! \n"; else { str=fgetc(fp); while(str! =EOF) { if(isalpha(str)! =0)//判断是否为字母(A–Zora–z) str=letterprocess(str); else { if(isdigit(str)! =0)//判断字符是否是数字(0–9) str=numberprocess(str); else//若不是,则执行其他字符处理程序 str=otherprocess(str); } }; cout<<"词法分析结束,谢谢使用! \n"; cout<<"点任意键退出! \n"; } system("pause"); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理词法分析器 课程设计 编译 原理 词法 分析器