| /** | |
| * Jason Luu | |
| * July 22, 2009 | |
| * Tokenizer | |
| */ | |
| #include <cstring> | |
| using namespace std; | |
| #include "vtr_assert.h" | |
| #include "vtr_log.h" | |
| #include "vtr_util.h" | |
| #include "vtr_memory.h" | |
| #include "token.h" | |
| #include "read_xml_util.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 == NULL) { | |
| return NULL; | |
| }; | |
| 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 NULL; | |
| } | |
| /* 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 = NULL; | |
| /* 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; | |
| } | |