OpenFPGA/libs/libvtrutil/src/vtr_token.cpp

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;
}