编译原理实验词法分析实验报告.docx

上传人:b****4 文档编号:5614190 上传时间:2023-05-08 格式:DOCX 页数:15 大小:38.21KB
下载 相关 举报
编译原理实验词法分析实验报告.docx_第1页
第1页 / 共15页
编译原理实验词法分析实验报告.docx_第2页
第2页 / 共15页
编译原理实验词法分析实验报告.docx_第3页
第3页 / 共15页
编译原理实验词法分析实验报告.docx_第4页
第4页 / 共15页
编译原理实验词法分析实验报告.docx_第5页
第5页 / 共15页
编译原理实验词法分析实验报告.docx_第6页
第6页 / 共15页
编译原理实验词法分析实验报告.docx_第7页
第7页 / 共15页
编译原理实验词法分析实验报告.docx_第8页
第8页 / 共15页
编译原理实验词法分析实验报告.docx_第9页
第9页 / 共15页
编译原理实验词法分析实验报告.docx_第10页
第10页 / 共15页
编译原理实验词法分析实验报告.docx_第11页
第11页 / 共15页
编译原理实验词法分析实验报告.docx_第12页
第12页 / 共15页
编译原理实验词法分析实验报告.docx_第13页
第13页 / 共15页
编译原理实验词法分析实验报告.docx_第14页
第14页 / 共15页
编译原理实验词法分析实验报告.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

编译原理实验词法分析实验报告.docx

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

编译原理实验词法分析实验报告.docx

编译原理实验词法分析实验报告

 

编译技术实验报告

 

 

实验题目:

词法分析

学院:

信息学院

专业:

计算机科学与技术

学号:

姓名:

一、实验目的

(1)理解词法分析的功能;

(2)理解词法分析的实现方法;

二、实验内容

PL0的文法如下

‘<>’为非终结符。

‘:

:

=’该符号的左部由右部定义,可读作“定义为”。

‘|’表示‘或’,为左部可由多个右部定义。

‘{}’表示花括号内的语法成分可以重复。

在不加上下界时可重复0到任意次数,有上下界时可重复次数的限制。

‘[]’表示方括号内的成分为任选项。

‘()’表示圆括号内的成分优先。

上述符号为“元符号”,文法用上述符号作为文法符号时需要用引号‘’括起。

〈程序〉∷=〈分程序〉.

〈分程序〉∷=[〈变量说明部分〉][〈过程说明部分〉]〈语句〉

〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}:

INTEGER;

〈无符号整数〉∷=〈数字〉{〈数字〉}

〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}

〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};

〈过程首部〉∷=PROCEDURE〈标识符〉;

〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉

〈赋值语句〉∷=〈标识符〉∶=〈表达式〉

〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END

〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉

〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}

〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}

〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'

〈加法运算符〉∷=+|-

〈乘法运算符〉∷=*

〈关系运算符〉∷=<>|=|<|<=|>|>=

〈条件语句〉∷=IF〈条件〉THEN〈语句〉

〈字母〉∷=a|b|…|X|Y|Z

〈数字〉∷=0|1|2|…|8|9

实现PL0的词法分析

三、实验分析与设计

PL0词法分析程序是一个独立的过程,其功能是为语法语义分析提供单词,把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析。

其主要方法步骤为从源程序扫描下一个字符,忽略空格、换行、TAB和注释并识别单词,再将不同类别的单词归类输出。

四、实验的实现

#include

#include

#include

#include

#include

#definenorw11//norw-1个关键字

#defineal20//最长的关键字的长度

#defineIDnorw

#defineINTnorw+1

#defineCOMMAnorw+2

#defineENDFnorw+3

#defineCOLONnorw+4

#defineSEMICnorw+5

#defineADDnorw+6

#defineMINUSnorw+7

#defineMULTInorw+8

#defineEVALUnorw+9

#defineLEnorw+10

#defineNEnorw+11

#defineLTnorw+12

#defineEQnorw+13

#defineGEnorw+14

#defineGTnorw+15

#defineFLOATnorw+16

charTOKEN[20];//字符数组用来依次存放单词词文的各个字符

externintlookup(char*);//以TOKEN字符串查保留字表

externvoidreport_error(char);//报告程序中的词法错误

boolisalpha(char);//判断接收字符是否为字母

boolisalnum(char);//判断接收字符是否为字母或者数字

boolisdigit(char);//判断接收字符是否为数字

boolisannotation(char);//判断接收字符是否为注释

externcharletter(charc);//用来将大写字母转化成小写字母

FILE*fin;

FILE*fout;

voidscanner()

{//词法分析的主体程序,对输入的文本文件进行词法分析

charch;

inti,c;

interror=0;//记录文件中词法错误的个数

ch=fgetc(fin);//从输入文件中读取一个字符

while(ch!

=EOF)

{//当从输入文件接收的字符不是文件结束符时,执行循环

if(isalpha(ch))

{//如果从输入文件接收的第一个字符是字母

ch=letter(ch);

TOKEN[0]=ch;

ch=fgetc(fin);i=1;

while(isalnum(ch))

{ch=letter(ch);

TOKEN[i]=ch;i++;

ch=fgetc(fin);

}

TOKEN[i]='\0';

c=lookup(TOKEN);//查保留字表

if(c==0){fprintf(fout,"(%d,%s)\n",ID,TOKEN);}//输出标识符

elsefprintf(fout,"(%d,%s)\n",c,TOKEN);//输出接收单词为保留字

}

if(isdigit(ch))//如果从输入文件接收的第一个字符是数字

{

intcdot=0;//统计小数点个数

TOKEN[0]=ch;

ch=fgetc(fin);i=1;

while(isdigit(ch)||ch=='.')

{//从第二个接收字符开始,当是数字或者是小数点时,执行循环

if(ch=='.')

cdot++;

TOKEN[i]=ch;i++;

ch=fgetc(fin);//重复接收字符,直到接收到非数字

if(cdot>=2)

{

error++;

TOKEN[i]='\0';

printf("%siserror\n",TOKEN);

break;

}

}

if(isalpha(ch))//如果第二个字符是字母

{

while(isalpha(ch))//接收完所有的字母,跳出循环

{

TOKEN[i]=ch;i++;

ch=fgetc(fin);

}

TOKEN[i]='\0';

error++;

printf("%siserror\n",TOKEN);

}

elseif(cdot==0)//当接收的字符为整型单词时

{

fseek(fin,-1,1);

TOKEN[i]='\0';

inta,temp=0,c;

for(c=0;c

{

a=TOKEN[c]-'0';

if(c!

=0)

{

temp=temp*10;

temp=temp+a;

}

else

{

temp=a;

}

}

fprintf(fout,"(%d,%d)\n",INT,temp);//输出接收单词为整数

}

elseif(cdot==1)

{

fseek(fin,-1,1);

TOKEN[i]='\0';

inta,part1=0,jc,b=0;//b用来确定小数点所在的位置

floatc=0.1,part2=0.0;

while(TOKEN[b]!

='.')

{

b=b+1;

}

for(jc=0;jc

{

a=TOKEN[jc]-'0';

if(jc!

=0)

{

part1=part1*10;

part1=part1+a;

}

else

{

part1=a;

}

}

for(jc=b+1;jc

{

a=TOKEN[jc]-'0';

part2=a*c+part2;

c=c*0.1;

}

fprintf(fout,"(%d,%f)\n",FLOAT,part1+part2);//输出接收单词为小数

}elseif(cdot==2)

{

fseek(fin,-1,1);

}

}

else//如果从输入文件接收的第一个字符既不是字母又不是数字

switch(ch)

{//将所接收到的符号字符进行分类,采取一符一类

case':

':

ch=fgetc(fin);

if(ch=='=')fprintf(fout,"(%d,:

=)\n",EVALU);//输出接收符号为赋值号

else

{ch=fgetc(fin);

fseek(fin,-1,1);//文件接收字符回推一个字符

fprintf(fout,"(%d,':

')\n",COLON);//输出冒号

}

break;

case',':

fprintf(fout,"(%d,',')\n",COMMA);break;//输出逗号

case'.':

fprintf(fout,"(%d,'.')\n",ENDF);break;//输出句号

case';':

fprintf(fout,"(%d,'.')\n",SEMIC);break;//输出分号

case'+':

fprintf(fout,"(%d,'+')\n",ADD);break;//输出加号

case'-':

fprintf(fout,"(%d,'-')\n",MINUS);break;//输出减号

case'*':

fprintf(fout,"(%d,'*')\n",MULTI);break;//输出乘号

case'<':

ch=fgetc(fin);

if(ch=='=')fprintf(fout,"(%d,'<=')\n",LE);//输出小于或等于号

elseif(ch=='>')fprintf(fout,"(%d,'<>')\n",NE);//输出不等于号

else

{

fseek(fin,-1,1);

fprintf(fout,"(%d,'<')\n",LT);;//输出小于号

}

break;

case'=':

fprintf(fout,"(%d,'=')\n",EQ);break;//输出等于号

case'>':

ch=fgetc(fin);

if(ch=='=')fprintf(fout,"(%d,'>=')\n",GE);//输出大于或等于号

else

{

fseek(fin,-1,1);

fprintf(fout,"(%d,'>')\n",GT);//输出大于号

}

break;

case'':

break;

case'\n':

break;

case'\t':

break;

case'/':

ch=fgetc(fin);//检查是否为单行注释

if(ch=='/'){

while(ch!

='\n'){

ch=fgetc(fin);

}

}

else{

fseek(fin,-1,1);

printf("/iserror\n");

error++;

}

break;

case'{':

while

(1){

ch=fgetc(fin);

if(ch=='}')break;

if(ch==EOF){

fseek(fin,-1,1);

printf("{iserror\n");

error++;

break;

}

}

break;

default:

printf("%ciserror\n",ch);//接收非上述字符程序报告词法错误

error++;break;

}

ch=fgetc(fin);//继续从文件中读取下一个单词,直到文件结束

}//while循环结束

printf("共发现%d个词法错误!

",error);

return;

}

intlookup(char*token)

{

intj;

charword[norw][al];

strcpy(&(word[1][0]),"begin");

strcpy(&(word[2][0]),"end");

strcpy(&(word[3][0]),"var");

strcpy(&(word[4][0]),"integer");

strcpy(&(word[5][0]),"while");

strcpy(&(word[6][0]),"do");

strcpy(&(word[7][0]),"if");

strcpy(&(word[8][0]),"then");

strcpy(&(word[9][0]),"procedure");

strcpy(&(word[10][0]),"else");

for(j=1;j<=norw-1;j++)if(strcmp(token,word[j])==0)returnj;//以TOKEN字符串查保留字表,若查到返回保留字类别码

return0;//TOKEN不是保留字,返回0

}

 

boolisalpha(charc)

{//判断接收字符是否为字母

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

elsereturn0;

}

boolisalnum(charc)

{//判断接收字符是否为字母或者数字

if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))return1;

elsereturn0;

}

boolisdigit(charc)

{//判断接收字符是否为数字

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

elsereturn0;

}

charletter(charc)//将大写字母转换成小写字母,即不区分大小写

{

if(c>='A'&&c<='Z')

{

c=c+32;

}

returnc;

}

intmain()

{

charfilename[20];

printf("请输入文件名:

");

scanf("%s",filename);

if((fin=fopen(filename,"r"))==NULL)//打开要读取的文本文件

{

printf("不能打开文件.\n");

exit(0);

}

printf("请输入保存分析结果的文件名:

");

scanf("%s",filename);

if((fout=fopen(filename,"w"))==NULL)

{

printf("不能打开文件.\n");

exit(0);

}

scanner();//调用词法分析程序

//getchar();getchar();

fclose(fin);

fclose(fout);

return0;

}

五、运行的结果

 

 

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

当前位置:首页 > 农林牧渔 > 林学

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

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