简单词法分析程序设计.docx
《简单词法分析程序设计.docx》由会员分享,可在线阅读,更多相关《简单词法分析程序设计.docx(9页珍藏版)》请在冰豆网上搜索。
简单词法分析程序设计
实验一 简单词法分析程序设计
一、实验目的
了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造方法。
二、实验内容
1、了解编译程序的词法分析过程。
2、根据PASCAL语言的说明语句形式,用手工方法构造一个对说明语句进行词法分析的程序。
该程序能对从键盘输入或从文件读入的形如:
“constcount=10,sum=81.5,char1=’f’,string1=”hj”,max=169;”
的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。
三、实验要求
1、输入的常量说明串,要求最后以分号作结束标志;
2、根据输入串或读入的文本文件中第一个单词是否为“const”判断输入串或文本文件是否为常量说明内容;
3、识别输入串或打开的文本文件中的常量名。
常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线;
4、根据各常量名紧跟等号“=”后面的内容判断常量的类型。
其中:
字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、-号,不以0开头的若干数字的组合;实型常量定义为带或不带+、-号,不以0开头的若干数字加上小数点再后跟若干数字的组合;
5、统计并输出串或文件中包含的各种类型的常量个数;
6、以二元组(类型,值)的形式输出各常量的类型和值;
7、根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。
四、运行结果
1、输入如下正确的常量说明串:
constcount=10,sum=81.5,char1=‘f’,max=169,str1=“h*542..4S!
AAsj”,char2=‘@’,str2=“aa!
+h”;
输出:
count(integer,10)
sum(float,81.5)
char1(char,‘f’)
max(integer,169)
str1(string,“h*542..4S!
AAsj”)
char2(char,‘@’)
str2(string,“aa!
+h”)
int_num=2;char_num=2;string_num=2;float_num=1.
2、输入类似如下的保留字const错误的常量说明串:
Aconsttcount=10,sum=81.5,char1=‘f’;
输出类似下面的错误提示信息:
Itisnotaconstantdeclarationstatement!
Pleaseinputastringagain!
3、输入类似如下含常量名或常量值错误的常量说明串:
constcount=10,12sum=81.5,char1=‘ff’,max=0016;
输出类似下面的错误提示信息:
count(integer,10)
12sum(Wrong!
Itisnotaidentifier!
)
char1(Wrong!
Therearemorethanonecharin‘’.)
max(Wrong!
Theintegercan’tbestartedwith‘0’.)
int_num=1;char_num=0;string_num=0;float_num=0.
4、其他类型的错误处理情况(略)。
五、提示
本实验重点有三个:
一是作为常量名的标识符的识别;二是如何根据“=”后出现的内容来判断常量类型;三是对各种错误的处理。
难点是对整型和实型常量的判断必须综合考虑多种可能情况。
建议:
1、用指针或数组与指针相结合来处理输入的常量说明串;2、对整型和实型常量处理时,重点考虑常数中‘0’的位置。
六、分析与讨论
1、若考虑用E或e的科学计数法来表示整数和实数,应该如何实现?
2、若考虑布尔型常量,且规定其值只能为true或false,应该如何实现?
3、如何对手工构造的词法分析程序做进一步的优化,以提高代码质量和运行效率?
七.代码
#include"stdio.h"
#include"ctype.h"
#include
#include
#include
#defineN80
#defineM16
char*p0,*t0,*p1,*t1,*p2,*str,*p3,*t3="const",*digi,*flo;
charcha;
intci=0,cf=0,cc=0,cs=0;
voidmain()
{
voidmeasurefw();
voidmeasure_iden();
voidmeasure_str();
voidmeasure_digit();
voidmeasure_cha();
printf("\nInputstring:
\n");
p0=(char*)malloc(N*sizeof(char));
p1=(char*)malloc(M*sizeof(char));
p2=(char*)malloc(M*sizeof(char));
p3=(char*)malloc(M*sizeof(char));
gets(p0);
printf("\n");
measurefw();
/*开始处理输入串p0*/
while(*(p0)==''||*(p0)==',')/*从串p0中取标识符,并将其作为常量名存放到串p1中*/
{
p0++;
if(*(p0)==''||*(p0)==',')
continue;
else
{
measure_iden();//*p0=="="
if(!
isdigit(*p0)&&*p0!
='\"'&&*p0!
='\'')//注意'和"做字符表示时用\'和\"
{
system("cls");
printf("\nConstdataiswrong.Exit!
");
exit(0);
}
elseif(*p0=='\"')/*处理字符串常量*/
{
p0++;
measure_str();
}
elseif(isdigit(*p0))/*处理数字*/
{
measure_digit();
}
elseif(*p0=='\'')//处理字符常量
{
p0++;
measure_cha();
}
}
}
if(*p0!
=';')
{
system("cls");
printf("\nThiscentenceiswrong.Exit!
");
exit(0);
}
else
{
printf("int_num=%d;char_num=%d;string_num=%d;float_num=%d.\n",ci,cc,cs,cf);
}
}
voidmeasurefw()
{
while(*p0!
='')/*检查输入串是否以"'const"开头*/
{
if(*p0==*t3)
{
p0++;
t3++;
}
else
{
system("cls");
printf("\nThisstringisn'taconstdeclaration!
");
exit(0);
}
}
//printf("Thisstringisaconstdeclaration!
\n");
}
voidmeasure_iden()
{
if(*p0!
='_'&&(!
isalpha(*p0)))
{
system("cls");
printf("\nConstnameiswrong.Exit!
");
exit(0);
}
elseif(*p0=='_'||isalpha(*p0))
{
t1=p1;
while(*p0!
='=')
{
*p1=*p0;
p0++;
p1++;
}
*p1='\0';
//printf("%s\n",p0);
p0++;
}
printf("%s",t1);
}
voidmeasure_str()
{
str=p2;
while(*(p0)!
='\"')
{
*p2=*p0;
if(*(p0)==';')//丢了个分号,直接输出Stringdataiswrong.Exit
{
system("cls");
printf("\nStringdataiswrong.Exit!
");
exit(0);
}
p0++;
p2++;
}
*p2='\0';
p0++;
cs++;
printf("(string,\"%s\")\n",str);
}
voidmeasure_digit()
{
char*jud;
intmark=0;
jud=p0;
for(;*(jud)!
=','&&*(jud)!
=';';jud++)
{
if(*jud=='.')
{
mark=1;
break;
}
}
if(mark==0)
{
digi=p2;
while(*p0!
=','&&*p0!
=';')
{
*p2=*p0;
p0++;
p2++;
}
*p2='\0';
ci++;
printf("(integer,%s)\n",digi);
}
if(mark==1)
{
flo=p2;
while(*p0!
=','&&*p0!
=';')
{
*p2=*p0;
p0++;
p2++;
}
*p2='\0';
cf++;
printf("(float,%s)\n",flo);
}
}
voidmeasure_cha()
{
char*jud;
jud=p0;
if(*(jud+1)=='\''&&*(jud)!
='\'')
{
cha=*p0;
p0=p0+2;
cc++;
}
else
{
system("cls");
printf("\nchardataiswrong.Exit!
");
exit(0);
}
printf("(char,'%c')\n",cha);
}