编译原理1.docx
- 文档编号:6247440
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:13
- 大小:70.88KB
编译原理1.docx
《编译原理1.docx》由会员分享,可在线阅读,更多相关《编译原理1.docx(13页珍藏版)》请在冰豆网上搜索。
编译原理1
一、课程设计内容和要求
设计一个程序,进行调试,并利用编译来实现词法分析的功能,识别各单词或字符所属类别,并显示在屏幕上。
主要目的是为了掌握词法分析的基本原理,理解词法分析在编译程序过程中的作用,熟悉关键字表等相关的数据结构与单词的分类方法,加深对编译原理的理解,掌握词法分析器的实现方法和技术。
二、词法分析识别的语言介绍
词法分析程序完成打的是编译第一阶段的工作,它的主要任务是从左至右逐个字符的对源程序进行扫描,产生一个个单词序列,用以语法分析。
本程序是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件作为语法分析程序的输入而继续编译过程。
词法分析需解决的首要问题是如何正确的获得一个单词,并判断它的类型,本程序设定了三种单词类型,分别为:
关键字、标识符、常数、运算符和界符。
需要识别的关键字及其识别码有:
(1)关键字"begin","end","if","then","else","while","write","read"等,"do","call","const","char","until","procedure","repeat"等
(2)运算符:
"+","-","*","/","="等
(3)界符:
"{","}","[","]",";",",",".","(",")",":
"等
(4)标识符
(5)常量
三、流程图
图3总流程图
四、程序设计:
总体设计,子程序设计
1.总体设计:
(1)标识符的识别
(2)关键字的识别
(3)常数的识别:
整数,实数,指数形式表示的数
(4)界符的识别
(5)算符的识别(注意区分:
单目,双目的区分+,++,+=)
(6)关系比较符的识别(注意区分:
单目,双目>,>=)
(7)字符常量的识别
(8)字符串常量的识别
(9)错误处理
2.子程序设计:
各模块概要设计
判断当前读入的字符是字母还是数字
intIsLetter(charch)//判断ch是否为字母
{if(ch是A~Z或a~z)return1;
elsereturn0;}
intIsDigit(charch)//判断ch是否为数字
{if(ch是0~9)return1;
elsereturn0;}
将读入的字符连接成单词或数
while(IsLetter(ch)||IsDigit(ch))
{Concat();//将ch中的字符拼接到strToken中
ch=GetChar();}
查表判断当前的独立串是关键字、标示符还是常数
求出当前的独立串的code和value
3.字符集定义:
关键字:
BEGIN,END,IF,THEN,ELSE,for,do,while
<标识符>--><字母>|<标识符><字母>|<标识符><数字>
<无符号整数>--><数字>|<无符号整数><数字>
<分界符>-->+|-|*|/|;|(|)|{|}|<|<=|=|!
=|>=|>|:
=|<空格>
<字母>-->a|…|z|A|…|Z
<数字>-->0|…|9
<空格>-->’’
五、程序中的结构说明:
结构体、符号表等
1、识别语言的词法:
(1)关键字"begin","end","if","then","else","while","write","read"等,
"do","call","const","char","until","procedure","repeat"等
(2)运算符:
"+","-","*","/","="等
(3)界符:
"{","}","[","]",";",",",".","(",")",":
"等
(4)标识符
(5)常量
2、词法的编码表:
表1关键字编码
关键字
编码
关键字
编码
关键字
编码
关键字
编码
Auto
1
Do
9
goto
17
sizeof
25
Break
2
Double
10
if
18
static
26
Case
3
Else
11
int
19
switch
27
Char
4
Struct
12
long
20
typedef
28
Const
5
Enum
13
register
21
union
29
Return
6
Extern
14
void
22
unsigned
30
Continue
7
Float
15
short
23
volatile
31
Default
8
For
16
signed
24
while
32
表2界符编码
界符
,
;
{
}
(
)
[
]
“
编码
501
502
503
504
505
506
507
508
509
表3运算符编码
运算符
编码
运算符
编码
运算符
编码
运算符
编码
+
401
/=
409
==
417
%=
425
=
402
/
410
=
418
>>
426
++
403
!
=
411
&&
419
<<
427
--
404
!
412
&
420
|
428
-=
405
>=
413
||
421
^
429
-
406
>
414
.
422
%
430
*=
407
<=
415
>
423
*
408
<
416
~
424
六、程序测试
1、运行测试:
运行程序,根据提示,输入源文件名fenxi.txt,显示词法分析结果如下图:
运行程序,输入另一个源文件名bianyi.txt,显示此法分析结果如下图:
2、源代码:
#include"stdio.h"
#include"string.h"
charkeywordtable[32][10]=
{"auto","double","int","struct",
"break","else","long","switch","case",
"enum","register","typedef","char","extern",
"return","union","const","float",
"short","unsigned","continue","for",
"signed","void","default","goto","sizeof",
"volatile","do","if","static","while"
};
charcaculatetable[20]={'+','-','*','/','%','(',')','=','>','<','#'};
charpartitiontable[20]={';','.','','{','}','"',','};
structpoint
{
char*kind;
charvalue[33];
};
intIsLetter(charch)
{
if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')
return1;
else
return0;
}
intIsDigit(charch)
{
if(ch>='0'&&ch<='9')
return1;
else
return0;
}
intReserve(charstrToken[33])
{
inti;
for(i=0;i<32;i++)
{
if(strcmp(keywordtable[i],strToken)==0)
return1;
}
return0;
}
voidoperate(FILE*fp,structpointa)
{
fp=fopen("result.txt","a+");
fprintf(fp,"<%s,%s>\n",a.kind,a.value);
fclose(fp);
}
voidRetract(FILE*fp)
{
fseek(fp,-1L,1);
}
voidPrint(structpointa)
{
printf("<%s,\"%s\">\n",a.kind,a.value);
}
intIsPatition(charch)
{
inti;
for(i=0;i<20;i++)
if(partitiontable[i]==ch)
return1;
return0;
}
intIsCaculator(charch)
{
inti;
for(i=0;i<20;i++)
if(caculatetable[i]==ch)
return1;
return0;
}
intIsSpecial(charch)
{
if(ch=='+'||ch=='-'||ch=='/'||ch=='%'||ch=='>'||ch=='<'||ch=='*'||ch=='=')
return1;
return0;
}
intmain()
{
intcode;
structpointresult;
charstrToken[33];
charch;
char*p;
FILE*fp,*fq;
fp=fopen("source.txt","r");
if(fp==NULL)
{
printf("filedoesnotexit!
!
");
return-1;
}
while
(1)
{
p=strToken;
ch=fgetc(fp);
if(feof(fp))
break;
if(ch=='')
continue;
if(IsLetter(ch))
{
while(IsLetter(ch)||IsDigit(ch))
{
*p=ch;
p++;
*p='\0';
ch=fgetc(fp);
if(feof(fp))
return-1;
}
Retract(fp);
code=Reserve(strToken);
if(code==1)
{
result.kind="keyword";
strcpy(result.value,strToken);
operate(fq,result);
Print(result);
}
else
{
result.kind="Identifier";
strcpy(result.value,strToken);
operate(fq,result);
Print(result);
}
}
elseif(IsDigit(ch))
{
while(IsDigit(ch))
{
*p=ch;
p++;
*p='\0';
ch=fgetc(fp);
if(feof(fp))
return-1;
}
Retract(fp);
result.kind="Digit";
strcpy(result.value,strToken);
operate(fq,result);
Print(result);
}
elseif(IsPatition(ch)||IsCaculator(ch))
{
if(IsPatition(ch))
{
result.kind="PatitionIdentifier";
*p=ch;
p++;
*p='\0';
strcpy(result.value,strToken);
operate(fq,result);
Print(result);
}
if(IsCaculator(ch))
{
charch2;
ch2=fgetc(fp);
if(!
IsCaculator(ch2))
Retract(fp);
result.kind="CaculatorIdentifier";
*p=ch;
p++;
*p='\0';
if(IsSpecial(ch)&&ch2=='=')
{
*p=ch2;
p++;
*p='\0';
}
if((ch=='>'||ch=='<'||ch=='+'||ch=='-')&&ch2==ch)
{
*p=ch2;
p++;
*p='\0';
}
strcpy(result.value,strToken);
operate(fq,result);
Print(result);
}
}
else
{
if(ch=='\n')
continue;
result.kind="Error!
!
";
strcpy(result.value,strToken);
operate(fq,result);
printf("Erroroccurs!
at%c\n",ch);
}
}
return1;
}
七、实验总结
经过此次实验,我了解了程序的词法构词规则和词法分析过程。
在实验过程中,得到了同学的帮助才得以完成。
本实验基本达到了老师的要求,实现了词法分析的基本功能。
程序运行的结果显示,程序能识别C语言的大部分符号,并能够正确分割成词法模块,得出正确的识别结果。
程序设计中用到了很多的编译原理课程重的知识,如为了识别“+”和“++”采用了超前搜索,回退的方法。
程序中普遍采用的算法,如“关键字”的时候则是穷举匹配关键字表中的标识符。
实验的难点是如何区分不用的词法单位,回退的判定等。
这次实验,实践了编译原理中关于状态转换图,自动机在匹配词法方面的应用,课程中词法分析设计原理的实现,在课本的指导下,一点点分析词法分析器的功能,并努力实现它,掌握了课程设计内容的同时也锻炼了自己分析解决问题的能力以及编程能力,收获很大。
指导教师签字:
年月日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理