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

📄 scanner.cpp

📁 编译原理的三个子模块,包括词法分析,语法分析和语义分析,是绘图语言解释器
💻 CPP
字号:
// ----------------------------- scanner.cpp ---------------------------------
// 词法分析器类的定义

#include "scanner.h"

// ---------------初始化词法分析器
int scanner_class::init_scanner(const char *file_name)
{
	in_flie = fopen(file_name, "r");
	if (in_flie != NULL)  return 1;
	else                  return 0;
}

// ---------------关闭词法分析器
void scanner_class::close_scanner(void)
{
	if (in_flie != NULL) fclose (in_flie) ;
}

// ---------------从输入源程序中读入一个字符
char scanner_class::get_char(void)
{
	int next_char = getc(in_flie);   return toupper(next_char);
}

// ---------------把预读的字符退回到输入源程序中
void scanner_class::back_char(char next_char)
{
	if (next_char != EOF)   ungetc(next_char, in_flie);
}

// ---------------加入字符到记号缓冲区
void scanner_class::add_in_token_str(char next_char)
{
	int token_len = strlen (token_buf);
	if (token_len + 1 >= sizeof (token_buf)) return;
	token_buf[token_len]   = next_char;
	token_buf[token_len+1] = str_end;
}

// ----------------- 清空记号缓冲区
void scanner_class::empty_token_str ()
{	
	memset(token_buf, 0, token_len);
} 

// ----------------- 判断所给的字符串是否在符号表中
token_rec scanner_class::check_token(const char * c_str)
{	
	int count;
	token_rec err_token;
	
	for (count=0; count<sizeof(token_table)/sizeof(token_table[0]); count++)
	{ if (strcmp(token_table[count].lexeme, c_str)==0) return token_table[count];
	}
	memset(&err_token, 0, sizeof(token_rec));
	err_token.type = ERRTOKEN;
	return err_token;
}

// ---------------获取一个记号
token_rec scanner_class::get_token(void)
{	
	token_rec token;
	int next_char ;
	
	memset(&token, 0, sizeof(token_rec));
	empty_token_str();
	token.lexeme = token_buf;
	for (;;)	// 过滤源程序中的空格、TAB、回车等,遇到文件结束符返回空记号
	{	next_char = get_char() ;
		if (next_char == EOF)
		{	token.type = NONTOKEN;
			return token;
		}
		if (next_char == '\n')	line_no ++ ;
		if (!isspace(next_char))	break ;
	} // end of for 
	add_in_token_str (next_char);	// 若不是空格、TAB、回车、文件结束符等,
									// 则先加入到记号的字符缓冲区中
	if(isalpha(next_char))			// 若char是A-Za-z,则它一定是函数、关键字、PI、E等
	{	for (;;)
		{	next_char = get_char () ;
			if ( isalnum(next_char) )	add_in_token_str (next_char) ;
			else					break ;
		}
		back_char (next_char) ;
		token = check_token (token_buf);
		token.lexeme = token_buf;
		return token;
	}	
	else if(isdigit(next_char))		// 若是一个数字,则一定是常量
	{	for (;;)
		{	next_char = get_char () ;
			if (isdigit(next_char))	add_in_token_str (next_char) ;
			else				break ;
		}
		if (next_char == '.')
		{	add_in_token_str (next_char) ;
			for (;;)
			{	next_char = get_char() ;
				if (isdigit(next_char))	add_in_token_str (next_char) ;
				else				break ;
			}
			
		} // end of if (next_char == '.')
		back_char (next_char) ;
		token.type = CONST_ID;
		token.value = atof (token_buf);
		return token;
	}
	else	// 不是字母和数字,则一定是符号
	{	switch (next_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 '-' :
				next_char = get_char();
				if (next_char =='-')
				{	while (next_char != '\n' && next_char != EOF) next_char = get_char();
					back_char(next_char);
					return get_token();
				}
				else 
				{	back_char(next_char);
					token.type = MINUS;
					break;
				}
			case '/' :
				next_char = get_char();
				if (next_char =='/') 
				{	while (next_char != '\n' && next_char != EOF) next_char = get_char();
					back_char(next_char);
					return get_token();
				}
				else
				{	back_char(next_char);
					token.type = DIV;
					break;
				}
			case '*' :
				next_char = get_char() ;
				if (next_char == '*')	token.type = POWER ;
				else 
				{	back_char (next_char);	
					token.type = MUL; 
				}
				break;
			default: 
				token.type = ERRTOKEN; 
		} // end of switch
	} // end of else(不是字母和数字,则一定是符号)
	return token;
} // end of get_token

⌨️ 快捷键说明

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