diff options
Diffstat (limited to 'src/parse.c')
| -rw-r--r-- | src/parse.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/parse.c b/src/parse.c index 3811eae..f8749ac 100644 --- a/src/parse.c +++ b/src/parse.c @@ -77,27 +77,34 @@ void symset_add_symbol(symset_t* symbolSet, sym_t* symbol) { } (symbolSet->symbols)[symbolSet->count - 1] = symbol; } -symset_t* parse_symbols(char** str) { +symset_t* parse_symbols(char** str, int* sLine) { symset_t* symbolSet = malloc(sizeof(symset_t)); symbolSet->count = 0; while (1) { /* clear whitespace */ while (!isalnum(**str) && **str != '"' && **str != '-' && **str != '(' && **str != ')' && **str != '\0') { + /* increment line counter if newline read */ + if (**str == '\n') { + (*sLine)++; + } (*str)++; } + /* ended args, return what we have */ if (**str == ')') { (*str)++; return symbolSet; } + /* EOF. return what we have and expect resolution */ else if (**str == '\0') { return symbolSet; } - char* symbolName = calloc(30, sizeof(char)); + char* symbolName = calloc(50, sizeof(char)); char isFloat = 0; char isString = 0; int i = 0; while (1) { symbolName[i] = **str; + /* do not allow control flow to exit here. strings naturally treat special characters differently */ if (**str == '"') { /* start quote */ if (!isString) { @@ -114,10 +121,13 @@ symset_t* parse_symbols(char** str) { } } else if (!isString) { + /* the non-string symbol contains a decimal. it must be a float */ if (**str == '.') { isFloat = 1; } + /* we've hit a character that cannot be part of the symbol. parse the prior characters as the symbol name */ else if (!isalnum(**str) && **str != '-' && **str != '(') { + /* move the pointer back, because the close paren is needed to return the calling function */ if (**str == ')') { (*str)--; } @@ -152,6 +162,7 @@ symset_t* parse_symbols(char** str) { symset_add_symbol(symbolSet, symbol); break; } + /* special case when symbol is terminated by args */ else if (**str == '(') { (*str)++; symbolName[i] = '\0'; @@ -162,7 +173,7 @@ symset_t* parse_symbols(char** str) { else { symbol = init_sym_key("root"); } - symset_t* symbols = parse_symbols(str); + symset_t* symbols = parse_symbols(str, sLine); for (int s = 0; s < symbols->count; s++) { symbol_add_arg(symbol, symbols->symbols[s]); } @@ -176,6 +187,13 @@ symset_t* parse_symbols(char** str) { } i++; (*str)++; + if (i > 50) { + printf("Parser error on line %d: symbol exceeds maximum length (%d)\n", *sLine, i - 1); + if (isString) { + printf("Did you fail to terminate a string?\n"); + } + return NULL; + } } free(symbolName); } @@ -183,8 +201,11 @@ symset_t* parse_symbols(char** str) { sym_t* parse_symbol_final(char* str) { char** strp = malloc(sizeof(char**)); *strp = str; - symset_t* finalSymset = parse_symbols(strp); + int* linep = malloc(sizeof(int*)); + *linep = 1; + symset_t* finalSymset = parse_symbols(strp, linep); free(strp); + free(linep); sym_t* root = init_sym_key("root"); for (int s = 0; s < finalSymset->count; s++) { symbol_add_arg(root, finalSymset->symbols[s]); |
