分享一个词法分析器程序编译原理.docx
- 文档编号:9608843
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:48
- 大小:222.66KB
分享一个词法分析器程序编译原理.docx
《分享一个词法分析器程序编译原理.docx》由会员分享,可在线阅读,更多相关《分享一个词法分析器程序编译原理.docx(48页珍藏版)》请在冰豆网上搜索。
分享一个词法分析器程序编译原理
作者:
Fstone
E-mail:
1028592683@
一个简单词法分析器的实现
一、程序运行
在Linux中,进到源文件目录下,使用如下命令(↓代表回车键):
make↓//完成编译连接
./asrcFileName,outputFileName↓//运行程序,给出三个参数
注
a:
可执行文件名(可通过修改makefile文件来自定义它的名字)
srcFileName:
想要分析的源代码文件名
outputFileName:
结果输出文件名(缺省为out)
二、文件组织
Analysis.c主程序文件,只有一个main()函数。
symbol.h一些符号的宏定义
algorithm.c一些通用的算法,包括错误处理、整数区间限制。
io.c文件读写操作,标准输出。
list.c链表结构及其相关操作的定义。
table.c线性表及其相关操作的定义。
transact.c主要处理过程函数的定义。
makefile编译脚本文件。
三、实现原理
3.1数据结构
3.1.1.相连的两块扫描缓冲区
每当扫描完一块缓冲区,则调用ReadFile读入新的数据以更新这块缓冲区,与此同时搜索指针移入下一块内存。
每次对搜索指针加减操作之后,都要进行行一次修饰,即令
Search=(Search+2048)%2048
3.1.2线性表TableType
/////////////////////////////
//表元素:
字符串
////////////////////////////
typedefstruct
{
charstr[MAX_IDENTIFIER_LENGTH+1];
}String;
/////////////////////////////
//表
////////////////////////////
typedefstruct
{
intlen;//长度
Stringtable[MAX_IDENTIFIER_LENGTH+1];//关键字数组
}TableType;
作用:
存储关键字、算符、界符,
分别对应KeyTable、OprTable、MeteTable
3.1.3链表ListType
////////////////////////////
//结点
////////////////////////////
typedefstructNodeType
{
charstr[MAX_IDENTIFIER_LENGTH+1];
structNodeType*next;
}NodeType;
////////////////////////////
//链表
////////////////////////////
typedefstruct
{
intlen;//链表长度
NodeType*head;//链表头指针
NodeType*tail;//链表尾指针
}ListType;
作用:
存储标识符、常量,
分别对应IdList、ConstList
3.1.4单词表示Word
////////////////////////////
//单词表示
////////////////////////////
typedefstruct
{
inttypeNum;//类型编号
char*pointer;//(链)表内指针
}Word;
作用:
存储分析出的单词住处
3.2全局变量
/*扫描缓冲区(2块)
*分为前后等大两部分,交替使用
*buffer_0:
[0~LOAD_BUFFER_SIZE)
*buffer_1:
[LOAD_BUFFER_SIZE~DOUBLE_BUFFER_SIZE)*/
charScanBuffer[DOUBLE_BUFFER_SIZE];
intOldBuffer=0;//读完的缓冲区索引
unsignednLoadBytes=LOAD_BUFFER_SIZE;//一次读取字节数
intBufferSwitching=0;//扫描缓冲区更换标志
intStart=DOUBLE_BUFFER_SIZE,//起始指示器
Search=0;//搜索指示器
/*关键字表*/
TableTypeKeyTable={35,
"auto","double","int","struct","break","else",
"long","switch","case","enum","register","typedef",
"char","extern","return","union","const","float",
"short","unsigned","continue","for","signed","void",
"default","goto","sizeof","volatile","do","if",
"static","while","main","include","define"
};
/*界符表*/
TableTypeMeteTable={13,
"(",")","[","]","{","}",
"#","<",">",";",":
",",",
"."};
/*算符表*/
TableTypeOprTable={12,
"+","-","*","/","%","=",
"&","|","!
","^","~","?
"
};
/*标识符链*/
ListTypeIdList={0,NULL,NULL};
/*常量链*/
ListTypeConstList={0,NULL,NULL};
/*文件*/
charInFileName[30],OutFileName[30];//输入/输出文件
longInFilePos=0,OutFilePos=0;//输入/输出文件的当前指针位置
intNotFileEnd=1;//文件未读完标志
/*临时字符ch,字符串strToken,串尾指针strTail*/
charch='',nextch='',strToken[MAX_IDENTIFIER_LENGTH];
intstrTail=0;
3.3重要逻辑功能函数
3.3.1charFetchar();从缓冲区中取一字符给ch变量
取一个字符给ch
Search加1,对Search进行求模修饰(防止越界)
预取下一个字符给nextch
返回ch
3.3.2voidBachar();向缓冲区退回一个字符
Search减1
对Search进行求模修饰(防止越界)
3.3.3intGetBC();过滤无效字符
过滤'\0''\r''\n''''\\''\t'
过滤注释行、块///**/
遇到有效字符返回0,否则返回非0
3.3.4voidValidStart();定位单词的开始
过滤无效字符
检查是否有缓冲区已经读完,更新读完的缓冲区
将起始指针Start与搜索指针Search置于同一位置
将字符串尾指针置0
3.3.5intIsLetter();判断ch是否是字母或者下划线
ch如果在['a','z']或者['A','Z']之间,或者等于'_'则返回真,否则返回假。
3.3.5intIsDigit();判断ch是否是数字
ch如果在['0','9']之间返回真,否则返回假。
3.3.6intConcat();将ch连接到strToken尾
strTail记录了strToken的结尾位置,所以使strToken[strTail]=ch,并且令strTail加1,
同时返回strTail的值。
3.3.7char*ParseWord(int*typeNum);解析一个单词
解析strToken,如果解析成功,用*typeNum带回strToken的符号类型,并且返回它
在相应表(关键字表、界符表、算符表)或者链表(常量链表、标识符链表)中的指针。
3.3.8intAnalysis(char*inFileName,char*outFileName);分析源代码
两个参数分别给出源文件名和分析输出文件名,或输出文件未给出则默认取out文件名。
这个函数将调用以上所提到的功能函数,以及文件IO函数(定义在io.c中)等。
它是
实现词法分析器的主框架函数。
4、附主要代码
//////////////////////////////////////////////////////////////////////////////////////
//4.0makefile
//////////////////////////////////////////////////////////////////////////////////////
#编译器
CC=gcc
#编译选项
CFLAGS=-c-g
#链接选项
LDFLAGS=
#源文件
SOURCES=Analysis.cio.ctransact.clist.calgorithm.ctable.c
#目标文件
OBJECTS=$(SOURCES:
.c=.o)
#可执行文件
EXECUTABLE=a
#链接
$(EXECUTABLE):
$(OBJECTS)
$(CC)$(LDFLAGS)$(OBJECTS)-o$(EXECUTABLE)
#编译
Analysis.o:
Analysis.c
$(CC)$(CFLAGS)Analysis.c
transact.o:
transact.c
$(CC)$(CFLAGS)transact.c
identlist.o:
identlist.c
$(CC)$(CFLAGS)identlist.c
io.o:
io.c
$(CC)$(CFLAGS)io.c
algorithm.o:
algorithm.c
$(CC)$(CFLAGS)algorithm.c
#清除命令
clean:
rm-rf$(OBJECTS)$(EXECUTABLE)
//////////////////////////////////////////////////////////////////////////////////////
//4.1Analysis.c
//////////////////////////////////////////////////////////////////////////////////////
#include"transact.h"
/***************************
*主函数
***************************/
intmain(intargc,char*argv[])
{
Analysis(argv[1],argv[2]);
return0;
}
//////////////////////////////////////////////////////////////////////////////////////
//4.2symbol.h
//////////////////////////////////////////////////////////////////////////////////////
#include
//条件编译
#ifndefSYMBOL_HEADER
#defineSYMBOL_HEADER
/***************************
*宏定义
**************************/
#defineLOAD_BUFFER_SIZE(1024*sizeof(char))//加载缓冲区大小
#defineDOUBLE_BUFFER_SIZE(2*LOAD_BUFFER_SIZE)//两个缓冲区大小
#defineMAX_IDENTIFIER_LENGTH180//标识符最大长度
/***************************
*符号种类定义
**************************/
//界符0--[0,100)
#defineMETE000//(
//算符1--[100,200)
#defineOPR_AND100//+
//常量2--[200,300)
#defineCONST_INT200//整数
#defineCONST_CHAR201//字符
#defineCONST_REAL202//实数float/double
#defineCONST_STR203//串
//标识符3--[300,400)
#defineIDENTIFIER300
//关键字4--[400,500)
#defineKEY_WORD400
////////////////
//单词表示
///////////////
typedefstruct
{
inttypeNum;//类型编号
char*pointer;//(链)表内指针
}Word;
//条件编译结束
#endif
//////////////////////////////////////////////////////////////////////////////////////
//4.3table.h
//////////////////////////////////////////////////////////////////////////////////////
//条件编译
#ifndefTABLE_HEADER
#defineTABLE_HEADER
#include"symbol.h"
////////////////
//表元素:
字符串
///////////////
typedefstruct
{
charstr[MAX_IDENTIFIER_LENGTH+1];
}String;
////////////////
//字符串表
///////////////
typedefstruct
{
intlen;//长度
Stringtable[MAX_IDENTIFIER_LENGTH+1];//关键字数组
}TableType;
/***************************
*在表中查找strToken
*返回:
<0:
未找到
*>=0:
返回表中索引
***************************/
intInTableOf(TableType*pTable,charstr[]);
//条件编译结束
#endif
//////////////////////////////////////////////////////////////////////////////////////
//4.4table.c
//////////////////////////////////////////////////////////////////////////////////////
#include"table.h"
/***************************
*在表中查找strToken
*返回:
<0:
未找到
*>=0:
返回表中索引
***************************/
intInTableOf(TableType*pTable,charstr[])
{
intlen=pTable->len;
intindex=0;
for(;index { if(0==strcmp(pTable->table[index].str,str)) returnindex; } return-1; } ////////////////////////////////////////////////////////////////////////////////////// //4.5transact.h ////////////////////////////////////////////////////////////////////////////////////// //条件编译 #ifndefTRANSACT_HEADER #defineTRANSACT_HEADER /*************************** *从缓冲区取一个字符给ch,并将搜索指针后移一位 *返回: 此字符 ***************************/ charFetchar(); /*************************** *退回一个字符 ***************************/ voidBachar(); /*************************** *过虑空白/回车/注释 *返回: 0当前ch有效 *非0ch无效 ***************************/ intGetBC(); /*************************** *定位下一个合法单词的起始指针 ***************************/ voidValidStart(); /*************************** *ch是字母或_下划线 ***************************/ intIsLetter(); /*************************** *ch是数字 ***************************/ intIsDigit(); /*************************** *将ch连接到strToken尾 *返回: strToken的长度 ***************************/ intConcat(); /*************************** *解析一个单词 *返回: 单词在链表或表中的字符串首地址 *typeNum输出其类型码 ***************************/ char*ParseWord(int*typeNum); /*************************** *解析源代码文件 *返回: <=0解析失败 *>0成功 ***************************/ intAnalysis(char*inFileName,char*outFileName); //条件编译结束 #endif ////////////////////////////////////////////////////////////////////////////////////// //4.6transact.c ////////////////////////////////////////////////////////////////////////////////////// #include"transact.h" #include"symbol.h" #include"list.h" #include"table.h" #include"algorithm.h" ////////////////////////////////////////////////////// //全局变量 ////////////////////////////////////////////////////// /*关键字表*/ TableTypeKeyTable={35, "auto","double","int","struct","break","else", "long","switch","case","enum","register","typedef", "char","extern","return","union","const","float", "short","unsigned","continue","for","signed","void", "default","goto","sizeof","volatile","do","if", "static","while","main","include","define" }; /*界符表*/ TableTypeMeteTable={13, "(",")","[","]","{","}", "#","<",">",";",": ",",", "." }; /*算符表*/ TableTypeOprTable={12, "+","-","*","/","%","=", "&","|","! ","^","~","? " }; /*标识符链*/ ListTypeIdList={0,NULL,NULL}; /*常量链*/ ListTypeConstList={0,NULL,NULL}; /*文件*/ charInFileName[30],OutFileName[30];//输入/输出文件 longInFilePos=0,OutFilePos=0;//输入/输出文件的当前指针位置 intNotFileEnd=1;//文件未读完标志 /*扫描缓冲区(2块) *分为前后等大两部分,交替使用 *buffer_0: [0~LOAD_BUFFER_SIZE) *buffer_1: [LOAD_BUFFER_SIZE~DOUBLE_BUFFER_SIZE)*/ charScanBuffer[DOUBLE_BUFFER_SIZE]; intOldBuffer=0;//读完的缓冲区索
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分享 一个 词法 分析器 程序 编译 原理
![提示](https://static.bdocx.com/images/bang_tan.gif)