⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanfiles.h

📁 一个简单的词法分析程序。是编译原理的部分课程设计。因为时间有限。未能完成全部。如果有朋友改了代码或添加了功能使代码更加完善。请与我联系:ningmeng_studio@163.com谢谢. 做的不是
💻 H
字号:
/*=============================================
**             2005-8-22					**
**			  读取源文件	 				**
**			 lizhu zhang					**
=============================================*/
#define NULL 0
//================================================
#include "FILEOP.h"
#include "Matchkeywords.h"
#include "HandleCom.h"
#include "GetWord.h"
#include "TestWordExistOrNot.h"
#include "SymbleLinkList.h"
/*=============================================
**函数用能:从源文件中读取字符串,然后进行分类.
**参数说明:[in]pString:接受传入的字符串, 为源文件的名称
**		   [in]findError:是否查错标志0,不查错,1查错.此功能由词法分析调用
**		   [in]tcount:要查找的token的位置
**返回值  : 连表的头指针
**===========================================*/
Sl * FScanFile(const char *pString)
{	
	//符号表 
	Sl	  *symbleList;
	symbleList = (struct SYMBELLIST*)malloc(sizeof(SYMBELLIST));
	Sl	  *pHead = NULL;
	symbleList->name.addr = 0;
	symbleList->addr = -1;
	//符号串
	Token *token;
	token = (struct TOKEN*)malloc(sizeof(TOKEN));
	token->addr = 0;
	//变量自身值
	pRMsg pMsg;
	pMsg = (pRMsg)malloc(sizeof(RMSG));
	//对当前分析的代码所在过程的层计数
	unsigned int layer = -1;
	//种别码
	int kind;
	//定义一个单词记录数组
	char newWord[2048];
	//列的临时计数,也作为注释行返回的接受者
	int tempCol;
	//错误信息结构
	PErrMsg pErrMsg;
	//分配空间
	pErrMsg = (struct ERRMSG*)malloc(sizeof(ERRMSG));
	//错误信息缓冲区
	char errMsg[1024];
	//定义行列计数
	int row(1),col(0);
	//错误标识
	int err = 0;
	//字符串缓冲区
	char word[2048];
	//源文件结束标志:1,文件未结束;0,文件结束
	int  flagSoceEnd(1);
	//标识下一个单词是否为过程名称:1,是;0,不是
	int  procFlag(0);
	//对关键字'end'的标志
	int endFlag(0);
	//从源文件中读取一行数据
	err = FFileRead(pString,word,row,flagSoceEnd);
	//对资源文件的行进行计数
	int vRowCount = 0;
	//过程结束的中间标志
	int endTmpFlg = 0;
	while(err&&flagSoceEnd)
	{
		//对行进行处理,看是否为注释行
		tempCol = FHandleCom(word,errMsg);
		if(tempCol == -1)
		{
			//是注释行,不进行任何操作
				;
		}			//不是注释行
		else if(tempCol == 0)
			{
				do
				{
					//存放检测值是否存在的函数的返回值的临时变量
				//	int testWordExist;
					//获得一个单词,并的到列计数
					FGetWord(word,col,newWord);
					//对单词进行识别
					kind = FFindKind(newWord,errMsg,tempCol);
					//关键字的种别码和界限符号的种别码
					if((kind>=1&&kind<=33)||(kind>=38&&kind<=60))
					{
						//设置是否重写过程名的标志
						if((kind == 21 || kind == 22) && endFlag == 0)
							procFlag=1;
						else
							if((kind == 21 || kind == 22) && endFlag == 1 && endTmpFlg ==1)
							{
								//当前过程结束
								layer -= 1;
								if(layer == -1)
								{
									//注释行错误
									col = tempCol;
									pErrMsg->row = row;
									pErrMsg->col = col;
									pErrMsg->pErrMsg = "错误的程序结构!!!";
									//如果写入错误信息失败则退出整个分析过程
									if(!FFileWrite("ErrorMessage.txt",2,pErrMsg))
										return pHead;
								}
								//清除'end'标志
								endFlag = 0;
								endTmpFlg = 0;
							}
							else
								if((kind == 21 || kind == 22) && endFlag == 1 && endTmpFlg ==0)
								{
									endTmpFlg = 1;
								}
						//设置end的标志
						if(kind == 11)
							endFlag = 1;						
						//关键字和界限符的种别码为0
						token->addr=0;
						token->code = kind;
						//写token文件
						FFileWrite("token.tk",0,token);	
					}
					else
					{
						//如果标志为1,则说明现在的变量属于新的过程
						//添加新代码
						switch(kind)
						{
						case 34://标识符
								//写符号表信息
								symbleList->name.addr++;
								symbleList->name.len = strlen(newWord);
								if(procFlag == 1)
								{
									//将过程的层数加1
									layer++;
									symbleList->layer = layer;
									symbleList->kind = "过程名";
									symbleList->pNext = NULL;
									procFlag = 0;
									//写三个文件
									//写资源文件
									//对资源文件计数加1
									vRowCount ++;
									//将变量写入资源文件
									//设置变量自身值结构信息
									strcpy(pMsg->pMsg,newWord);
									pMsg->num = layer;
									FFileWrite("reliable.txt",3,pMsg);
									//写符号表
									//记录写入的符号表节点的位置,以写token文件
									int nodeCount;
									pHead = FInsertNode(symbleList,pHead,nodeCount);
									//写token信息
									token->addr = nodeCount;
									token->code = 34;
									//*
									FFileWrite("token.tk",0,token);
								}else//将其他变量等信息写入符号表,token表和资源文件
								{
									//设置符号表信息
									symbleList->layer = layer;
									symbleList->kind = "变量";
									symbleList->type ="标识符";
									symbleList->pNext = NULL;
									//写三个文件
									//写资源文件
									//对资源文件计数加1
									vRowCount ++;
									//将变量写入资源文件
									//设置变量自身值结构信息
									strcpy(pMsg->pMsg,newWord);
									pMsg->num = layer;
									FFileWrite("reliable.txt",3,pMsg);
									//写符号表
									//记录写入的符号表节点的位置,以写token文件
									int nodeCount;
									pHead = FInsertNode(symbleList,pHead,nodeCount);
									//写token信息
									token->addr = nodeCount;
									token->code = 34;
									//*
									FFileWrite("token.tk",0,token);

								}					
								break;
						case 35://整常数
							{
								//写符号表信息
								symbleList->name.addr++;
								symbleList->name.len = strlen(newWord);
								symbleList->layer = layer;
								symbleList->kind = "变量";
								symbleList->type ="整常数";
								symbleList->pNext = NULL;
								//写三个文件
								//写资源文件
								//对资源文件计数加1
								vRowCount ++;
								//将变量写入资源文件
								//设置变量自身值结构信息
								strcpy(pMsg->pMsg,newWord);
								pMsg->num = layer;
								FFileWrite("reliable.txt",3,pMsg);
								//写符号表
								//记录写入的符号表节点的位置,以写token文件
								int nodeCount;
								pHead = FInsertNode(symbleList,pHead,nodeCount);
								//写token信息
								token->addr = nodeCount;
								token->code = 35;
								//*
								FFileWrite("token.tk",0,token);
							}
							break;
						case 36://实常数
							{
								//写符号表信息
								symbleList->name.addr++;
								symbleList->name.len = strlen(newWord);
								symbleList->layer = layer;
								symbleList->kind = "变量";
								symbleList->type ="实常数";
								symbleList->pNext = NULL;
								//写三个文件
								//写资源文件
								//对资源文件计数加1
								vRowCount ++;
								//将变量写入资源文件
								//设置变量自身值结构信息
								strcpy(pMsg->pMsg,newWord);
								pMsg->num = layer;
								FFileWrite("reliable.txt",3,pMsg);
								//写符号表
								//记录写入的符号表节点的位置,以写token文件
								int nodeCount;
								pHead = FInsertNode(symbleList,pHead,nodeCount);
								//写token信息
								token->addr = nodeCount;
								token->code = 36;
								//*
				
								FFileWrite("token.tk",0,token);
							}
							break;
						case 37://实常数
							{
								//写符号表信息
								symbleList->name.addr++;
								symbleList->name.len = strlen(newWord);
								symbleList->layer = layer;
								symbleList->kind = "变量";
								symbleList->type ="实符常数";
								symbleList->pNext = NULL;
								//写三个文件
								//写资源文件
								//对资源文件计数加1
								vRowCount ++;
								//将变量写入资源文件,写文件的时候去掉开头和结尾的'''号
								int j = 1;
								while(newWord[j]!='\'')
								{
									newWord[j-1]=newWord[j];
									j++;
								}
								newWord[j-1]='\0';
								//设置变量自身值结构信息
								strcpy(pMsg->pMsg,newWord);
								pMsg->num = layer;
								FFileWrite("reliable.txt",3,pMsg);
								//写符号表
								//记录写入的符号表节点的位置,以写token文件
								int nodeCount;
								pHead = FInsertNode(symbleList,pHead,nodeCount);
								//写token信息
								token->addr = nodeCount;
								token->code = 37;
								//*
								FFileWrite("token.tk",0,token);
							}
							break;
						default://错误
							if(kind >=61)
							{
								pErrMsg->row = row;
								pErrMsg->col = col +tempCol+kind - 62;
								pErrMsg->pErrMsg = errMsg;
								if(!FFileWrite("ErrorMessage.txt",2,pErrMsg))
									return pHead;
							}
							break;

						}
						//在这里写符号表文件

						//在这里写token文件
					}
					//单词识别完毕,对列加一,以获得本行中的其他单词
					col +=1;
				}while(col<=(int)strlen(word));
				
			}		
			else
				{
					//注释行错误
					col = tempCol;
					pErrMsg->row = row;
					pErrMsg->col = col;
					pErrMsg->pErrMsg = errMsg;
					//如果写入错误信息失败则退出整个分析过程
					if(!FFileWrite("ErrorMessage.txt",2,pErrMsg))
						return pHead;
				}
		//对列初始化
		col = 0;
		//行计数加1
		row++;
		//获得新的一行
		err = FFileRead(pString,word,row,flagSoceEnd);
		
	}
	//将token节点的所有信息保存到文件
	FOutToFile(pHead);
	return pHead;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -