feat: made the firsts system for parser (not yet populated)
This commit is contained in:
parent
32e182bd50
commit
da1a73c264
3 changed files with 129 additions and 22 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue