diff options
Diffstat (limited to 'src/parse.c')
| -rw-r--r-- | src/parse.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..27ee417 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,143 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include "parse.h" +#include "hashtable.h" + +int symtoi(sym_t* symbol) { + return *((int*)symbol->name); +} +float symtof(sym_t* symbol) { + return *((float*)symbol->name); +} +char* symtos(sym_t* symbol) { + return (char*)symbol->name; +} + +void symbol_add_arg(sym_t* symbol, sym_t* arg) { + symbol->argCount += 1; + if (symbol->argCount == 1) { + symbol->args = malloc(sizeof(sym_t*)); + } + else { + symbol->args = realloc(symbol->args, symbol->argCount * (sizeof(sym_t*))); + } + (symbol->args)[symbol->argCount - 1] = arg; +} +void symset_add_symbol(symset_t* symbolSet, sym_t* symbol) { + symbolSet->count += 1; + if (symbolSet->count == 1) { + symbolSet->symbols = malloc(sizeof(sym_t*)); + } + else { + symbolSet->symbols = realloc(symbolSet->symbols, symbolSet->count * (sizeof(sym_t*))); + } + (symbolSet->symbols)[symbolSet->count - 1] = symbol; +} +symset_t* parse_symbols(char** str) { + symset_t* symbolSet = malloc(sizeof(symset_t)); + symbolSet->count = 0; + while (1) { + /* clear whitespace */ + while (!isalnum(**str) && **str != '(' && **str != ')' && **str != '\0') { + (*str)++; + } + if (**str == ')') { + (*str)++; + return symbolSet; + } + else if (**str == '\0') { + return symbolSet; + } + char* symbolName = calloc(30, sizeof(char)); + int i = 0; + while (1) { + symbolName[i] = **str; + if (**str == ',' || **str == ';') { + (*str)++; + sym_t* symbol = malloc(sizeof(sym_t)); + symbol->province = LITERAL; + symbol->argCount = 0; + symbolName[i] = '\0'; + /* TODO: float */ + /* string */ + if (isalpha(symbolName[0])) { + //symbolName = realloc(symbolName, i * sizeof(char)); + symbol->name = symbolName; + symbol->litType = STRING; + } + /* int */ + else { + int v = atoi(symbolName); + int* vp = malloc(sizeof(int)); + *vp = v; + symbol->name = (void*)vp; + free(symbolName); + symbol->litType = INT; + } + symset_add_symbol(symbolSet, symbol); + break; + } + else if (**str == '(') { + (*str)++; + symbolName[i] = '\0'; + sym_t* symbol = malloc(sizeof(sym_t)); + symbol->province = KEY_REF; + symbol->argCount = 0; + if (i > 1) { + symbol->name = symbolName; + } + else { + symbol->name = "root"; + } + symset_t* symbols = parse_symbols(str); + for (int s = 0; s < symbols->count; s++) { + symbol_add_arg(symbol, symbols->symbols[s]); + } + symset_add_symbol(symbolSet, symbol); + break; + } + i++; + (*str)++; + } + } +} +sym_t* parse_symbol_final(char* str) { + char** strp = malloc(sizeof(char**)); + *strp = str; + symset_t* finalSymset = parse_symbols(strp); + sym_t* root = malloc(sizeof(sym_t)); + root->name = "root"; + root->province = KEY_REF; + root->argCount = 0; + for (int s = 0; s < finalSymset->count; s++) { + symbol_add_arg(root, finalSymset->symbols[s]); + } + return root; +} +void write_symbol_visual(sym_t* symbol, int offset) { + for (int o = 0; o < offset; o++) { + printf(" "); + } + if (symbol->province == KEY_REF) { + printf("%s (%s)\n", (char*)(symbol->name), "KEY"); + } + else if (symbol->province == LITERAL) { + if (symbol->litType == INT) { + printf("%d (%s)\n", *(int*)(symbol->name), "LITERAL"); + } + else if (symbol->litType == FLOAT) { + printf("%f (%s)\n", *(float*)(symbol->name), "LITERAL"); + } + else if (symbol->litType == STRING) { + printf("%s (%s)\n", (char*)(symbol->name), "LITERAL"); + } + } + else { + printf("symbol parse error\n"); + } + for (int i = 0; i < symbol->argCount; i++) { + write_symbol_visual(symbol->args[i], offset + 4); + } +} |
