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

📄 lexer.cpp

📁 3D游戏开发需要用到BSP树来经行场景渲染的管理。本代码包含完整的BSP及文件生成实现
💻 CPP
字号:
#include "lexer.h"
#include "log.h"

CString& CLexer::ReadRestOfLine() {
	int new_pos = cur_pos;

	while(data[new_pos] != '\n') {
		if(data[new_pos] == NULL) {
			g_CLog.Log(LOG_SYSTEM, LOG_LEX_EOF_INSIDE_COMMENT, NULL);
			break;
		}else
			new_pos++;
	}
	if(data[new_pos] != NULL)
		cur_line++;
#if LEX_NULL_DELIMIT
	data[new_pos] = 0;
#endif
	token = CString (data + cur_pos, new_pos - cur_pos, false);
	cur_pos = new_pos + 1;
	return token;
}


int CLexer::ReadWhiteSpace() {
	// special characters have ascii code less than SPACE
	while(data[cur_pos] <= ' ' || data[cur_pos] == '/') {
		if(data[cur_pos] == NULL)
			return L_EOF;
		else if(data[cur_pos] == '\n')
			cur_line++;
		else if(data[cur_pos] == '/') { // comments
			if (data[cur_pos + 1] == '/') {
				ReadRestOfLine();
				continue;
			} else if (data[cur_pos + 1] == '*') {
				cur_pos += 2;
				while(!(data[cur_pos] == '*' && data[cur_pos+1] == '/')) {
					if(data[cur_pos] == NULL) {
						g_CLog.Log(LOG_SYSTEM, LOG_LEX_EOF_INSIDE_COMMENT, NULL);
						return L_EOF;
					}else if(data[cur_pos] == '\n')
						cur_line++;
					cur_pos++;
				}
				cur_pos++;
			}
		}

		cur_pos++;
	}
	return L_OK;
}

int CLexer::ReadInt() {
	GetToken();
	if(type == TT_INT)
		return atoi(token.GetData());
	else {
		g_CLog.Log(LOG_SYSTEM, "Lex: on line %d expected int, got %s.\n", cur_line, &token);
		return 0;
	}
}

float CLexer::ReadFloat() {
	GetToken();
	if(type == TT_FLOAT || type == TT_INT)
		return (float)atof(token.GetData());
	else {
		g_CLog.Log(LOG_SYSTEM, "Lex: on line %d expected float, got %s.\n", cur_line, &token);
		return 0;
	}
}

CString& CLexer::GetToken() {
	if(token_ready) {
		token_ready = false;
		return token;
	}
	
	bool seems_int = true;
	bool seems_float = false;

	if(ReadWhiteSpace() == L_EOF) {
		token = CString(false);
		return token;
	}

	int new_pos = cur_pos;

	// string
	if(data[new_pos] == '\"' || data[new_pos] == '\'') {
		type = TT_STRING;
#if LEX_NULL_DELIMIT
		data[new_pos] = 0;
		cur_pos++;
#endif
		new_pos++;
		while (data[new_pos] >= ' ' && 
			!(data[new_pos] == '\"' || data[new_pos] == '\'')) {
			if(data[cur_pos] == '\n')
				cur_line++;
			new_pos++;
		}
#if LEX_NULL_DELIMIT
		// this leaks a byte
		data[new_pos] = 0;
#endif
		new_pos++;
	} else {
		// word token
		while (data[new_pos] > ' ' && data[new_pos] != '\t') {
			// check for numbers
			if(data[new_pos] == '.' ||
				((data[new_pos] == 'f' || data[new_pos] == 'F') &&
				(data[new_pos+1] == ' ' || data[new_pos+1] == '\t'))) {
				if(new_pos != cur_pos)
					seems_float = true;
			} else if(data[new_pos] < '0' || data[new_pos] > '9')
				if(new_pos != cur_pos || data[new_pos] != '-')
					seems_int = false;
			new_pos++;
		}

		if(seems_int) {
			if(seems_float)
				type = TT_FLOAT;
			else
				type = TT_INT;
		} else
			type = TT_WORD;
	}

	if(data[new_pos] == '\n')
		cur_line++;

#if LEX_NULL_DELIMIT
	// properly terminate the token;
	data[new_pos] = 0;
#endif

	int len = new_pos - cur_pos;
	if (len) {
		if(type == TT_STRING) // remove quotes
			len--;
		token = CString(data + cur_pos, len, false);
	}
	else
		token = CString(false);

	// jump over the white space
	cur_pos = new_pos + 1;

	return token;
}


CString& CLexer::PeekToken() {
	if(!token_ready) {
		GetToken();
		token_ready = true;	
	}
	return token;
}

CString& CLexer::FindNext(char *str, int str_len) {
	// unget any ready tokens
	if(token_ready) {
		cur_pos--;
		data[cur_pos] = ' ';
		cur_pos -= token.Length();
		token_ready = false;
	}

	int new_pos = cur_pos;
	while(data[new_pos] != NULL) {
		if(data[new_pos] == str[0] &&
			( str_len == 1 || !strncmp(data+new_pos, str, str_len) )) {
				new_pos += str_len;
				break;
		} else if(data[new_pos] == '\n')
			cur_line++;
		new_pos++;
	}

	int len = new_pos - cur_pos;
	token = CString(data + cur_pos, len, false);

	cur_pos = new_pos + 1;

#if LEX_NULL_DELIMIT
	// properly terminate the token;
	data[new_pos] = 0;
#endif

	return token;
}

void CLexer::ReadMatrix1D(float *fptr, int n) {
	FindNext("(");
	for(int i=0; i<n ;i++)
		*fptr++ = ReadFloat();
	FindNext(")");
}

⌨️ 快捷键说明

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