您的位置:首页 > 其它

实验一  简单词法分析程序设计

2013-04-22 19:47 501 查看
实验一  简单词法分析程序设计

一、实验目的
了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造方法。
二、实验内容
1、了解编译程序的词法分析过程。
2、根据PASCAL语言的说明语句形式,用手工方法构造一个对说明语句进行词法分析的程序。该程序能对从键盘输入或从文件读入的形如:

“const count=10,sum=81.5,char1=’f’,string1=”hj”, max=169;”
的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。
三、实验要求
1、输入的常量说明串,要求最后以分号作结束标志;
2、根据输入串或读入的文本文件中第一个单词是否为“const”判断输入串或文本文件是否为常量说明内容;
3、识别输入串或打开的文本文件中的常量名。常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线;

4、根据各常量名紧跟等号“=”后面的内容判断常量的类型。其中:字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、-
号,不以0开头的若干数字的组合;实型常量定义为带或不带+、-
号,不以0开头的若干数字加上小数点再后跟若干数字的组合;

5、统计并输出串或文件中包含的各种类型的常量个数;

6、以二元组(类型,值)的形式输出各常量的类型和值;

7、根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。
四、运行结果
1、输入如下正确的常量说明串:

const count=10,sum=81.5,char1=‘f’,max=169,str1=“h*54 2..4S!AAsj”, char2=‘@’,str2=“aa!+h”;
输出:
count(integer,10)
sum(float,81.5)
char1(char, ‘f’)
max(integer,169)

str1(string,“h*54
2..4S!AAsj”)

char2(char, ‘@’)

str2(string,“aa!+h”)

int_num=2;
char_num=2; string_num=2; float_num=1.
2、输入类似如下的保留字const错误的常量说明串:

Aconstt count=10,sum=81.5,char1=‘f’;
输出类似下面的错误提示信息:
It is not a constant declaration statement!

Please input a string again!
3、输入类似如下含常量名或常量值错误的常量说明串:

const count=10,12sum=81.5,char1=‘ff’,max=0016;
输出类似下面的错误提示信息:
count(integer,10)
12sum(Wrong! It is not a identifier!)
char1(Wrong! There are
more than one char in ‘’.)
max(Wrong! The integer can’t be started with ‘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<ctype.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define N 80

#define M 16

void check_const();

void measure_iden();

void measure_string();

void measure_digit();

void measure_char();

char cha;

int ci=0,cf=0,cc=0,cs=0;

char *p0,*t0,*p1,*t1, *p2,*str,*p3,*t3="const",*digi,*flo;

void main()

{

printf("Please input string: \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");

check_const();

/* 开始处理输入串 p0 */

while(*(p0)==' '||*(p0)==',') /*从串p0中取标识符,并将其作为常量名存放到串p1中 */

{

p0++;

if(*(p0)==' '||*(p0)==',')

continue;

else

{

measure_iden(); //*p0=="="

if(!isdigit(*p0)&&*p0!='\"'&&*p0!='\'')//注意'和"做字符表示时用\'和\"

{

system("cls");

printf("\n Const data is wrong . Exit !");

exit(0);

}

else if(*p0=='\"') /* 处理字符串常量 */

{

p0++;

measure_string();

}

else if(isdigit(*p0)) /* 处理数字 */

{

measure_digit();

}

else if(*p0=='\'') //处理字符常量

{

p0++;

measure_char();

}

}

}

if(*p0!=';')

{

system("cls");

printf("\n This centence is wrong . Exit !");

exit(0);

}

else

{

printf("int_num=%d; char_num=%d; string_num=%d; float_num=%d.\n",ci,cc,cs,cf);

}

}

/* 检查输入串是否以"'const"开头 */

void check_const()

{

while(*p0!=' ')

{

if(*p0==*t3)

{

p0++;

t3++;

}

else

{

printf("This string isn't a const declaration!");

exit(0);

}

}

}

void measure_iden()

{

if (*p0!='_'&&(!isalpha(*p0)))

{

system("cls");

printf("\n Const name is wrong . Exit !");

exit(0);

}

else if (*p0=='_'||isalpha(*p0))

{

t1=p1;

while(*p0!='=')

{

*p1=*p0;

p0++;

p1++;

}

*p1='\0';

// printf("%s\n",p0);

p0++;

}

printf("%s",t1);

}

void measure_string()

{

str=p2;

while(*(p0)!='\"')

{

*p2=*p0;

if(*(p0)==';')//丢了个分号,直接输出String data is wrong. Exit

{

system("cls");

printf("\n String data is wrong. Exit !");

exit(0);

}

p0++;

p2++;

}

*p2='\0';

p0++;

cs++;

printf("(string,\"%s\")\n",str);

}

void measure_digit()

{

char *jud;

int mark=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);

}

}

void measure_char()

{

char *jud;

jud=p0;

if(*(jud+1)=='\''&&*(jud)!='\'')

{

cha=*p0;

p0=p0+2;

cc++;

}

else

{

system("cls");

printf("\n char data is wrong. Exit !");

exit(0);

}

printf("(char,'%c')\n",cha);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: