diff --git a/src/parser/grammar_basic.c b/src/parser/grammar_basic.c index b7f58bd..f0f96f9 100644 --- a/src/parser/grammar_basic.c +++ b/src/parser/grammar_basic.c @@ -68,8 +68,13 @@ struct ast *parse_list(struct lexer_context *ctx) token = PEEK_TOKEN(); while (token->type == TOKEN_SEMICOLON) { - token = POP_TOKEN(); + // Forward + POP_TOKEN(); token = PEEK_TOKEN(); + + // TODO seems a little akward (not fully compliant with the grammar) + // but it's time consuming to rewrite to only cover edge cases. + // So it'll probably stay like that for now if (is_first(*token, RULE_AND_OR)) { current_node = parse_and_or(ctx); @@ -304,8 +309,26 @@ struct ast *parse_element(struct lexer_context *ctx) struct token *token = PEEK_TOKEN(); if (token->type == TOKEN_WORD || token->type == TOKEN_ASSIGNMENT_WORD) { - token = POP_TOKEN(); - return ast_create_word(token->data); + POP_TOKEN(); + + char *word = strdup(token->data); + if (word == NULL) + { + perror("Internal error: could not copy token data (is your memory " + "full ?)"); + return NULL; + } + + struct ast *result = ast_create_word(word); + if (result == NULL) + { + perror("Internal error: could not create ast node (is your memory " + "full ?)"); + free(word); + return NULL; + } + + return result; } else if (token->type == TOKEN_IONUMBER || is_token_redir(token)) { @@ -378,12 +401,15 @@ struct ast *parse_if_rule(struct lexer_context *ctx) // Condition content struct ast *condition_content = parse_compound_list(ctx); + if (condition_content == NULL) + return NULL; + token = PEEK_TOKEN(); // Then keyword - token = PEEK_TOKEN(); if (token->type != TOKEN_THEN) { - perror("Expected the 'then' keyword but token has different type"); + perror("Syntax error: Expected the 'then' keyword but token has " + "different type"); return err_if_rule(&condition_content, NULL, NULL); } POP_TOKEN(); @@ -394,9 +420,9 @@ struct ast *parse_if_rule(struct lexer_context *ctx) { return err_if_rule(&condition_content, &then_content, NULL); } + token = PEEK_TOKEN(); struct ast *else_content = NULL; - token = PEEK_TOKEN(); // Eventual else/elif clause(s) if (is_first(*token, RULE_ELSE_CLAUSE)) { @@ -405,10 +431,10 @@ struct ast *parse_if_rule(struct lexer_context *ctx) { return err_if_rule(&condition_content, &then_content, NULL); } + token = PEEK_TOKEN(); } // Fi keyword - token = PEEK_TOKEN(); if (token->type != TOKEN_FI) { perror("Expected the 'fi' keyword but token has different type"); @@ -437,7 +463,7 @@ struct ast *parse_compound_list(struct lexer_context *ctx) // Skip newlines while (token->type == TOKEN_NEWLINE) { - token = POP_TOKEN(); + POP_TOKEN(); token = PEEK_TOKEN(); } @@ -446,9 +472,9 @@ struct ast *parse_compound_list(struct lexer_context *ctx) if (current_cmd == NULL) return NULL; result_list = list_append(result_list, current_cmd); + token = PEEK_TOKEN(); // Following commands - token = PEEK_TOKEN(); while (token->type == TOKEN_SEMICOLON || token->type == TOKEN_NEWLINE) { POP_TOKEN(); @@ -457,7 +483,7 @@ struct ast *parse_compound_list(struct lexer_context *ctx) // Skip newlines while (token->type == TOKEN_NEWLINE) { - token = POP_TOKEN(); + POP_TOKEN(); token = PEEK_TOKEN(); } @@ -468,22 +494,21 @@ struct ast *parse_compound_list(struct lexer_context *ctx) if (current_cmd == NULL) return NULL; result_list = list_append(result_list, current_cmd); + token = PEEK_TOKEN(); } - - token = PEEK_TOKEN(); } - // Eventual semicolons + // Eventual semicolon if (token->type == TOKEN_SEMICOLON) { - token = POP_TOKEN(); + POP_TOKEN(); token = PEEK_TOKEN(); } // Skip newlines while (token->type == TOKEN_NEWLINE) { - token = POP_TOKEN(); + POP_TOKEN(); token = PEEK_TOKEN(); } @@ -513,18 +538,31 @@ struct ast *parse_else_clause(struct lexer_context *ctx) // Then clause struct ast *then_content = parse_compound_list(ctx); + if (then_content == NULL) + { + ast_free(&condition); + return NULL; + } + token = PEEK_TOKEN(); // 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(ctx); + if (else_content == NULL) + { + ast_free(&then_content); + ast_free(&condition); + return NULL; + } + } + else + { + else_content = ast_create_void(); } - struct ast *result = - ast_create_if(condition, then_content, else_content); - return result; + return ast_create_if(condition, then_content, else_content); } // Eventual else content @@ -533,12 +571,15 @@ struct ast *parse_else_clause(struct lexer_context *ctx) if (token->type == TOKEN_ELSE) { - token = POP_TOKEN(); // eat else + token = POP_TOKEN(); result = parse_compound_list(ctx); + if (result == NULL) + return NULL; } - - if (result == NULL) + else + { result = ast_create_void(); + } return result; }