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

📄 scanner.cpp

📁 用VC做的一个简单编译器.实现简单的画图
💻 CPP
字号:

// ----------------------------- scanner.cpp ---------------------------------

#include "..\\funcdraw\\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,则它一定是函数、关键字、PI、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);
					//token.type = NONTOKEN;
			       // return token;
					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 + -