#include #include #include #include #include "parse.h" #include "hashtable.h" sym_t* init_sym(prov_t province, litType_t litType, void* name) { sym_t* symbol = malloc(sizeof(sym_t)); symbol->province = province; symbol->litType = litType; symbol->name = name; symbol->argCount = 0; return symbol; } void destroy_sym(sym_t* symbol) { free(symbol->name); free(symbol->args); free(symbol); } 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)++; symbolName[i] = '\0'; sym_t* symbol; /* TODO: float */ /* string */ if (isalpha(symbolName[0])) { //symbolName = realloc(symbolName, i * sizeof(char)); symbol = init_sym(LITERAL, STRING, symbolName); } /* int */ else { int v = atoi(symbolName); int* vp = malloc(sizeof(int)); *vp = v; free(symbolName); symbol = init_sym(LITERAL, INT, vp); } symset_add_symbol(symbolSet, symbol); break; } else if (**str == '(') { (*str)++; symbolName[i] = '\0'; sym_t* symbol; if (i > 1) { symbol = init_sym(KEY_REF, NO_TYPE, symbolName); } else { free(symbolName); char* memName = malloc(5 * sizeof(char)); strcpy(memName, "root"); symbol = init_sym(KEY_REF, NO_TYPE, memName); } 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); char* memName = malloc(5 * sizeof(char)); strcpy(memName, "root"); sym_t* root = init_sym(KEY_REF, NO_TYPE, memName); 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); } }