📄 lexer.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 + -