21游戏网
您的当前位置:首页词法分析程序

词法分析程序

来源:21游戏网




专业课程设计II

题 目:


肇学生姓名
莄班级学号

罿指导教师

指导单位



1



词法分析程序的构造

一、

二、课题内容和要求

蚇基本功能:通过状态转换图构造C或者PASCAL 语言子集的词法分析程序。例如选取了C语言,选取其中一个子集,例如包含了部分关键字mainfloatiffor等等,特殊符号(<=+等等,特殊定义的标识符变量以及部分常量等,采用《编译原理》词法分析中有穷自动机的思想构建出该语言子集的状态转换图,并编码实现。要求将选取的语言子集编写一个简单程序,放在一个文本文件中;要将一个个单词区分清楚并归类(例如for属于关键字),词法分析程序作一遍扫描,采用双缓冲区结构。并且如vc将关键字着色以加以识别。

袅二、概要设计 (1)

(2) 状态装换图

(3)

(4) 功能模块

核心代码:

1)、数据类型定义:

2



extern struct table

{

int id;

char code[10];

};

//保留字(关键字)和各自的编码

struct table key[100] = {{100,"main"},{101,"int"},{102,"char"},{103,"if"},



int a=200; //自定义变量编码

int b=300; //数字编码

int d=400; //运算符编码

int e=500; //分隔符编码

int f=600; //关系运算符编码


3



2)、函数调用

void scanner(FILE *fp)

int reserve(char* p)

//读取文件内容,并加以识别判断

//识别判断是否为关键字函数

void output(int t,char *s) //输出函数

3)、状态判断

void scanner(FILE *fp)


if(isalpha(ch)) //如果是字母

{

token[0]=ch;

i=1;

ch=fgetc(fp);


4



while(isalpha(ch)||isalnum(ch)) //循环接受字母

{

token[i]=ch; //放入数组中

i++;

ch=fgetc(fp);

}


token[i]='\0';

c=reserve(token); //判断是否为关键字

if(c!=-1){

output(c,token);

}


5



else

output(a++,token);

}

else

if(isdigit(ch)) //如果是数字

{


ch=fgetc(fp);

i=1;

while(isdigit(ch))//循环接受

{

token[i]=ch;


6



i++;

ch=fgetc(fp);

}

token[i]='\0';

fseek(fp,-1,1);

output(b++,token);


else

switch(ch) //判断是否为符号

{

case'(':output(e++,"(");break; //是否为(,是则输出

case')':output(e++,")");break; //是否为),是则输出


7



case'[':output(e++,"[");break; //是否为[,是则输出

case']':output(e++,"]");break; //是否为],是则输出

case'{':output(e++,"{");break; //是否为{,是则输出

case'}':output(e++,"}");break; //是否为},是则输出

case',':output(e++,",");break; //是否为,,是则输出

case':':output(e++,":");break; //是否为:,是则输出


case'"':output(e++,"\"");break; //是否为\,是则输出

case'+':ch=fgetc(fp);//是否为+,是则往前搜索一个字符

if(!feof(fp)) //判断是否到文件末尾

{

if(ch=='+') //如果下一个字符是+,则输出++


8



output(f++,"++");

else //不是则文件指针回退一个,输出+

{

fseek(fp,0,1);

output(f++,"+");

}


else output(f++,"+");

break;

case'-':ch=fgetc(fp); //是否为-,是则往前搜索一个字符

if(!feof(fp))

{


9



if(ch=='-')

output(f++,"--");

else

{

fseek(fp,0,1);

output(f++,"-");


}

else output(f++,"-");

break;

case'*':output(d++,"*");break;

case'/':output(d++,"/");break;


10



case'>':ch=fgetc(fp);//是否为>,是则往前搜索一个字符

if(!feof(fp))

{

if(ch=='=')

output(f++,">=");

else


fseek(fp,0,1);

output(f++,">");

}

罿 }

else output(f++,">");


11



break;

case'<': ch=fgetc(fp); //是否为<,是则往前搜索一个字符

if(!feof(fp))

{

if(ch=='=')

output(f++,"<=");


{

fseek(fp,-1,1);

罿 output(f++,"<");

}

}


12



else{

fseek(fp,0,1);

output(f++,"<");}

break;

case'=':ch=fgetc(fp);//是否为=,是则往前搜索一个字符

if(feof(fp)){


output(f++,"=");}

else

{

if(ch=='=')

output(f++,"==");


13



else

{

fseek(fp,-1,1);

output(f++,"=");

}

}


case'!':ch=fgetc(fp); //是否为!,是则往前搜索一个字

if(!feof(fp))

{

if(ch=='=')



output(f++,"!=");


14



else

{

fseek(fp,0,1);

output(f++,"!");

}

}


break;

}

}

蚀三、详细设计(格式:宋体,4号,加粗,两端对齐)


15



源代码

********************************extre.h*********************************

externstruct table

{

intid;

charcode[10];

};



{104,"else"},{105,"for"},{106,"while"},{107,"ERROR"}};

intreserve(char* p)

{

inti=0;


for(i=0;i<8;i++)

16



{

if(strcmp(p,key[i].code)==0)

return(key[i].id);

}

return(-1);

}

void output(int t,char *s)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);

if(100<=t&&t<=107){

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);

printf("%-2d %-6s",t,s);


17



printf(" 关键字\n");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);

}

else printf("%-2d %-6s ",t,s);

switch(t/100){

case 2:printf("

变量 \n");break;

case 3:printf("

数字 \n");break;


case 5:printf("

分隔符 \n");break;

case 6:printf("

关系运算符 \n");break;

}

}


*****************************************guwen.cpp***********************************

18



#include<stdio.h>

#include<string.h>

#include<windows.h>

#include<ctype.h>

#include"extre.h"

extern int reserve(char*);

extern void output(int,char*);

chartoken[20];

charch;

inti,c;

int a=200;

//变量


int b=300;

//数字


19



intd=400; //运算符

inte=500; //分隔符

intf=600; //关系运算符

voidscanner(FILE *fp)

{

if(isalpha(ch))

//如果是字母

{


i=1;
ch=fgetc(fp);
while(isalpha(ch)||isalnum(ch)) //循环接受字母
{



token[i]=ch;

//放入数组中


20



}

i++;

ch=fgetc(fp);

}

fseek(fp,-1,1);

token[i]='\0';

c=reserve(token);



output(c,token);

}

else

output(a++,token);



21



罿

else

if(isdigit(ch))

//如果是数字

{

token[0]=ch;

ch=fgetc(fp);

i=1;

while(isdigit(ch))


token[i]=ch;
i++;
ch=fgetc(fp);
}



token[i]='\0';


22



fseek(fp,-1,1);

output(b++,token);

罿 }

else

switch(ch)//判断是否为符号

{

case')':output(e++,")");break; //是否为),是则输出

case'[':output(e++,"[");break; //是否为[,是则输出

case']':output(e++,"]");break; //是否为],是则输出

case'{':output(e++,"{");break; //是否为{,是则输出

case'}':output(e++,"}");break; //是否为},是则输出


23



case',':output(e++,",");break;

//是否为,,是则输出

//是否为:,是则输出

case':':output(e++,":");break;

//是否为;,是则输出

case';':output(e++,";");break;

//是否为\,是则输出

case'"':output(e++,"\"");break;

case'+':ch=fgetc(fp); //是否为+,是则往前搜索一个字


if(!feof(fp)) //判断是否到文件末尾
if(ch=='+') //如果下一个字符是+,则输出++
output(f++,"++");

else

//不是则文件指针回退一个,输出+

{

fseek(fp,0,1);



24



output(f++,"+");

}

}

else output(f++,"+");

break;

case'-':ch=fgetc(fp); //是否为-,是则往前搜索一个字


{
if(ch=='-')
output(f++,"--");
else

{



25



fseek(fp,0,1);
output(f++,"-");
}
}
else output(f++,"-");
break;
case'*':output(d++,"*");break;

case'>':ch=fgetc(fp); //是否为>,是则往前搜索一个字

if(!feof(fp))


{

罿

if(ch=='=')


26



output(f++,">=");

else

{

fseek(fp,0,1);

output(f++,">");

}

}


break;

case'<': ch=fgetc(fp);

//是否为<,是则往前搜索一个字符

if(!feof(fp))

{



if(ch=='=')


27



output(f++,"<=");

else

{

fseek(fp,-1,1);

output(f++,"<");

}

else{

fseek(fp,0,1);

output(f++,"<");}

break;

case'=':ch=fgetc(fp); //是否为=,是则往前搜索一个字


28



if(feof(fp)){

fseek(fp,0,1);

output(f++,"=");}

else

{

if(ch=='=')


else
{
fseek(fp,-1,1);
output(f++,"=");

}



29



}

break;

case'!': ch=fgetc(fp);

//是否为!,是则往前搜索一个字符

if(!feof(fp))

{

if(ch=='=')

output(f++,"!=");


{
fseek(fp,0,1);
output(f++,"!");
}



}


30



else output(f++,"!");

break;

}

}

voidmain()

{


FILE *fp;
char wenjian[30];
printf("|************************您要分析的文件结果如下**********************|\n");
fp=fopen("1.txt","r");
while(feof(fp)==0)

{ ch=fgetc(fp);



31



scanner(fp);

}

fclose(fp);

}

四、测试数据及其结果分析

蝿测试用例(1):


测试用例(2):

测试结果:

五、课程设计总结

1)课程设计过程中的问题


肅问题:在超前搜索时候,当达到文件最后一个字符时候,仍然会超前搜索,搜索

32



eof,从而程序陷入无限循环。原来部分代码为:

case'<': ch=fgetc(fp);

if(ch=='=')

output(f++,"<=");

else{

fseek(fp,-1,1);

output(f++,"<");

}

break;莈解决方案

号,是则输出当前符号,否则继续判断是否为双目符号。修正后:

case'<': ch=fgetc(fp);

if(!feof(fp))

{

if(ch=='=')
output(f++,"<=");

33



else

{

fseek(fp,-1,1);

output(f++,"<");

}

}

else{

fseek(fp,0,1);
output(f++,"<");}break;

(2)课程设计的总结

词法分析程序的编写,是我对c语言编程的认识又多了一些新的认识。让我把这段时间

荒废的c语言中的一些知识点重新巩固了。了解了一些计算机编程的艺术。同样也发现了

自己的不足,对于界面设计的缺乏。

从这个设计中我更加理解了《编译原理》中关于词法分析这块的知识,对于这本书的

理解加深了一层,“书读百遍,其义自现”最为贴切。也从vc++这个程序运行环境发现了

自己对于词法分析器考虑的不足之处,对于以后自身的发展有着重要的意义。


34




同学出勤率(满勤、较高、一般,较低),学习态度(端正、较端正、一般、较差),程序设计基础(好、较好、一般、较差),

演示程序(已经、基本、没有)达到了基本要求,算法设计(好、

较好、一般),界面友好程度(好、较好、一般),答辩过程中回

答问题(准确、较准确、错误率较高),撰写报告格式(规范、较

为规范、一般)、内容(丰满、较为丰满、简单)、表述(清晰、一

般、不清楚),(、较好、基本)完成了课题任务。

教师签名:











35



Forpersonal use only in study and research; not for commercial use





36

显示全文