编译原理实验词法分析器的设计.docx
《编译原理实验词法分析器的设计.docx》由会员分享,可在线阅读,更多相关《编译原理实验词法分析器的设计.docx(12页珍藏版)》请在冰豆网上搜索。
编译原理实验词法分析器的设计
集美大学计算机工程学院实验报告
课程名称:
编译原理
班级:
指导教师:
姓名:
实验项目编号:
实验一
学号:
实验项目名称:
词法分析器的设计
实验成绩:
一、实验目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
二、实验内容
编写一个词法分析器,从输入的源程序(编写的语言为C语言的一个子集)中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
三、实验要求
1、 词法分析器的功能和输出格式
词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
单词
示例
单词种别码要求
保留字
if、else、int、while、do
每个保留字的单词种别都单独为一种
标识符
以字母开头且包含字母和数字的字符串
标识符作为一种
常数(只识别无符号整数)
123、343
无符号整数作为一种
运算符
+、-、*、/、=、==、!
=、>、<、>=、<=
每符一种,也可以每一类符号一种
分隔符
、;、{、}、(、)
每符一种
2、上述要求仅为基本要求,可以在此基础上扩充,例如删除注释,增加识别单词的类型,将标识符和常量分别插入到相应的符号表中,增加错误处理等。
3、编程语言不限。
四、实验设计方案
1、数据字典
本实验用到的数据字典如下表所示:
单词
示例
标识ID
保留字
void、if、else、for、while、do、return、break、main、int、float、char、double、String
1
标识符
以字母开头且包含字母和数字的字符串
2
常数(只识别无符号整数)
无符号整数和小数
3
运算符
+、-、*、/、=、>、<、
4
分隔符
、;、{、}、(、)
5
本实验所使用的开发语言是C语言,在Test2类中定义了以下几个函数:
2.程序流程图:
Y
N
YN
N
YY
N
YN
YY
NN
N
YY
NNN
YY
Y
NYN
3、实验程序
#include
#include
#include
#include
//判断读入的字符是否为字母
boolisLetter(charc){
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
returntrue;
}
else
returnfalse;
}
//判断读入的字符是否为数字
boolisDigit(charc){
if(c>='0'&&c<='9'){
returntrue;
}
else
returnfalse;
}
//判断是否为关键字
boolisKey(char*string){
if(!
strcmp(string,"void")||!
strcmp(string,"if")||!
strcmp(string,"for")||!
strcmp(string,"while")
||!
strcmp(string,"do")||!
strcmp(string,"return")||!
strcmp(string,"break")
||!
strcmp(string,"main")||!
strcmp(string,"int")||!
strcmp(string,"float")||!
strcmp(string,"char")
||!
strcmp(string,"double")||!
strcmp(string,"String"))
{
returntrue;
}
elsereturnfalse;
}
boolisError(charch){
if(ch=='@'||ch=='$'||ch=='&'||ch=='#'||ch=='~'||ch=='^')
{
returntrue;
}
else
returnfalse;
}
voidmain()
{
charstring[500]="";//存放文件中读出来的字符串
charstr[10]="";//存放需要对比的字符串
charch,c;//ch存放文件中的单个字符(翻译时用),c存放文件中的单个字符(从文件中提取信息时用)
charfilename[20];//文件名
intj=0;
printf("请输入文件名进行词法翻译:
");
scanf("%s",filename);
FILE*cfPtr;
if((cfPtr=fopen(filename,"r"))==NULL)
printf("文件未找到!
");
else{
while(!
feof(cfPtr)){
if(isspace(c=fgetc(cfPtr))){//判断是否是字符串
;
}else{
string[j]=c;//从文件中一一提取字符
j++;
}
}
}
intm=0,k=0;//m翻译时用,k是str数组的下标
string[j]='';
j++;
boolcheck=true,error=false;//用于判断标识
for(inti=0;iswitch(m)
{
case0:
ch=string[i];
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='='
||ch=='>'||ch=='<')
{
if(error){
printf("%s,此字符无法是识别!
\n",str);
error=false;
check=true;
}elseif(!
check){
printf("(2,%s)标示符\n",str);
check=true;
}
m=4;
}
elseif(ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')')
{
if(error){
printf("%s此字符无法识别\n",str);
error=false;
check=true;
}elseif(!
check){
printf("(2,%s)标示符\n",str);
check=true;
}
m=5;
}
elseif(isDigit((ch=string[i])))
{
if(check){
memset(str,0,strlen(str));//清空
k=0;
str[k]=ch;
k++;
m=3;
check=false;
}else{
str[k]=ch;
k++;
}
}
elseif(isLetter(ch=string[i]))
{
if(check){
check=false;
memset(str,0,strlen(str));
k=0;
str[k]=ch;
k++;
}else{
str[k]=ch;
k++;
if(isKey(str))
{
printf("(1,%s)关键字\n",str);
check=true;
}
}
}elseif(isError(ch=string[i])){
if(check){
memset(str,0,strlen(str));//清空
k=0;
str[k]=ch;
k++;
check=false;
error=true;
}else{
str[k]=ch;
k++;
error=true;
}
}else{}
break;
case3:
if(isLetter(ch=string[i])){
printf("程序有错误\n");
str[k]=ch;
k++;
error=true;
m=0;
break;
}
if(isError(ch=string[i])){
printf("程序有错误\n");
str[k]=ch;
k++;
error=true;
m=0;
break;
}
if(isDigit((ch=string[i])))
{
str[k]=ch;
k++;
}elseif(ch=='.'){
str[k]=ch;
k++;
}
else
{
printf("(3,%s)数字\n",str);
i--;
m=0;
check=true;
}
break;
case4:
i--;
printf("(4,%c)运算符\n",ch);
m=0;
break;
case5:
i--;
printf("(5,%c)分隔符\n",ch);
m=0;
break;
}
}
return;
}
五、实验结果
六、实验小结
本次实验中,运用C语言进行实验,实验刚开始的时候,能够对输入的字符进行判断,但是却不能排错以及只能识别全是字母的标识符,后来经过修改程序代码和编程的逻辑最