feat: made the firsts system for parser (not yet populated)

This commit is contained in:
Gu://em_ 2026-01-24 13:06:39 +01:00
parent 32e182bd50
commit da1a73c264
3 changed files with 129 additions and 22 deletions

View file

@ -1,30 +1,105 @@
#define _POSIX_C_SOURCE 200809L
// === Includes
#include "grammar.h"
#include "../utils/hash_map/hash_map.h"
#include <stdio.h>
#include <stdlib.h>
#include "grammar_basic.h"
// === Static variables
static struct hash_map *firsts_map = NULL;
// rule-indexed array containing firsts
static struct firsts_list *firsts_map = NULL;
// === Static functions
static enum token_type first(enum rule r)
/* @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)
{
// TODO
return TOKEN_NULL;
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)
{
// Create firsts hashmap
// TODO
// Initialize the firsts map
bool success = init_firsts_map();
if (success != true)
return false;
// Populate the hashmap
// Populate the firsts map
// TODO
return true;
@ -32,7 +107,16 @@ bool grammar_init(void)
void grammar_close(void)
{
// TODO free hashmap
// 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)