213 lines
5.4 KiB
C++
213 lines
5.4 KiB
C++
/**
|
|
* Jason Luu
|
|
* July 22, 2009
|
|
* Tokenizer
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
#include "vtr_assert.h"
|
|
#include "vtr_log.h"
|
|
#include "vtr_util.h"
|
|
#include "vtr_memory.h"
|
|
#include "vtr_token.h"
|
|
|
|
enum e_token_type GetTokenTypeFromChar(const enum e_token_type cur_token_type,
|
|
const char cur);
|
|
|
|
bool IsWhitespace(char c);
|
|
|
|
/* Returns true if character is whatspace between tokens */
|
|
bool IsWhitespace(char c) {
|
|
switch (c) {
|
|
case ' ':
|
|
case '\t':
|
|
case '\r':
|
|
case '\n':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Returns a token list of the text for a given string. */
|
|
t_token* GetTokensFromString(const char* inString, int* num_tokens) {
|
|
const char* cur;
|
|
t_token* tokens;
|
|
int i, in_string_index, prev_in_string_index;
|
|
bool has_null;
|
|
enum e_token_type cur_token_type, new_token_type;
|
|
|
|
*num_tokens = i = 0;
|
|
cur_token_type = TOKEN_NULL;
|
|
|
|
if (inString == nullptr) {
|
|
return nullptr;
|
|
};
|
|
|
|
cur = inString;
|
|
|
|
/* Count number of tokens */
|
|
while (*cur) {
|
|
new_token_type = GetTokenTypeFromChar(cur_token_type, *cur);
|
|
if (new_token_type != cur_token_type) {
|
|
cur_token_type = new_token_type;
|
|
if (new_token_type != TOKEN_NULL) {
|
|
i++;
|
|
}
|
|
}
|
|
++cur;
|
|
}
|
|
*num_tokens = i;
|
|
|
|
if (*num_tokens > 0) {
|
|
tokens = (t_token*)vtr::calloc(*num_tokens + 1, sizeof(t_token));
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
|
|
/* populate tokens */
|
|
i = 0;
|
|
in_string_index = 0;
|
|
has_null = true;
|
|
prev_in_string_index = 0;
|
|
cur_token_type = TOKEN_NULL;
|
|
|
|
cur = inString;
|
|
|
|
while (*cur) {
|
|
new_token_type = GetTokenTypeFromChar(cur_token_type, *cur);
|
|
if (new_token_type != cur_token_type) {
|
|
if (!has_null) {
|
|
tokens[i - 1].data[in_string_index - prev_in_string_index] = '\0'; /* NULL the end of the data string */
|
|
has_null = true;
|
|
}
|
|
if (new_token_type != TOKEN_NULL) {
|
|
tokens[i].type = new_token_type;
|
|
tokens[i].data = vtr::strdup(inString + in_string_index);
|
|
prev_in_string_index = in_string_index;
|
|
has_null = false;
|
|
i++;
|
|
}
|
|
cur_token_type = new_token_type;
|
|
}
|
|
++cur;
|
|
in_string_index++;
|
|
}
|
|
|
|
VTR_ASSERT(i == *num_tokens);
|
|
|
|
tokens[*num_tokens].type = TOKEN_NULL;
|
|
tokens[*num_tokens].data = nullptr;
|
|
|
|
/* Return the list */
|
|
return tokens;
|
|
}
|
|
|
|
void freeTokens(t_token* tokens, const int num_tokens) {
|
|
int i;
|
|
for (i = 0; i < num_tokens; i++) {
|
|
free(tokens[i].data);
|
|
}
|
|
free(tokens);
|
|
}
|
|
|
|
enum e_token_type GetTokenTypeFromChar(const enum e_token_type cur_token_type,
|
|
const char cur) {
|
|
if (IsWhitespace(cur)) {
|
|
return TOKEN_NULL;
|
|
} else {
|
|
if (cur == '[') {
|
|
return TOKEN_OPEN_SQUARE_BRACKET;
|
|
} else if (cur == ']') {
|
|
return TOKEN_CLOSE_SQUARE_BRACKET;
|
|
} else if (cur == '{') {
|
|
return TOKEN_OPEN_SQUIG_BRACKET;
|
|
} else if (cur == '}') {
|
|
return TOKEN_CLOSE_SQUIG_BRACKET;
|
|
} else if (cur == ':') {
|
|
return TOKEN_COLON;
|
|
} else if (cur == '.') {
|
|
return TOKEN_DOT;
|
|
} else if (cur >= '0' && cur <= '9' && cur_token_type != TOKEN_STRING) {
|
|
return TOKEN_INT;
|
|
} else {
|
|
return TOKEN_STRING;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool checkTokenType(const t_token token, enum e_token_type token_type) {
|
|
if (token.type != token_type) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void my_atof_2D(float** matrix, const int max_i, const int max_j, const char* instring) {
|
|
int i, j;
|
|
char *cur, *cur2, *copy, *final;
|
|
|
|
copy = vtr::strdup(instring);
|
|
final = copy;
|
|
while (*final != '\0') {
|
|
final++;
|
|
}
|
|
|
|
cur = copy;
|
|
i = j = 0;
|
|
while (cur != final) {
|
|
while (IsWhitespace(*cur) && cur != final) {
|
|
if (j == max_j) {
|
|
i++;
|
|
j = 0;
|
|
}
|
|
cur++;
|
|
}
|
|
if (cur == final) {
|
|
break;
|
|
}
|
|
cur2 = cur;
|
|
while (!IsWhitespace(*cur2) && cur2 != final) {
|
|
cur2++;
|
|
}
|
|
*cur2 = '\0';
|
|
VTR_ASSERT(i < max_i && j < max_j);
|
|
matrix[i][j] = vtr::atof(cur);
|
|
j++;
|
|
cur = cur2;
|
|
*cur = ' ';
|
|
}
|
|
|
|
VTR_ASSERT((i == max_i && j == 0) || (i == max_i - 1 && j == max_j));
|
|
|
|
free(copy);
|
|
}
|
|
|
|
/* Date:July 2nd, 2013 *
|
|
* Author: Daniel Chen *
|
|
* Purpose: Checks if the number of entries (separated by whitespace) *
|
|
* matches the the expected number (max_i * max_j), *
|
|
* can be used before calling my_atof_2D */
|
|
bool check_my_atof_2D(const int max_i, const int max_j, const char* instring, int* num_entries) {
|
|
/* Check if max_i * max_j matches number of entries in instring */
|
|
const char* cur = instring;
|
|
bool in_str = false;
|
|
int entry_count = 0;
|
|
|
|
/* First count number of entries in instring */
|
|
while (*cur != '\0') {
|
|
if (!IsWhitespace(*cur) && !in_str) {
|
|
in_str = true;
|
|
entry_count++;
|
|
} else if (IsWhitespace(*cur)) {
|
|
in_str = false;
|
|
}
|
|
cur++;
|
|
}
|
|
*num_entries = entry_count;
|
|
|
|
if (max_i * max_j != entry_count) return false;
|
|
return true;
|
|
}
|