c词法分析器.docx
- 文档编号:7251334
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:33
- 大小:94.77KB
c词法分析器.docx
《c词法分析器.docx》由会员分享,可在线阅读,更多相关《c词法分析器.docx(33页珍藏版)》请在冰豆网上搜索。
c词法分析器
编译原理
——————C语言词法分析器
C语言词法分析器的设计与实现
一.实验目的:
1.强化对系统软件综合工程实现能力、规划能力的训练;
2.加强对词法分析原理、方法和基本实现技术的理解;
二.实验内容:
用C语言(或C++)作为宿主语言完成:
C语言(ANSIC或turboC2.0)词法分析器的设计和实现。
三、程序简要说明:
1、属性字说明:
共9种
KEYWORD:
关键字
"auto","break","case","char","const","continue",
"default","do","double","else","enum","extern",
"float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct",
"switch","typedef","union","unsigned","void",
"volatile","while","include","define"
共34个
详见IsKeyWord()函数
NUMBER:
数字
包括十进制整数,八进制整数,二进制整数,十六进制整数
还可返回几种错误
详见IsNumber()函数
CONSTANT:
常量
宏定义标识符,不识别C++关键字const,简单处理一层宏定义。
详见IsDefined()函数
ERROR:
错误
可以识别几种简单的错误,数字四种,单双引号不匹配,注释符不匹配等。
FUNCTIONNAME:
函数名
可以识别自定义函数和库函数,不识别C++语法
详见IsFunctionName()函数
VARIABLE:
变量名
所有其他属性字特征之外的属性
TRANSLATION:
转义字符
'\b',\'n','\r','\t','\"','\'','\0','\\','\v','\a','\o','\x'共12个
详见源代码417-444行
OPERATOR:
运算符
+-*/%等
INCLUDEFILE:
包含的文件
#include<>或””中的字符串
详见IsInclude()函数
2、原程序主要流程:
源程序使用纯C语法,提供了一个字符界面,重写了scanf(源程序中为scanff())函数,以方便用户界面的交互。
总流程:
分析并生成终结果文件流程:
3、主要数据结构:
本程序大量采用缓冲机制,这样做的好处显而易见,提高了程序的执行效率,简化了代码编写的难度,最重要的是,缓解了C语言对内存支配限制的压力。
文件打开以后,对行设立行缓冲区,对属性字设置属性字缓冲区,同时对于判断中的常量储存,关键字存储均以缓冲提供进算法,程序没有任何全局变量,初始化界面后,程序只有一个入口getFileName();这是用户界面与核心程序之间的接口,而程序的核心算法同样只有一个接口analyse(),接口提供的参数只是文件的文件名,这样做的好处是,程序通过analyse()可以随处使用。
另外程序设置了大量的函数,在获得完整的属性字后,通过函数判断属性,并返回属性编号,在输出时,并未对编号进行处理,因为程序之后并没有更进一步的语法分析衔接。
判断采用自动机理论,满足终态条件则返回以获得的属性字。
程序在输出上同样提供了非常人性化的设置,如输出先输出每一行的内容,之后在列出属性字流。
4、部分附加功能处理技巧说明:
由于程序配合了行列号的输出,行号非常容易处理,但是列号要涉及很多空格,回车,制表符等,其中最难处理的是制表符,制表符的长度在判断算法中为8,则通过语句
col+=((TAB-(*col+1)%TAB)%TAB);
可以使col获得期望中的列号。
对单层宏定义,则必然是#define**的格式,算法将第一个*中的内容存入数组(definebuf),后面接一个空白符,再存入第二个*的内容
definebuf的结构
对函数名的判断,这个算法并不是简单的字符串匹配,而是要看这个标识符后面的内容,
由于程序对单行判断,除多行注释,并未提供匹配记忆,所以对于一下写法程序无能为力
printf/*******函数调用信息另起了一行,将不能正确识别*******/
(“abcd”);
所以在使用本程序时,请提供尽量规范的代码
对于C++语法规则inti(3);程序将会把i判断为函数名,所以请使用标准C语言的代码。
本人能力有限,部分算法有待改进。
5、函数列表和简单说明
voidinit();//初始化图形界面
voidmessageBox();//画框函数,用于图形界面
voidbutton();//生成一个图形按钮
voidrightBox();//更新界面右侧打印信息
intscanff();//从键盘获得字符串
voidgetFileName();//图形交互接口,提供了TAB,UPARROW等按钮的功能
voidanalyse();//内核接口
voidcheckOutNotes();//检查并生成注释文件
voidcheckOutWordsStream();//词法分析函数
voidcheckDefine();//检查并保存宏定义
voidfputline();//在生成文件中写入当前分析中的行内容
voidfputEnd();//在生成文件中打印一个回车
voidfputTip();//在生成文件中打印行列号
voidfputcc();//在生成的文件中打印制表符并返回虚拟列号
voidfputWord();//在生成文件中写入完整的一行
voidfputdefine();//在生成的文件中写入常量及其值
intnoUse();//判断是否为无用字符'\t','\n','\r','\0',''
intisKeyWord();//判断是否为关键字
intisNumber();//判断是否为数字
intisFunctionName();//判断是否是函数名
intisInclude();//判断是否是包含文件
intisDefined();//判断是否为宏(即常量)
intreadLine();//读行
intreadWord();//读入一个属性字
intcton();//将字符转化为数字
intntoc();//将数字转化为字符
#include"stdio.h"
#include"string.h"
#include"dos.h"
#include"conio.h"
#include"ctype.h"
#include"sys/stat.h"
#defineOK1
#defineTAB8
voidinit();
intscanff();
voidgetFileName();
voidanalyse();
voidcheckOutNotes();
voidcheckOutWordsStream();
voidcheckDefine();
voidfputEnd();
voidfputTip();
voidfputcc();
voidfputWord();
voidfputdefine();
voidfputline();
intnoUse();
voidmessageBox();
voidbutton();
voidrightBox();
intisKeyWord();
intisNumber();
intisFunctionName();
intisInclude();
intisDefined();
intreadLine();
intreadWord();
intcton();
intntoc();
main()
{
chardealfile[200]="";
charoutputfile[200]="";
charnotefile[200]="";
textbackground
(1);
clrscr();
init();
getFileName(dealfile,outputfile,notefile);
getch();
}
intscanff(char*str,intdislen)/**needfile
{
intch=0,lenth;
inti;
intx,y;
x=wherex();y=wherey();
lenth=strlen(str);
if(lenth>dislen&&dislen)
{
i=lenth-dislen;
}
elsei=0;
for(i;i printf("%c",str[i]); while(ch! =7181) { ch=bioskey(0); switch(ch) { case3592: /**key_backspace**/ { if(lenth==0); else { printf("\b"); printf("%c",32); printf("\b"); lenth--; } break; } case19200: case19712: case283: case18432: case20480: case11520: case27392: returnch;break; case3849: /**key_tab**/returnch;break; case7181: /**key_Enter**/returnch;break; default: str[lenth++]=ch; } str[lenth]='\0'; if(lenth>dislen&&dislen) { i=lenth-dislen; } elsei=0; gotoxy(x,y); for(i;i printf("%c",str[i]); } } /**********AllDFAincludeinthisfunction***********/ voidanalyse(char*filename,char*nfile,char*outputfile) { char*constant; checkOutNotes(filename,nfile); checkOutWordsStream(outputfile); } /*************DFAfornotesmessage********************/ /****therearesomeposibilities,stringbegins*******/ /****with//,forsimplelinenote,stringbegins*******/ /****with/*,endswiththeoppositeform,for*******/ /****multi-linenote,DFAwilldiscernit*******/ voidcheckOutNotes(char*filename,char*nfile) { FILE*fp,*fp1,*fp2; charch=0; chardealline[5000]; intline=0,col,lenth,isnote=0,i,col1; fp1=fopen(nfile,"w+"); rewind(fp1); fp2=fopen("c: \\temp.c","w+"); rewind(fp2); fp=fopen(filename,"r"); rewind(fp); while(ch! =EOF) { ch=readLine(fp,dealline,&line); lenth=strlen(dealline); col1=0; for(col=0;col { if(isnote)/******noteshavechangedline***/ { if(dealline[col]=='*'&&dealline[col+1]=='/') { fputcc(&col1,dealline[col],fp1); fputcc(&col1,dealline[col+1],fp1); fputEnd(fp1); isnote=! isnote; col++;col1++; } elseif(dealline[col]=='\n') { fputcc(&col1,dealline[col],fp1); fputEnd(fp2); } else { fputcc(&col1,dealline[col],fp1); } } else/***justfindsomenotes******/ { if(dealline[col]=='/') { if(dealline[col+1]=='/') { fputTip(fp1,line,col1); for(i=col;i fputcc(&col1,dealline[i],fp1); fputEnd(fp2); col=lenth; } elseif(dealline[col+1]=='*') { fputTip(fp1,line,col1); fputcc(&col1,dealline[col],fp1); fputcc(&col1,dealline[col+1],fp1); isnote=! isnote; col++;col1++; } else { fputcc(&col1,dealline[col],fp2); } } else { fputcc(&col1,dealline[col],fp2); } } if(col==lenth&&isnote) fputEnd(fp2); } } fclose(fp1); fclose(fp2); fclose(fp); } /************Giveanendingtothecurrentline*********/ voidfputEnd(FILE*fp) { fputc('\n',fp); } voidfputTip(FILE*fp,intline,introw) { charnum[10]; fputs("(line: ",fp); ntoc(num,line); fputs(num,fp); fputs("col: ",fp); ntoc(num,row+1); fputs(num,fp); fputs(")",fp); } voidfputcc(int*col,charletter,FILE*fp) { if(letter=='\t') *col+=((TAB-(*col+1)%TAB)%TAB); fputc(letter,fp); } /*********exchangeastringtoanum***************/ intcton(char*str) { intlen,num3; len=strlen(str); switch(len) { case1: num3=str[0]-48;break; case2: num3=(str[0]-48)*10+(str[1]-48);break; case3: num3=(str[0]-48)*100+(str[1]-48)*10+(str[2]-48);break; case4: num3=(str[0]-48)*1000+(str[1]-48)*100+(str[2]-48)*10+(str[3]-48);break; case5: num3=(str[0]-48)*10000+(str[1]-48)*1000+(str[2]-48)*100+(str[3]-48)*10+(str[4]-48);break; dafult: gotoxy(1,1);printf("NOTENOUGHMENORY"); } return(num3); } /*********exchangeanumtoastring***************/ intntoc(char*buf,intnum1) { if(num1<10) {buf[0]=num1+48;buf[1]='\0';} elseif(num1<100) {buf[0]=num1/10+48;buf[1]=(num1%10)+48;buf[2]='\0';} elseif(num1<1000) {buf[0]=num1/100+48;buf[1]=(num1%100)/10+48;buf[2]=((num1%100)%10)+48;buf[3]='\0';} elseif(num1<10000) {buf[0]=num1/1000+48;buf[1]=(num1%1000)/100+48; buf[2]=((num1%1000)%100)/10+48;buf[3]=(((num1%1000)%100)%10)+48; buf[4]='\0';} elseif(num1<55000) {buf[0]=1+48;buf[1]=(num1%10000)/1000+48; buf[2]=((num1%10000)%1000)/100+48; buf[3]=(((num1%10000)%1000)%100)/10+48; buf[4]=((((num1%10000)%1000)%100)%10)+48; buf[5]='\0';} elseexit(0); return(OK); } /*******readfromafilelinebyline,positeitinaarray***/ /*******thereisnonotesinthefile***/ voidcheckOutWordsStream(char*filename) { inti,line=0,col,col1; chartempa[100],dealline[5000],ch=0; chardefinebuf[10000],valuebuf[100]; intlenth,winclude; FILE*fp,*fp1; checkDefine(definebuf); fp=fopen("c: \\temp.c","r"); fp1=fopen(filename,"w+"); while(ch! =EOF) { ch=readLine(fp,dealline,&line); lenth=strlen(dealline); fputline(fp1,dealline,line); col1=0; for(col=0;col { switch(dealline[col]) { case'\"': case'\'': { i=0; while(dealline[col+1]! ='\''&&dealline[col+1]! ='\"'&&col<(lenth-3)) { tempa[i++]=dealline[col++]; col1++; } tempa[i++]=dealline[col++];col1++; tempa[i++]=dealline[col];tempa[i]='\0'; if(isInclude(tempa)) fputWord(fp1,tempa,line,col1,"ERROR"); elseif(tempa[0]=='\"'&&winclude) fputWord(fp1,tempa,line,col1,"INCLUDEFILE"); elseif(tempa[0]=='\"') fputWord(fp1,tempa,line,col1,"STRING"); else fputWord(fp1,tempa,line,col1,"ACHAR"); winclude=0; break; } case'+': case'-': case'<': { if(winclude&&dealline[col]=='<')/*include { i=0; while(dealline[col]! ='>'&&col<(lenth-2)) { tempa[i++]=dealline[col]; c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 分析器