From b657d65664a27f55c23d58d984fcae5892afcfb8 Mon Sep 17 00:00:00 2001 From: matteo Date: Wed, 28 Jan 2026 12:11:40 +0100 Subject: [PATCH] feat(parser): parse_command version with prefixes and elements --- src/parser/grammar_basic.c | 69 +++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/src/parser/grammar_basic.c b/src/parser/grammar_basic.c index f3e63b6..932d7f5 100644 --- a/src/parser/grammar_basic.c +++ b/src/parser/grammar_basic.c @@ -153,11 +153,11 @@ struct ast *parse_command(struct lexer_context *ctx) { struct token *token = PEEK_TOKEN(); - if (token->type == TOKEN_WORD) + if (is_first(*token, RULE_SIMPLE_COMMAND)) { return parse_simple_command(ctx); } - else if (token->type == TOKEN_IF) + else if (is_first(*token, RULE_SHELL_COMMAND)) { return parse_shell_command(ctx); } @@ -168,23 +168,54 @@ struct ast *parse_command(struct lexer_context *ctx) } } +/* @brief: frees command_elements and redirections lists + * @return: NULL + */ +static err_simple_command(struct list *command_elements, + struct list *redirections) +{ + list_deep_destroy(command_elements); + list_deep_destroy(redirections); + return NULL; +} + struct ast *parse_simple_command(struct lexer_context *ctx) { struct list *command_elements = NULL; struct list *redirections = NULL; // list of redirection ASTs - // WORD - struct token *token = POP_TOKEN(); - if (token->type != TOKEN_WORD) + bool has_prefix = false; + struct token *token = PEEK_TOKEN(); + if (is_first(*token, RULE_PREFIX)) + { + has_prefix = true; + while (is_first(*token, RULE_PREFIX)) + { + struct ast *redir = parse_prefix(ctx); + if (redir == NULL) + { + return err_simple_command(command_elements, redirections); + } + redirections = list_append(redirections, redir); + token = PEEK_TOKEN(); + } + } + + if (token->type != TOKEN_WORD && !has_prefix) { perror("Expected a command but got a different token type"); - return NULL; + return err_simple_command(command_elements, redirections); } - char *command = strdup(token->data); - command_elements = list_append(command_elements, command); - - token = PEEK_TOKEN(); + + // we can have only prefixes askip + if (token->type == TOKEN_WORD) + { + char *command = strdup(token->data); + command_elements = list_append(command_elements, command); + POP_TOKEN(); + token = PEEK_TOKEN(); + } // Eventual elements while (is_first(*token, RULE_ELEMENT)) { @@ -192,16 +223,20 @@ struct ast *parse_simple_command(struct lexer_context *ctx) struct ast *element = parse_element(ctx); if (element == NULL) { - list_deep_destroy(command_elements); - return NULL; + return err_simple_command(command_elements, redirections); } // Get element type if (ast_is_word(element)) { struct ast_word *element_word = ast_get_word(element); + + // TODO test this fix for the memory leaks + char *word = strdup(element_word->word); + ast_free(element_word); command_elements = - list_append(command_elements, element_word->word); + list_append(command_elements, word); + // end of fix } else if (ast_is_redir(element)) { @@ -212,9 +247,7 @@ struct ast *parse_simple_command(struct lexer_context *ctx) { perror("Internal error: unexpected return value from parse_element " "in parse_simple_command"); - list_deep_destroy(command_elements); - list_deep_destroy(redirections); - return NULL; + return err_simple_command(command_elements, redirections); } // Forward @@ -225,9 +258,7 @@ struct ast *parse_simple_command(struct lexer_context *ctx) struct ast *result = ast_create_command(command_elements, redirections); if (result == NULL) { - list_deep_destroy(command_elements); - list_deep_destroy(redirections); - return NULL; + return err_simple_command(command_elements, redirections); } return result; }