summaryrefslogtreecommitdiff
path: root/src/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse.c')
-rw-r--r--src/parse.c29
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]);