东北大学编译原理实验1.docx

上传人:b****6 文档编号:5875966 上传时间:2023-01-01 格式:DOCX 页数:21 大小:130.94KB
下载 相关 举报
东北大学编译原理实验1.docx_第1页
第1页 / 共21页
东北大学编译原理实验1.docx_第2页
第2页 / 共21页
东北大学编译原理实验1.docx_第3页
第3页 / 共21页
东北大学编译原理实验1.docx_第4页
第4页 / 共21页
东北大学编译原理实验1.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

东北大学编译原理实验1.docx

《东北大学编译原理实验1.docx》由会员分享,可在线阅读,更多相关《东北大学编译原理实验1.docx(21页珍藏版)》请在冰豆网上搜索。

东北大学编译原理实验1.docx

东北大学编译原理实验1

编译原理程序设计实验报告

——实验题目

班级:

计算机1507班姓名:

罗艺博学号:

********

一、实验目标:

词法分析扫描器的设计实现。

在程序源文件中输入类C语言程序源文件,设计词法分析扫描器,并以TOKEN类别码序列的形式输出扫描结果。

二、实验内容:

1.概要设计:

将程序大致分为:

主函数、识别器(有限自动机state_change)、词法分析器(state_to_code)三大部分。

其中,主函数所完成的功能为:

打开、读取、关闭文件(即C语言源程序),重置token串等。

识别器的功能为:

识别字符,完成token串的生成,判断词法错误等。

词法分析器的功能为:

生成token类别码,判断token是否出错等。

主函数、识别器、词法分析器关系图

2.流程图

词法分析扫描器流程图

 

3.关键函数

a.识别器(有限自动机state_change)

intstate_change(state,ch)//识别器,有限自动机

{

if((ch=='')||(ch=='\t')||(ch=='\n'))//略去空格、TAB、换行

return0;

elseif((IsAlpha(ch)==1)||(ch=='_'))//判断是否为字母或'_',从而判断是关键字、标识符、CT字符还是ST字符串

{

if(state==1)

return2;

elseif(state==2)

return2;

elseif(state==7)

return8;

elseif(state==8)

return8;

elseif(state==10)

return11;

elseif(state==11)

return11;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return2;

}

else

return-1;

}

elseif(IsNum(ch)==1)//判断是否为数字,从而进一步判断是为IT,CT,KT

{

if(state==1)

return3;

elseif(state==2)

return2;

elseif(state==3)

return3;

elseif(state==4)

return4;

elseif(state==5)

return5;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return3;

}

else

return-1;

}

elseif(ch=='.')//判断是否为CT中的小数点

{

if(state==3)

return4;

else

return-1;

}

elseif(ch=='\'')//判断是否为CT字符

{

if(state==1)

return7;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return7;

}

elseif(state==8)

return9;

else

return-1;

}

elseif(ch=='\"')//判断是否为ST

{

if(state==1)

return10;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return10;

}

elseif(state==11)

return12;

else

return-1;

}

else//判断是否为PT

{

if(state==1)

return6;

elseif(state==2)//考虑与IT,KT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==3)//考虑与CT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==9)//考虑与CT字符相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==12)//考虑与ST相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==6)

{

if(((i==1)&&(ch=='='))&&((token[0]=='>')||(token[0]=='<')||(token[0]=='=')))

{

return6;

}

else

return0;

}

else

return-1;

}

}

b.词法分析器(state_to_code)

intstate_to_code(state_before,token)//词法分析器

{

intn;//循环

code1=0;

code2=0;

switch(state_before)

{

case2:

//KT<1X>

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

{

if(strcmp(token,KT[n])==0)

{

code1=1;

code2=n;

printf("<%d%d>\n",code1,code2);//why改变不了全局的code1,code2

break;

}

}

if(code1==0)//IT<20>

{

printf("<20>\n");

}

break;

case3:

//CT<30>

printf("<30>\n");

break;

case5:

//CT(小数)<30>

printf("<30>\n");

break;

case6:

//PT<6X>

for(n=0;n<18;n++)

{

if(strcmp(token,PT[n])==0)

{

code1=6;

code2=n;

printf("<%d%d>\n",code1,code2);//why改变不了全局的code1,code2

break;

}

}

break;

case9:

//CT字符<40>

printf("<40>\n");

break;

case12:

//ST<50>

printf("<50>\n");

break;

default:

//不被任何词识别

printf("Sorryit'sgoingwrong!

");

}

return0;

}

c.判断函数

intIsAlpha(charc)//判断是否为字母

{

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

return1;

else

return0;

}

intIsNum(charc)//判断是否为数字

{

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

return1;

else

return0;

}

intIsKey(char*word)//判断是否为关键字

{

intm,n;

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

{

if((m=strcmp(word,KT[n]))==0)

{

if(n==0)

return2;

return1;

}

}

return0;

}

intIsDelimiter(char*token)//判断是否为界符

{

intm,n;

for(n=0;n<18;n++)

{

if((m=strcmp(token,PT[n]))==0)

{

if(n==0)

return2;

return1;

}

}

return0;

}

源程序代码:

(加入注释)

#include

#include

#include

FILE*fp;

charinput[200];//存放输入字符串

chartoken[10];//存放构成单词符号的符号串

charword[10];//存放识别出的单词流

charch;//存放当前读入字符

intp;//input下标

inti=0;//token下标

intstate;//存放状态标记

intcode1;//token类别码,1->KT,2->IT,3->CT,4->CTT,5->ST,6->PT

intcode2;

intstate_before;//存放之前状态

intnum;//存放整形值

char*KT[6]={"int","main","void","if","else","char"};//1

char*PT[18]={">=","<=","==","=",">","<","+","-","*","/","{","}",",",";","(",")","[","]"};//18

//char*IT[20]={NULL};//2

//char*CT[20]={NULL};//3

//char*CTT[20]={"\0"};//4

//char*ST[20]={NULL};//5

intstate_change(state,ch);

intstate_to_code(state_before,token);

intIsAlpha(charc);

intIsNum(charc);

intIsKey(char*word);

intIsDelimiter(char*token);

intmain()

{

state=1;//state=1设为初始态,0设为结束态

if((fp=fopen("E:

\\Cwork\\Analysis\\test.txt","r"))==NULL)

{

printf("Cannotopenfile.\n");

exit

(1);

}

while((ch=fgetc(fp))!

='#')

{

state_before=state;

state=state_change(state,ch);

if(state==-1)

{

printf("Err!

Stupidman!

\n");

}

elseif(state!

=0)

{

token[i++]=ch;

}

else

{

if(state_before!

=1)

{

state_to_code(state_before,token);

}

memset(token,0,10);

i=0;

state=1;

}

}

fclose(fp);

return0;

}

intstate_change(state,ch)//识别器,有限自动机

{

if((ch=='')||(ch=='\t')||(ch=='\n'))//略去空格、TAB、换行

return0;

elseif((IsAlpha(ch)==1)||(ch=='_'))//判断是否为字母或'_',从而判断是关键字、标识符、CT字符还是ST字符串

{

if(state==1)

return2;

elseif(state==2)

return2;

elseif(state==7)

return8;

elseif(state==8)

return8;

elseif(state==10)

return11;

elseif(state==11)

return11;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return2;

}

else

return-1;

}

elseif(IsNum(ch)==1)//判断是否为数字,从而进一步判断是为IT,CT,KT

{

if(state==1)

return3;

elseif(state==2)

return2;

elseif(state==3)

return3;

elseif(state==4)

return4;

elseif(state==5)

return5;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return3;

}

else

return-1;

}

elseif(ch=='.')//判断是否为CT中的小数点

{

if(state==3)

return4;

else

return-1;

}

elseif(ch=='\'')//判断是否为CT字符

{

if(state==1)

return7;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return7;

}

elseif(state==8)

return9;

else

return-1;

}

elseif(ch=='\"')//判断是否为ST

{

if(state==1)

return10;

elseif(state==6)//考虑与PT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return10;

}

elseif(state==11)

return12;

else

return-1;

}

else//判断是否为PT

{

if(state==1)

return6;

elseif(state==2)//考虑与IT,KT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==3)//考虑与CT相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==9)//考虑与CT字符相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==12)//考虑与ST相连的情况

{

state_to_code(state_before,token);

i=0;

memset(token,0,10);

return6;

}

elseif(state==6)

{

if(((i==1)&&(ch=='='))&&((token[0]=='>')||(token[0]=='<')||(token[0]=='=')))

{

return6;

}

else

return0;

}

else

return-1;

}

}

intstate_to_code(state_before,token)//词法分析器

{

intn;//循环

code1=0;

code2=0;

switch(state_before)

{

case2:

//KT<1X>

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

{

if(strcmp(token,KT[n])==0)

{

code1=1;

code2=n;

printf("<%d%d>\n",code1,code2);//why改变不了全局的code1,code2

break;

}

}

if(code1==0)//IT<20>

{

printf("<20>\n");

}

break;

case3:

//CT<30>

printf("<30>\n");

break;

case5:

//CT(小数)<30>

printf("<30>\n");

break;

case6:

//PT<6X>

for(n=0;n<18;n++)

{

if(strcmp(token,PT[n])==0)

{

code1=6;

code2=n;

printf("<%d%d>\n",code1,code2);//why改变不了全局的code1,code2

break;

}

}

break;

case9:

//CT字符<40>

printf("<40>\n");

break;

case12:

//ST<50>

printf("<50>\n");

break;

default:

//不被任何词识别

printf("Sorryit'sgoingwrong!

");

}

return0;

}

intIsAlpha(charc)//判断是否为字母

{

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

return1;

else

return0;

}

intIsNum(charc)//判断是否为数字

{

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

return1;

else

return0;

}

intIsKey(char*word)//判断是否为关键字

{

intm,n;

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

{

if((m=strcmp(word,KT[n]))==0)

{

if(n==0)

return2;

return1;

}

}

return0;

}

intIsDelimiter(char*token)//判断是否为界符

{

intm,n;

for(n=0;n<18;n++)

{

if((m=strcmp(token,PT[n]))==0)

{

if(n==0)

return2;

return1;

}

}

return0;

}

程序运行结果:

(截屏)

输入:

输出:

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

当前位置:首页 > 高等教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1