feat: final firsts initialization
This commit is contained in:
parent
98d18eef7d
commit
3601c3136f
5 changed files with 104 additions and 50 deletions
|
|
@ -68,7 +68,11 @@ enum token_type
|
|||
TOKEN_FI,
|
||||
TOKEN_ELIF,
|
||||
TOKEN_AND,
|
||||
TOKEN_OR
|
||||
TOKEN_OR,
|
||||
TOKEN_FOR,
|
||||
TOKEN_WHILE,
|
||||
TOKEN_UNTIL,
|
||||
TOKEN_CASE
|
||||
};
|
||||
|
||||
struct token
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../lexer/lexer.h"
|
||||
#include "grammar_basic.h"
|
||||
|
||||
// === Static variables
|
||||
|
|
@ -57,6 +56,23 @@ static bool add_first(enum rule rule, enum token_type token)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* @brief Add a list of tokens to a rule's firsts (in firsts_map)
|
||||
*
|
||||
* @arg rule the rule to which add a first
|
||||
* @arg tokens_list the list of tokens to add to the rule's firsts
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
static bool add_firsts(enum rule rule, struct firsts_list *tokens_list)
|
||||
{
|
||||
for (size_t i = 0; i < tokens_list->list_length; i++)
|
||||
{
|
||||
bool res = add_first(rule, tokens_list->tokens[i]);
|
||||
if (!res)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @brief initializes the firsts_map static variable (does not populate it)
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
|
|
@ -73,21 +89,6 @@ static bool init_firsts_map(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* @brief: add all the redirection token_types to the first of [rule].
|
||||
* this also contains IONUMBER
|
||||
*/
|
||||
static void add_first_redir(enum rule rule)
|
||||
{
|
||||
add_first(rule, TOKEN_IONUMBER);
|
||||
add_first(rule, TOKEN_REDIR_LEFT);
|
||||
add_first(rule, TOKEN_REDIR_RIGHT);
|
||||
add_first(rule, TOKEN_REDIR_LEFT_RIGHT);
|
||||
add_first(rule, TOKEN_REDIR_DOUBLE_RIGHT);
|
||||
add_first(rule, TOKEN_REDIR_LEFT_AMP);
|
||||
add_first(rule, TOKEN_REDIR_RIGHT_AMP);
|
||||
add_first(rule, TOKEN_REDIR_RIGHT_PIPE);
|
||||
}
|
||||
|
||||
// === Functions
|
||||
|
||||
bool grammar_init(void)
|
||||
|
|
@ -98,46 +99,85 @@ bool grammar_init(void)
|
|||
return false;
|
||||
|
||||
// Populate the firsts map
|
||||
add_first(RULE_INPUT, TOKEN_WORD);
|
||||
add_first(RULE_INPUT, TOKEN_IF);
|
||||
add_first(RULE_COMMAND, TOKEN_NEGATION);
|
||||
add_first(RULE_INPUT, TOKEN_NEWLINE);
|
||||
add_first(RULE_INPUT, TOKEN_EOF);
|
||||
|
||||
add_first(RULE_LIST, TOKEN_WORD);
|
||||
add_first(RULE_LIST, TOKEN_IF);
|
||||
add_first(RULE_LIST, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_AND_OR, TOKEN_WORD);
|
||||
add_first(RULE_AND_OR, TOKEN_IF);
|
||||
add_first(RULE_AND_OR, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_PIPELINE, TOKEN_WORD);
|
||||
add_first(RULE_PIPELINE, TOKEN_IF);
|
||||
add_first(RULE_PIPELINE, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_COMMAND, TOKEN_WORD);
|
||||
add_first(RULE_COMMAND, TOKEN_IF);
|
||||
|
||||
add_first(RULE_SIMPLE_COMMAND, TOKEN_WORD);
|
||||
|
||||
add_first(RULE_SHELL_COMMAND, TOKEN_IF);
|
||||
// TODO CHECK ORDER
|
||||
|
||||
// If
|
||||
add_first(RULE_IF, TOKEN_IF);
|
||||
|
||||
add_first(RULE_COMPOUND_LIST, TOKEN_NEWLINE);
|
||||
add_first(RULE_COMPOUND_LIST, TOKEN_WORD);
|
||||
add_first(RULE_COMPOUND_LIST, TOKEN_IF);
|
||||
|
||||
// Else clause
|
||||
add_first(RULE_ELSE_CLAUSE, TOKEN_ELSE);
|
||||
add_first(RULE_ELSE_CLAUSE, TOKEN_ELIF);
|
||||
|
||||
// For
|
||||
add_first(RULE_FOR, TOKEN_FOR);
|
||||
|
||||
// While
|
||||
add_first(RULE_WHILE, TOKEN_WHILE);
|
||||
|
||||
// Until
|
||||
add_first(RULE_WHILE, TOKEN_UNTIL);
|
||||
|
||||
// Case
|
||||
add_first(RULE_CASE, TOKEN_CASE);
|
||||
|
||||
// Case item
|
||||
add_first(RULE_CASE_ITEM, TOKEN_LEFT_PAREN);
|
||||
add_first(RULE_CASE_ITEM, TOKEN_WORD);
|
||||
|
||||
// Case clause
|
||||
add_firsts(RULE_CASE_CLAUSE, first(RULE_CASE_ITEM));
|
||||
|
||||
// Redirection
|
||||
add_first(RULE_REDIRECTION, TOKEN_IONUMBER);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_LEFT);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_RIGHT);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_LEFT_RIGHT);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_DOUBLE_RIGHT);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_LEFT_AMP);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_RIGHT_AMP);
|
||||
add_first(RULE_REDIRECTION, TOKEN_REDIR_RIGHT_PIPE);
|
||||
// %RIP Matteo 30/01/2026
|
||||
|
||||
// Element
|
||||
add_first(RULE_ELEMENT, TOKEN_WORD);
|
||||
add_first_redir(RULE_ELEMENT);
|
||||
add_firsts(RULE_ELEMENT, first(RULE_REDIRECTION));
|
||||
|
||||
add_first_redir(RULE_REDIRECTION);
|
||||
// Prefix
|
||||
add_first(RULE_PREFIX, TOKEN_ASSIGNMENT_WORD);
|
||||
add_firsts(RULE_PREFIX, first(RULE_REDIRECTION));
|
||||
|
||||
add_first_redir(RULE_PREFIX);
|
||||
// Shell command
|
||||
add_firsts(RULE_SHELL_COMMAND, first(RULE_IF));
|
||||
|
||||
// Simple command
|
||||
add_firsts(RULE_SIMPLE_COMMAND, first(RULE_PREFIX));
|
||||
|
||||
// Funcdec
|
||||
add_first(RULE_FUNCDEC, TOKEN_WORD);
|
||||
|
||||
// Command
|
||||
add_firsts(RULE_COMMAND, first(RULE_SIMPLE_COMMAND));
|
||||
add_firsts(RULE_COMMAND, first(RULE_SHELL_COMMAND));
|
||||
add_firsts(RULE_COMMAND, first(RULE_FUNCDEC));
|
||||
|
||||
// Pipeline
|
||||
add_first(RULE_PIPELINE, TOKEN_WORD);
|
||||
add_firsts(RULE_PIPELINE, first(RULE_COMMAND));
|
||||
|
||||
// And Or
|
||||
add_firsts(RULE_AND_OR, first(RULE_PIPELINE));
|
||||
|
||||
// Compound list
|
||||
add_first(RULE_COMPOUND_LIST, TOKEN_NEWLINE);
|
||||
add_firsts(RULE_COMPOUND_LIST, first(RULE_AND_OR));
|
||||
|
||||
// List
|
||||
add_firsts(RULE_LIST, first(RULE_AND_OR));
|
||||
|
||||
// Input
|
||||
add_first(RULE_INPUT, TOKEN_NEWLINE);
|
||||
add_first(RULE_INPUT, TOKEN_EOF);
|
||||
add_firsts(RULE_INPUT, first(RULE_LIST));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ enum rule
|
|||
RULE_ELEMENT,
|
||||
RULE_REDIRECTION,
|
||||
RULE_PREFIX,
|
||||
RULE_FUNCDEC,
|
||||
RULE_WHILE,
|
||||
RULE_UNTIL,
|
||||
RULE_FOR,
|
||||
RULE_CASE,
|
||||
RULE_CASE_CLAUSE,
|
||||
RULE_CASE_ITEM,
|
||||
NUMBER_OF_RULES
|
||||
};
|
||||
|
||||
|
|
@ -89,6 +96,7 @@ bool is_first(struct token token, enum rule rule);
|
|||
* | '\n'
|
||||
* | EOF
|
||||
* ;
|
||||
* @first first(list), '\n', EOF
|
||||
*/
|
||||
struct ast *parse_input(struct lexer_context *ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -160,13 +160,15 @@ struct ast *parse_command(struct lexer_context *ctx)
|
|||
}
|
||||
else if (is_first(*token, RULE_SHELL_COMMAND))
|
||||
{
|
||||
parse_shell_command(ctx);
|
||||
result = parse_shell_command(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("Syntax error: unexpected token");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* @brief: frees command_elements and redirections lists (helper func)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ struct ast *parse_if_rule(struct lexer_context *ctx);
|
|||
struct ast *parse_compound_list(struct lexer_context *ctx);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* @brief parses an else clause rule (inside if)
|
||||
*
|
||||
* @code else_clause = 'else' compound_list
|
||||
* | 'elif' compound_list 'then' compound_list [else_clause]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue