diff --git a/src/parser/parsing_utils.c b/src/parser/parsing_utils.c index 0d0f43a..f1408c5 100644 --- a/src/parser/parsing_utils.c +++ b/src/parser/parsing_utils.c @@ -52,9 +52,57 @@ struct ast *parse_input(void) return parse_list(); } -/* Parses a simple list of words (command and arguments) - * and returns the resulting ast - */ +struct ast *parse_list(void) +{ + struct list *result_list = NULL; + struct ast *current_node = NULL; + + struct token *token = PEEK_TOKEN(); + + while (!is_end_of_list(token)) + { + if (token->type == TOKEN_SEMICOLON) + { + result_list = list_append(result_list, current_node); + } + else + { + current_node = parse_and_or(); + } + token = PEEK_TOKEN(); + } + + return ast_create_list(result_list); +} + +struct ast *parse_and_or(void) +{ + return parse_pipeline(); +} + +struct ast *parse_pipeline(void) +{ + return parse_command(); +} + +struct ast *parse_command(void) +{ + struct token *token = PEEK_TOKEN(); + + if (token->type == TOKEN_WORD) + { + return parse_simple_command(); + } + else if (token->type == TOKEN_IF) + { + return parse_shell_command(); + } + else + { + return ast_create_void(); // TODO not sure what to do + } +} + struct ast *parse_simple_command(void) { struct list *command_elements = NULL; @@ -71,30 +119,23 @@ struct ast *parse_simple_command(void) return result; } -struct ast *parse_list(void) +// TODO check compliance with the grammar +struct ast *parse_shell_command(void) { - struct list *result_list = NULL; - struct ast *current_node = NULL; - struct token *token = PEEK_TOKEN(); - while (!is_end_of_list(token)) + switch (token->type) { - if (token->type == TOKEN_SEMICOLON) - { - result_list = list_append(result_list, current_node); - } - else - { - // TODO use parse_and_or() instead. - current_node = parse_simple_command(); - } - token = PEEK_TOKEN(); - } + case TOKEN_IF: + return parse_if_rule(); - return ast_create_list(result_list); + default: + puts("I think it's not implemented yet"); + return NULL; + } } +// TODO check compliance with the grammar struct ast *parse_if_rule(void) { // If condition @@ -143,6 +184,7 @@ struct ast *parse_if_rule(void) return result; } +// TODO comply with header's grammar struct ast *parse_compound_list(void) { struct list *result_list = NULL; // ast* list @@ -178,19 +220,44 @@ struct ast *parse_compound_list(void) struct ast *parse_else_clause(void) { - // Eventual elif content struct token *token = PEEK_TOKEN(); + // TODO handle ELIF + // Eventual elif content + while (token->type == TOKEN_ELIF) + { + // Condition + token = POP_TOKEN(); + struct ast *condition = parse_compound_list(); + + // 'then' + token = POP_TOKEN(); + if (token->type != TOKEN_THEN) + { + puts("Expected the 'then' keyword but got a different token type"); + return NULL; + } + + // Then clause + struct ast *then_content = parse_compound_list(); + + // Eventual else clause (recursive) + struct ast *else_content = NULL; + token = PEEK_TOKEN(); + if (token->type == TOKEN_ELSE || token_type == TOKEN_ELIF) + { + else_content = parse_else_clause(); + } + + struct ast *result = + ast_create_if(condition, then_content, else_content); + return result; + } + + // Eventual else content + struct ast *result = NULL; - // TODO handle ELIF - // while (token->type == TOKEN_ELIF) - // { - // puts("ABORTING ELIF: Not implemented ma gueule"); - // token = POP_TOKEN(); // Forward - // } - - // Eventual else content if (token->type == TOKEN_ELSE) { result = parse_compound_list(); @@ -202,18 +269,3 @@ struct ast *parse_else_clause(void) return result; } - -struct ast *parse_shell_command(void) -{ - struct token *token = PEEK_TOKEN(); - - switch (token->type) - { - case TOKEN_IF: - return parse_if_rule(); - - default: - puts("I think it's not implemented yet"); - return NULL; - } -} diff --git a/src/parser/parsing_utils.h b/src/parser/parsing_utils.h index 3c9101c..f4c5a68 100644 --- a/src/parser/parsing_utils.h +++ b/src/parser/parsing_utils.h @@ -20,11 +20,6 @@ } /* @brief Acts as the entry point of the parser, calls parse_list - */ -struct ast* parse_input(void); - -/* @brief: parses a list of [and_or] rules separated by semicolons and that - * ends by a newline * * @code input = list '\n' * | list EOF @@ -32,6 +27,13 @@ struct ast* parse_input(void); * | EOF * ; */ +struct ast* parse_input(void); + +/* @brief: parses a list of [and_or] rules separated by semicolons and that + * ends by a newline + * + * @code list = and_or { ';' and_or } [ ';' ] ; + */ struct ast *parse_list(void); /* @brief Only parses a pipeline rule for the moment