merge parser in dev
This commit is contained in:
commit
56f0a979a7
5 changed files with 102 additions and 49 deletions
|
|
@ -68,7 +68,11 @@ enum token_type
|
||||||
TOKEN_FI,
|
TOKEN_FI,
|
||||||
TOKEN_ELIF,
|
TOKEN_ELIF,
|
||||||
TOKEN_AND,
|
TOKEN_AND,
|
||||||
TOKEN_OR
|
TOKEN_OR,
|
||||||
|
TOKEN_FOR,
|
||||||
|
TOKEN_WHILE,
|
||||||
|
TOKEN_UNTIL,
|
||||||
|
TOKEN_CASE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token
|
struct token
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../lexer/lexer.h"
|
|
||||||
#include "grammar_basic.h"
|
#include "grammar_basic.h"
|
||||||
|
|
||||||
// === Static variables
|
// === Static variables
|
||||||
|
|
@ -57,6 +56,23 @@ static bool add_first(enum rule rule, enum token_type token)
|
||||||
return true;
|
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)
|
/* @brief initializes the firsts_map static variable (does not populate it)
|
||||||
* @return true on success, false on error
|
* @return true on success, false on error
|
||||||
*/
|
*/
|
||||||
|
|
@ -73,21 +89,6 @@ static bool init_firsts_map(void)
|
||||||
return true;
|
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
|
// === Functions
|
||||||
|
|
||||||
bool grammar_init(void)
|
bool grammar_init(void)
|
||||||
|
|
@ -98,46 +99,85 @@ bool grammar_init(void)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Populate the firsts map
|
// Populate the firsts map
|
||||||
add_first(RULE_INPUT, TOKEN_WORD);
|
// TODO CHECK ORDER
|
||||||
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);
|
|
||||||
|
|
||||||
|
// If
|
||||||
add_first(RULE_IF, TOKEN_IF);
|
add_first(RULE_IF, TOKEN_IF);
|
||||||
|
|
||||||
add_first(RULE_COMPOUND_LIST, TOKEN_NEWLINE);
|
// Else clause
|
||||||
add_first(RULE_COMPOUND_LIST, TOKEN_WORD);
|
|
||||||
add_first(RULE_COMPOUND_LIST, TOKEN_IF);
|
|
||||||
|
|
||||||
add_first(RULE_ELSE_CLAUSE, TOKEN_ELSE);
|
add_first(RULE_ELSE_CLAUSE, TOKEN_ELSE);
|
||||||
add_first(RULE_ELSE_CLAUSE, TOKEN_ELIF);
|
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(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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,13 @@ enum rule
|
||||||
RULE_ELEMENT,
|
RULE_ELEMENT,
|
||||||
RULE_REDIRECTION,
|
RULE_REDIRECTION,
|
||||||
RULE_PREFIX,
|
RULE_PREFIX,
|
||||||
|
RULE_FUNCDEC,
|
||||||
|
RULE_WHILE,
|
||||||
|
RULE_UNTIL,
|
||||||
|
RULE_FOR,
|
||||||
|
RULE_CASE,
|
||||||
|
RULE_CASE_CLAUSE,
|
||||||
|
RULE_CASE_ITEM,
|
||||||
NUMBER_OF_RULES
|
NUMBER_OF_RULES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -89,6 +96,7 @@ bool is_first(struct token token, enum rule rule);
|
||||||
* | '\n'
|
* | '\n'
|
||||||
* | EOF
|
* | EOF
|
||||||
* ;
|
* ;
|
||||||
|
* @first first(list), '\n', EOF
|
||||||
*/
|
*/
|
||||||
struct ast *parse_input(struct lexer_context *ctx);
|
struct ast *parse_input(struct lexer_context *ctx);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ struct ast *parse_command(struct lexer_context *ctx)
|
||||||
perror("Syntax error: unexpected token");
|
perror("Syntax error: unexpected token");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ struct ast *parse_if_rule(struct lexer_context *ctx);
|
||||||
struct ast *parse_compound_list(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
|
* @code else_clause = 'else' compound_list
|
||||||
* | 'elif' compound_list 'then' compound_list [else_clause]
|
* | 'elif' compound_list 'then' compound_list [else_clause]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue