编译原理实验11365400017陈志颖.docx
《编译原理实验11365400017陈志颖.docx》由会员分享,可在线阅读,更多相关《编译原理实验11365400017陈志颖.docx(13页珍藏版)》请在冰豆网上搜索。
编译原理实验11365400017陈志颖
广州大学学生实验报告
开课学院及实验室:
计算机科学与工程实验室416A2015年12月22日
学院
计算机科学与教育软件学院
年级/专业/班
计机二141
姓名
陈志颖
学号
11365400017
实验课程名称
编译原理实验
成绩
实验项目名称
词法分析
指导老师
冯元勇
评语:
一、实验目的
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、基本知识
1、正则表达式
2、正则表达式到有限自动机的转换
3、有限自动机的确定化与最小化
三、实验环境
1、Windows操作系统
2、C/C++/Java语言
四、实验要求
1、做好实验预习,掌握并熟悉本实验中所使用的编程、测试环境及相应的软件
2、写出实验报告
五、实验内容
1、待分析的C语言子集的词法
1)关键字
mainifelseintreturnvoidwhile(都是小写)
2)专用符号
=+—*/<<=<>===!
=;:
,{}[]()
3)其他标记
STRING:
:
="[^"]*"
ID:
:
=letter(letter|digit)*
INT:
:
=digitdigit*
letter:
:
=a|…|z|A|…|Z
digit:
:
=0|…|9
4)空格由空白、制表符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
2、部分单词符号对应的种别码(可自行扩展)
单词符号
种别码
单词符号
种别码
main
1
/
25
int
2
(
26
char
3
)
27
if
4
[
28
else
5
]
29
for
6
{
30
while
7
}
31
return
8
32
void
9
:
33
STRING
50
;
34
ID
10
>
35
INT
20
<
36
=
21
>=
37
+
22
<=
38
-
23
==
29
*
24
!
=
40
3、词法分析程序的功能
输入:
所给文法的源程序字符串
输出:
二元组(syn,token或sum)构成的序列。
其中syn为单词种别码;token为存放的单词自身字符串;sum为整型常量(作为常量的值)。
实现时,可将单词的二元组用结构进行处理
代码:
#include
#include
usingnamespacestd;
boolisLetter(charb){
if((b>='a'&&b<='z')||(b>='A'&&b<='Z'))returntrue;
returnfalse;
}
boolisLetterOrDigit(charb){
if((b>='a'&&b<='z')||(b>='A'&&b<='Z')||(b>='0'&&b<='9')||b==EOF)returntrue;
returnfalse;
}
boolID(charb,chard[]){
boolflag;inti=1;
for(flag=false;(flag=isLetterOrDigit(b))&&b!
=EOF;d[i++]=b,b=getchar());
if(flag)returntrue;
else{
returnfalse;
}
}
voidmain(){
inti=0,j,k=0,state=1,f=0,linenum=1;
chara[9][10]={"main","int","char","if","else","for","while","return","void"};
charb,d[40]={"\0"};
freopen("E:
//input.txt","r",stdin);
freopen("E:
//output.txt","w",stdout);
b=getchar();
while(b!
=EOF)/*判断所输入字符是否为结束符*/{
if(b==''||b=='\n'||b=='\t')/*滤过空格、换行等分隔符号*/{
if(b='\n')linenum++;
b=getchar();
}
elseif((b>='a'&&b<='z')||(b>='A'&&b<='Z'))/*识别ID以及保留字*/{
d[i++]=b;
b=getchar();
while((b>='a'&&b<='z')||(b>='A'&&b<='Z')||(b>='0'&&b<='9')){
d[i++]=b;
b=getchar();
}
for(j=0;j<9;j++)/*查询保留字表确定该单词是否是保留字*/{
if(strcmp(d,a[j])==0){
cout<k=1;
break;
}
}
if(k==0)/*在保留字表中没有查到该单词,是ID*/
cout<<"20,"<for(j=0;j<=i;j++)
d[j]='\0';
i=0;
k=0;
}
elseif(b=='\"'){/*识别STRING*/
do{
d[i++]=b;
b=getchar();
}while(b=='\"');
cout<<"10,"<b=getchar();
for(j=0;j<=i;j++)d[j]='\0';
i=0;
}
elseif(b>='0'&&b<='9')/*识别常数*/{
boolc=true;
while(c){
d[i++]=b;
b=getchar();
if(b!
='0'&&b!
='1'&&b!
='2'&&b!
='3'&&b!
='4'&&b!
='5'&&b!
='6'&&b!
='7'&&b!
='8'&&b!
='9'){
c=false;
}
}
cout<<"20,"<for(i=0;i<39;i++)d[i]=0;
i=0;
}
elseif(b=='!
'){/*识别'!
='*/
d[i++]=b;
b=getchar();
if(b=='='){
d[i++]=b;
b=getchar();
cout<<"40,"<i=0;
d[1]=0;
}
}
elseif(b=='='){/*识别'='和'=='*/
d[i++]=b;
b=getchar();
if(b=='='){
d[i++]=b;
b=getchar();
cout<<"29,"<i=0;
d[1]=0;
}
else{
cout<<"21,"<i=0;
}
}
elseif(b=='*'){/*识别运算符*/
d[i++]=b;
b=getchar();
cout<<"24,"<i=0;
}
elseif(b=='/'){/*识别运算符*/
d[i++]=b;
b=getchar();
cout<<"25,"<i=0;
}
elseif(b=='+'){/*识别运算符*/
d[i++]=b;
b=getchar();
cout<<"22,"<i=0;
}
elseif(b=='-'){/*识别运算符*/
d[i++]=b;
b=getchar();
cout<<"23,"<i=0;
}
elseif(b=='<'){/*识别'<'、'<='*/
d[i++]=b;
b=getchar();
if(b=='='){
d[i++]=b;
b=getchar();
cout<<"38,"<i=0;
d[1]=0;
}
else{
cout<<"36,"<i=0;
}
}
elseif(b=='>'){/*识别'>'和'>='*/
d[i++]=b;
b=getchar();
if(b=='='){
d[i++]=b;
b=getchar();
cout<<"37,"<i=0;
d[1]=0;
}
else{
cout<<"35,"<i=0;
}
}
elseif(b==':
'){/*识别':
'*/
d[i++]=b;
b=getchar();
cout<<"33,"<i=0;
}
elseif(b==','){/*识别','*/
d[i++]=b;
b=getchar();
cout<<"32,"<i=0;
}
elseif(b==';'){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"34,"<i=0;
}
elseif(b=='('){/*识别'('*/
d[i++]=b;
b=getchar();
cout<<"26,"<i=0;
}
elseif(b==')'){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"27,"<i=0;
}
elseif(b=='['){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"28,"<i=0;
}
elseif(b==']'){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"29,"<i=0;
}
elseif(b=='{'){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"30,"<i=0;
}
elseif(b=='}'){/*识别';'*/
d[i++]=b;
b=getchar();
cout<<"31,"<i=0;
}
}
}
试验结果: