编译原理词法分析课程设计.docx

上传人:b****4 文档编号:4653427 上传时间:2023-05-07 格式:DOCX 页数:28 大小:106.37KB
下载 相关 举报
编译原理词法分析课程设计.docx_第1页
第1页 / 共28页
编译原理词法分析课程设计.docx_第2页
第2页 / 共28页
编译原理词法分析课程设计.docx_第3页
第3页 / 共28页
编译原理词法分析课程设计.docx_第4页
第4页 / 共28页
编译原理词法分析课程设计.docx_第5页
第5页 / 共28页
编译原理词法分析课程设计.docx_第6页
第6页 / 共28页
编译原理词法分析课程设计.docx_第7页
第7页 / 共28页
编译原理词法分析课程设计.docx_第8页
第8页 / 共28页
编译原理词法分析课程设计.docx_第9页
第9页 / 共28页
编译原理词法分析课程设计.docx_第10页
第10页 / 共28页
编译原理词法分析课程设计.docx_第11页
第11页 / 共28页
编译原理词法分析课程设计.docx_第12页
第12页 / 共28页
编译原理词法分析课程设计.docx_第13页
第13页 / 共28页
编译原理词法分析课程设计.docx_第14页
第14页 / 共28页
编译原理词法分析课程设计.docx_第15页
第15页 / 共28页
编译原理词法分析课程设计.docx_第16页
第16页 / 共28页
编译原理词法分析课程设计.docx_第17页
第17页 / 共28页
编译原理词法分析课程设计.docx_第18页
第18页 / 共28页
编译原理词法分析课程设计.docx_第19页
第19页 / 共28页
编译原理词法分析课程设计.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

编译原理词法分析课程设计.docx

《编译原理词法分析课程设计.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析课程设计.docx(28页珍藏版)》请在冰点文库上搜索。

编译原理词法分析课程设计.docx

编译原理词法分析课程设计

课程设计

报告题目:

编译原理词法分析

学习中心:

计算机信息工程学院

指导老师:

郜晓晶

学生姓名:

黄正鹏学号:

091014861

专业:

软件工程

2011年12月1日

 

2011—2012学年第一学期

目录

一、问题描述………………………………………………………………………………………………………2

二、词法分析………………………………………………………………………………………………………2

三、简要分析与概要设计…………………………………………………………………………………………3

四、程序流程图.……………………………………………………………………………………………………4

五、源代码.…………………………………………………………………………………………………………4

六、运行结果………………………………………………………………………………………………………16

七、设计收获与体会………………………………………………………………………………………………19

 

词法分析程序设计

1.问题描述

本次课程设计要求在Windows环境下使用visualC++软件,采用熟悉的语言,通过设计、编制、调试一个对于C语言词法的词法分析程序,加深对词法分析原理的理解,并实现输出单词序列的词法检查和分析。

2.词法分析

2.1五种单词的文法

<标识符>->l|l<字母数字>

<字母数字>->l|d|l<字母数字>|d<字母数字>

<无符号整数>->d|d<无符号整数>

<运算符>->+|-|*|/|=|<<等号>|><等号>……

<界符>->,|;|(|)|{|}|……

其中l表示a~z中的任何一个英文字母,d表示0~9中的任一个数字。

关键字也是一种单词,一般关键字都是由字母构成,关键字集合时标识符集合的子集。

2.2词法分析方法

从待分析文件中取出当前符号ch=fgetc(fp)

If(Isalpha(ch))

{

读出字符串,放进TOKEN代码中

If(Iskey(token))

{

对不同关键字进行种别码设置

}

else标识符种别码设置

}

elseif(Isdigit(ch))

{

统一设置为一种种别码

数字放入TOKEN代码中

}

elseif(Isoperation(ch))

{

对不同操作符设置不同种别码

将读出的操作符放入TOKEN代码

}

elseif(Isboundrary(ch))

{

设置每种界符的种别码

将读出的界符放入TOKEN代码中

}

2.3符号表设计和TOKEN代码设计

typedefstruct_token_list//记录词法分析结果

{

Tokentoken;

struct_token_list*next;

}TokenNode,*PTokenList;

typedefstruct_symtab{//符号表

charname[10];//名称

chartype[10];//类型

intlength;//长度

intoffset;//相对数

struct_symtab*next;

}sym,*PSYMLIST;

typedefstruct_token//TOKEN代码设计

{

intsym;//种别码

charstr[10];//存放单词

}*PToken,Token;

3.简要分析与概要设计:

设置一个TOKEN结构体,用来存放单词信息,其中包含sym和str[10]两个成员,sym用来存放单词种别码,str[10]数组用来存放单词符号。

设置一个Symtab结构体,用来存放符号表中个变量的信息,其中name[10]用来存放单词名称,type[10]用来存放单词类型,length用来存放单词存储位置信息。

在程序运行之前,先把要分析的程序放在一个.txt记事本中,分析过程中通过ch=fgetc(ch)从文件中读取字符,并进行分析,分析过程见2.2词法分析方法。

对分析之后的单词用二元式进行输出。

接下来进行符号表内容的输出,将已经分析过的关键字,存放在table[]数组中,当遇到分析出的符号为‘;’时,将table[]数组清空。

对分析出的标识符进行判断,如果是第一次分析出,则用symtab.type存放其类型,用symtab.name存放其名称,symtab.length存放其长度,symtab.offset存放其相对数,然后输出符号表信息,如果不是第一次分析出,则输出错误提示。

 

4.程序主要流程图

5.源代码

#define_CRT_SECURE_NO_WARNINGS//字符串和内存操作时关闭函数的安全警告

#include

#include

#include

intj,n;

charch;

typedefstruct_token

{

intsym;//种别码

charstr[10];//存放单词

}*PToken,Token;

typedefstruct_token_list{//记录词法分析结果

Tokentoken;

struct_token_list*next;

}TokenNode,*PTokenList;

typedefstruct_symtab{//符号表

charname[10];//名称

chartype[10];//类型

intlength;//长度

intoffset;//相对数

struct_symtab*next;

}sym,*PSYMLIST;

char_type[5][10]={"int","float","char","double","long"};//符号表类型

int_size[5]={32,32,8,64,32};//及对应的长度

PSYMLISTsymtab=NULL;//符号表的头指针

PSYMLISTsymtail=symtab;//符号表的尾指针

Tokentoken;

chartype[10]={0};//保存类型名称

PTokenListptl=NULL;//TokenList的头指针

PTokenListptltail=ptl;//TokenList的尾指针

intLineNumber=1;//记录代码行数

intoffset=0;//计算变量偏移地址

voidScan(FILE*);//词法分析

boolIsoperation(charch);//判断i当前所指的字符是否为一个运算符

boolIsboundary(charch);//判断i当前所指的字符是否为一个分界符

boolIskey(charch[]);//判断i当前所指的字符是否为关键字

boolIsalpha(charch);//判断i当前所指的字符是否为字母

boolIsdigit(charch);//判断i当前所指的字符是否为数字

boolIsType(charch[]);//判断是否为类型

intGetSizeOfType(chartype[]);//获得类型大小

intSearchSymTab(charname[]);//查找符号表

voidAddToSymTab(Tokentoken);

voidPrintSymTab();//显示符号表

voidAddToTokenList(Tokentoken);//保存到词法分析表

voidPrintTokenList();//显示词法分析表

//主函数

voidmain()

{

charinput[20];

FILE*fp;

printf("*****************************************\n"

"10~~22----------------表示关键字\n"

"2---------------------表示标识符\n"

"3---------------------表示数字\n"

"40~~57----------------表示操作符\n"

"60~~65----------------表示界符\n"

"*******************************************\n");

printf("pleaseinputthesourcefilename:

");

while(true)

{

gets(input);

if((fp=fopen(input,"r"))!

=NULL)break;//读取文件内容,并返回文件指针,该指针指向文件的第一个字符

else

printf("fileopenfiled!

Pleaseinputagain:

");

}

printf("\n********theresultisasfollows********\n");

while(!

feof(fp))Scan(fp);//扫描源程序

//符号表

PrintSymTab();

//词法分析

PrintTokenList();

getchar();//暂停

}

//判断i当前所指的字符是否为一个运算符,是的话返回真,反之假

boolIsoperation(charch)

{

intt;

chararr[8]={'+','*','/','=','<','>','!

'};

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

if(ch==arr[t])

returntrue;

returnfalse;

}

//判断i当前所指的字符是否为一个分界符,是的话返回真,反之假

boolIsboundary(charch)

{

intt;

chararr[6]={',',';','{','}','(',')'};

for(t=0;t<6;t++)

if(ch==arr[t])

returntrue;

returnfalse;

}

//判断i当前所指的字符是否为一个关键字,是的话返回真,反之假

boolIskey(charch[])

{

intt;

char*keywords[13]={"const","auto","if","else","break","int",

"char","float","long","for","do","printf","case"};

for(t=0;t<13;t++)

if(strcmp(token.str,keywords[t])==0)

returntrue;

returnfalse;

}

boolIsType(charch[])

{

intt;

char*keywords[5]={"int",

"char","float","long","double"};

for(t=0;t<5;t++)

if(strcmp(token.str,keywords[t])==0)

returntrue;

returnfalse;

}

//判断i当前所指的字符是否为字母,是的话返回真,反之假

boolIsalpha(charch)

{

if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))

returntrue;

returnfalse;

}

 

//判断i当前所指的字符是否为数字,是的话返回真,反之假

boolIsdigit(charch)

{

if(ch>='0'&&ch<='9')

returntrue;

returnfalse;

}

intGetSizeOfType(chartype[])

{

for(inti=0;i<5;i++)

{

if(strcmp(type,_type[i])==0)

{

return_size[i];

}

}

return0;

}

voidAddToSymTab(Tokentoken)

{

PSYMLISTs=(PSYMLIST)malloc(sizeof(sym));

if(s==NULL)return;

memset(s,0,sizeof(sym));

memcpy(s->name,token.str,10);

memcpy(s->type,type,10);

s->length=GetSizeOfType(s->type);

s->offset=offset;

offset+=s->length;

s->next=NULL;

if(symtab==NULL)//如果链表为空则初始化链表

{

symtab=s;

symtail=symtab;

}

else//链表不为空则将节点增加到链表尾部

{

symtail->next=s;

symtail=s;

}

}

intSearchSymTab(charname[])

{

intexist=0;//如果没有找到

intindex=-1;

for(PSYMLISTs=symtab;s!

=NULL;s=s->next)

{

index+=1;

if(strcmp(name,s->name)==0)

exist=1;

}

returnexist?

index:

-1;

}

voidPrintSymTab()

{

printf("符号表:

\n");

printf("名称类型长度相对数\n");

for(PSYMLISTs=symtab;s!

=NULL;s=s->next)

{

printf("%-10s%-10s%-10d%-10d\n",s->name,s->type,s->length,s->offset);

}

}

voidAddToTokenList(Tokentoken)

{

TokenNode*tn=(TokenNode*)malloc(sizeof(TokenNode));

if(tn==NULL)return;

memcpy(&(tn->token),&token,sizeof(Token));

tn->next=NULL;

if(ptl==NULL)

{

ptl=tn;

ptltail=tn;

}

else

{

ptltail->next=tn;

ptltail=tn;

}

}

voidPrintTokenList()

{

printf("词法分析表:

\n");

printf("名称类型\n");

for(PTokenLists=ptl;s!

=NULL;s=s->next)

{

printf("%-10s%-10d\n",s->token.str,s->token.sym);

}

}

voidScan(FILE*fp)

{

token.str[10]=NULL;

j=0;

ch=fgetc(fp);//获取字符,指针fp并自动指向下一个字符

if(ch=='\n')

{

LineNumber++;//记录分析的代码的行号

strcpy(type,"");

}

//分析字符串

if(Isalpha(ch))//判断该字符是否是字母

{

while((ch>='a')&&(ch<='z')||((ch>='A')&&(ch<='Z')))

{

token.str[j++]=ch;

ch=fgetc(fp);

}

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

if(Iskey(token.str))

{

switch(n)//关键字种别码设置

{

case0:

token.sym=10;break;

case1:

token.sym=11;break;

case2:

token.sym=12;break;

case3:

token.sym=13;break;

case4:

token.sym=14;break;

case5:

token.sym=15;break;

case6:

token.sym=16;break;

case7:

token.sym=17;break;

case8:

token.sym=18;break;

case9:

token.sym=19;break;

case10:

token.sym=20;break;

case11:

token.sym=21;break;

case12:

token.sym=22;break;

}

}

else

token.sym=2;//2表示标识符种别码

//printf("(%d,%s)\n",token.sym,token.str);

AddToTokenList(token);

}

elseif(Isdigit(ch))

{

token.sym=3;//3表示数字种别码

while((ch>='0')&&(ch<='9'))

{

token.str[j++]=ch;

ch=fgetc(fp);

}

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

//printf("(%d,%s)\n",token.sym,token.str);

AddToTokenList(token);

}

elseif(Isoperation(ch))//运算符

{

switch(ch)

{

case'=':

token.str[j++]=ch;

token.str[j]='\0';

ch=fgetc(fp);

if(ch=='=')

{

token.sym=40;

token.str[j++]=ch;

token.str[j]='\0';

}

else

{

token.sym=41;

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

}

break;

case'>':

token.str[j++]=ch;

token.str[j]='\0';

ch=fgetc(fp);

if(ch=='=')

{

token.sym=42;

token.str[j++]=ch;

token.str[j]='\0';

}

else

{

token.sym=43;

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

}

break;

case'<':

token.str[j++]=ch;

token.str[j]='\0';

ch=fgetc(fp);

if(ch=='=')

{

token.sym=44;

token.str[j++]=ch;

token.str[j]='\0';

}

else

{

token.sym=45;

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

}

break;

case'!

':

token.str[j++]=ch;

token.str[j]='\0';

ch=fgetc(fp);

if(ch=='=')

{

token.sym=46;

token.str[j++]=ch;

token.str[j]='\0';

}

else

{

token.sym=47;

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

}

break;

case'+':

token.str[j++]=ch;

token.str[j]='\0';

ch=fgetc(fp);

if(ch=='=')

{

token.sym=48;

token.str[j++]=ch;

token.str[j]='\0';

}

elseif(ch=='+')

{

token.sym=49;

token.str[j++]=ch;

token.str[j]='\0';

}

else

{

token.sym=50;

token.str[j++]='\0';//'\0'代表字符结束(空格)

fseek(fp,-1,1);//回退一个字符

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2