编译原理词法分析课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DONGFANG COLLEGE,FUJIAN AGRICULTURE AND FORESTRY UNIVERSITY
课程名称:编译原理
词法分析
系别:计算机科学系
年级专业: 2013级计算机科学与技术
学号: 1350303059
姓名:张清鉴
任课教师:朱均燕成绩:
2015 年12 月31 日
目录
前言 (1)
一、课程设计的目的 (1)
二、课程设计的要求 (1)
1.待分析的简单语言的词法 (1)
2.各种单词符号对应的种别码 (2)
3. 此法分析程序功能 (3)
三、课程设计报告内容 (3)
3.1课程设计的环境 (3)
3.2系统技术分析: (3)
3.3 系统流程图及各模块 (4)
3.4源程序代码清单 (4)
3.5程序调试情况 (9)
四、总结 (10)
参考文献 (11)
前言
词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。
进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。
词法分析器一般以函数的形式存在,供语法分析器调用。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用Lex等工具自动生成。
词法分析是编译程序的第一个阶段且是必要阶段;词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:自动生成,手工生成.
词法分析
一、课程设计的目的
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、课程设计的要求
1.待分析的简单语言的词法
(1)关键字:begin if then while do end
所有的关键字都是小写。
(2)运算符和界符::= + - * / <<=<>>>==:
()#
(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
(4)空格由空白\制表符\和换行符组成。
空格一般用来分隔ID\NUM\运算符\界符和关键字,词法分析阶段通常被忽略。
2.各种单词符号对应的种别码
表C.1各种单词符号对应的种别码
3.此法分析程序功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或s u m)构成的序列。
其中:s y n为单词种别码;token为存放的单词自身字符串;s u m为整型常数。
例如:对源程序
begin x:=9: if x>9 then x:=2*x+1/3; end # 的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
三、课程设计报告内容
3.1课程设计的环境
3.1.1 硬件环境:本系统适用于DOS环境下的计算机,内存1G、2G等现在较普遍的内存容量即可,并且配备有主机、显示屏、键盘和鼠标等硬件结构。
3.1.2 软件环境:本系统采用标准C语言,可在基于Windows操作系统的可视化集成开发环境的Visual C++ 6.0 使用。
3.2系统技术分析:
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
主程序示意图如图3-1所示。
其中初始包括以下两个方面:
图3-1
1)关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 2)程序中需要用到的主要变量为syn,token和sum。
3.3 系统流程图及各模块
首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;
③syn用来存放单词符号的种别码。
扫描子程序主要部分流程如图3-2所示。
图3-2
3.4源程序代码清单
#include <stdio.h>
#include <string.h>
char prog[80],token[8],ch;
int syn,p,m,n,sum;
char *rwtab[6]={"begin","if","then","while","do","end"};
scaner();
main()
{p=0;
printf("\n please input a string(end with '#'):/n");
do{
scanf("%c",&ch);
prog[p++]=ch;
}while(ch!='#');
p=0;
do{
scaner();
switch(syn)
{case 11:printf("( %-10d%5d )\n",sum,syn);
break;
case -1:printf("you have input a wrong string\n");
getch();
exit(0);
default: printf("( %-10s%5d )\n",token,syn);
break;
}
}while(syn!=0);
getch();
}
scaner()
{ sum=0;
for(m=0;m<8;m++)token[m++]=NULL;
ch=prog[p++];
m=0;
while((ch==' ')||(ch=='\n'))ch=prog[p++];
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
{ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<=' 9')))
{token[m++]=ch;
ch=prog[p++];
}
p--;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{ syn=n+1;
break;
}
}
else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
}
else switch(ch)
{ case '<':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{ syn=22;
token[m++]=ch;
}
else
{ syn=20;
p--;
}
break;
case '>':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{ syn=24;
token[m++]=ch;
}
else
{ syn=23;
p--;
break;
case '+': token[m++]=ch; ch=prog[p++];
if(ch=='+')
{ syn=17;
token[m++]=ch; }
else
{ syn=13;
p--;
}
break;
case '-':token[m++]=ch; ch=prog[p++];
if(ch=='-')
{ syn=29;
token[m++]=ch; }
else
{ syn=14;
p--;
}
break;
case '!':ch=prog[p++]; if(ch=='=')
{ syn=21;
token[m++]=ch; }
{ syn=31;
p--;
}
break;
case '=':token[m++]=ch; ch=prog[p++];
if(ch=='=')
{ syn=25;
token[m++]=ch; }
else
{ syn=18;
p--;
}
break;
case '*': syn=15;
token[m++]=ch;
break;
case '/': syn=16;
token[m++]=ch;
break;
case '(': syn=27;
token[m++]=ch;
break;
case ')': syn=28;
token[m++]=ch;
break;
case '{': syn=5;
token[m++]=ch;
break;
case '}': syn=6;
token[m++]=ch;
break;
case ';': syn=26;
token[m++]=ch;
break;
case '\"': syn=30;
token[m++]=ch;
break;
case '#': syn=0;
token[m++]=ch;
break;
case ':':syn=17;
token[m++]=ch;
break;
default: syn=-1;
break;
}
token[m++]='\0';
}
3.5程序调试情况
输入begin x:=9: if x>0 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图5-1所示:
图5-1
四.总结
通过此次课程设计,使我更加扎实的掌握了有关词法方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。
过而能改,善莫大焉。
在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。
最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。
这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。
在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永
远不可能得到社会及他人对你的认可!
参考文献
[1]刘铭,徐兰芳,骆婷.编译原理. 北京:电子工业出版社,2011. 32~49
[2]吕映芝.编译原理.清华大学出版社,2013. 52~65
[3]张素琴,吕映芝,等.编译原理.清华大学出版社,2005. 59~72
[4]李赣生.编译原理.清华大学出版社,2009. 36~61。