// === Includes #include "grammar.h" #include #include #include "grammar_basic.h" // === Static variables // rule-indexed array containing firsts static struct firsts_list *firsts_map = NULL; // === Static functions /* @brief get the first accepted tokens of a rule * * @arg r the rule * @return the accepted tokens as a firsts_list struct */ static struct firsts_list *first(enum rule r) { if (firsts_map == NULL || firsts_map[r].tokens == NULL) { puts("Internal error: attempted to get the firsts of a rule without " "properly initializing the firsts map"); return NULL; } return &firsts_map[r]; } /* @brief Add a token to a rule's firsts (in firsts_map) * * @arg rule the rule to which add a first * @arg token the token to add to the rule's firsts * @return true on success, false on error */ static bool add_first(enum rule rule, struct token token) { struct firsts_list *item = &firsts_map[rule]; if (item->tokens != NULL) { // Check for duplicates for (size_t i = 0; i < item->list_length; i++) { if (item->tokens[i].type == token.type) return true; } // Append item->list_length++; item->tokens = realloc( item->tokens, (item->list_length) * sizeof(struct firsts_list)); } else { // Create entry item->tokens = calloc(item->list_length + 1, sizeof(struct firsts_list)); } // Check for alloc error if (item->tokens == NULL) { item->list_length = 0; return false; } // Fill item->list_length++; item->tokens[item->list_length - 1] = token; return true; } /* @brief initializes the firsts_map static variable (does not populate it) * @return true on success, false on error */ static bool init_firsts_map(void) { firsts_map = calloc(NUMBER_OF_RULES, sizeof(struct firsts_list)); if (firsts_map == NULL) { puts("Internal error: couldn't create the firsts_map (is your memory " "full ?)"); return false; } return true; } // === Functions bool grammar_init(void) { // Initialize the firsts map bool success = init_firsts_map(); if (success != true) return false; // Populate the firsts map // TODO return true; } void grammar_close(void) { // Deep free firsts map for (int i = 0; i < NUMBER_OF_RULES; i++) { if (firsts_map[i].tokens != NULL) { free(firsts_map[i].tokens); } } free(firsts_map); firsts_map = NULL; } struct ast *parse_input(struct lexer_context *ctx) { return parse_list(ctx); }