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

📄 scanner.cpp

📁 为简单的函数绘图语言编写一个解释器词法分析部分 黑屏幕下输入text.txt,然后看运行结果
💻 CPP
字号:
#include "scanner.h"
#define TOKEN_LEN 100    //记号最大长度
unsigned int LineNo;     //跟踪源文件记号
static FILE* InFile;     //输入文件流
static char TokenBuffer[TOKEN_LEN];  //记号字符缓冲

//--------------初始化词法分析器
extern int InitScanner(const char *FileName)
{
	LineNo=1;
	InFile=fopen(FileName,"r");
	if(InFile!=NULL)return 1;
	else return 0;
}

//--------------关闭词法分析器
extern void CloseScanner(void)
{
	if(InFile!=NULL)
		fclose(InFile);
}

//--------------从输入源程序中读入一个字符
static char GetChar(void)
{
	int Char=getc(InFile);
	return toupper(Char);
}

//-------------把预读入的字符退回到输入源程序中
static void BackChar(char Char)
{
	if(Char!=EOF)
	{
		ungetc(Char,InFile);
	}
}

//------------加入记号到字符缓冲区
static void AddCharTokenString(char Char)
{
	int TokenLength=strlen(TokenBuffer);
	if(TokenLength+1>=sizeof(TokenBuffer))
		return ;
	TokenBuffer[TokenLength]=Char;
	TokenBuffer[TokenLength+1]='\0';
}

//-------------清空记号缓冲区
static void EmptyTokenString()
{
	memset(TokenBuffer,0,TOKEN_LEN);
}

//-------------判断所给的字符串是否在符号表中
static Token JudgeKeyToken(const char* IDString)
{
	int loop;
	for(loop=0;loop<sizeof(TokenTab)/sizeof(TokenTab[0]);loop++)
	{
		if(strcmp(TokenTab[loop].lexeme,IDString)==0)
			return TokenTab[loop];
	}
	Token errortoken;
	memset(&errortoken,0,sizeof(Token));
	errortoken.type=ERRTOKEN;
	return errortoken;
}

//-------------获取一个记号
extern Token GetToken(void)
{
	Token token;
	int Char;

	memset(&token,0,sizeof(Token));
	EmptyTokenString();
	token.lexeme=TokenBuffer;
	for(;;)  //过滤掉源程序中的空格,TAB,回车等,遇到文件结束符返回空记号
	{
		Char=GetChar();
		if(Char==EOF)
		{
			token.type=NONTOKEN;
			return token;
		}
		if(Char=='\n')
			LineNo ++;
		if(!isspace(Char))
			break;
	}  //end of for
	AddCharTokenString(Char);
	//若不是空格,TAB,回车,文件结束符等,则先加入到记号的字符缓冲区中
	if(isalpha(Char))   //若char是A-Za-z,则一定是函数,关键字,P1,E等
	{
		for(;;)
		{
		Char=GetChar();
		if(isalnum(Char))
			AddCharTokenString(Char);
		else
			break;
		}
		BackChar(Char);
		token=JudgeKeyToken(TokenBuffer);
		token.lexeme=TokenBuffer;
		return token;
	}
	else if(isdigit(Char))   //若是一个数字则一定是常量
	{
		for(;;)
		{
			Char=GetChar();
			if(isdigit(Char))
			{
				AddCharTokenString(Char);
			}
			else break;
		}
		if(Char=='.')
		{
			AddCharTokenString(Char);
			for(;;)
			{
				Char=GetChar();
				if(isdigit(Char))
					AddCharTokenString(Char);
				else break;
			}
		}//end of if (Char=='.')

	BackChar(Char);
	token.type=CONST_ID;
	token.value=atof(TokenBuffer);
	return token;
	}
	else  //若不是字符和数字,则一定是运算符或分隔符
	{
		switch(Char)
		{
		case ';':token.type=SEMICO;break;
		case '(':token.type=L_BRACKET;break;
		case ')':token.type=R_BRACKET;break;
		case ',':token.type=COMMA;break;
		case '+':token.type=PLUS;break;
		case '-':
			Char=GetChar();
			if(Char=='-')
			{
				while(Char!='\n'&&Char!=EOF)
					Char=GetChar();
				BackChar(Char);
				return GetToken();
			}
			else 
			{
				BackChar(Char);
				token.type=MINUS;
				break;

			}
		case '/':
			Char=GetChar();
			if(Char=='/')
			{
				while(Char!='\n'&&Char!=EOF)
					Char=GetChar();
				BackChar(Char);
				return GetToken();
			}
			else
			{
				BackChar(Char);
				token.type=DIV;
				break;

			}
		case '*':
			Char=GetChar();
			if(Char=='*')
			{
				token.type=POWER;
				break;
			}
			else 
			{
				BackChar(Char);
				token.type=MUL;
				break;
			}
		default:token.type=ERRTOKEN;break;
		}// end of switch
	}//end of else(不是字母和数字,则一定是符号)
	return token;
}//end of GetToken

⌨️ 快捷键说明

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