diff --git a/src/parser/parsing_utils.c b/src/parser/parsing_utils.c index f1408c5..487602d 100644 --- a/src/parser/parsing_utils.c +++ b/src/parser/parsing_utils.c @@ -59,17 +59,29 @@ struct ast *parse_list(void) struct token *token = PEEK_TOKEN(); - while (!is_end_of_list(token)) + // and_or + current_node = parse_and_or(); + if (current_node == NULL) + return NULL; + list_append(result_list, current_node); + + // Following and_or commands + token = PEEK_TOKEN(); + while (token->type == TOKEN_SEMICOLON) { - if (token->type == TOKEN_SEMICOLON) - { - result_list = list_append(result_list, current_node); - } - else + token = POP_TOKEN(); + if (!isterminator(token)) // Follow(list) { current_node = parse_and_or(); + if (current_node == NULL) + { + //TODO free list + // There must be a function for that + return NULL; + } + list_append(result_list, current_node); + token = PEEK_TOKEN(); } - token = PEEK_TOKEN(); } return ast_create_list(result_list); @@ -107,11 +119,17 @@ struct ast *parse_simple_command(void) { struct list *command_elements = NULL; struct token *token = PEEK_TOKEN(); + if (token->type != TOKEN_WORD) + { + puts("Expected a command but got a different token type"); + return NULL; + } while (token->type == TOKEN_WORD) { token = POP_TOKEN(); - command_elements = list_append(command_elements, token->data); + char* word = strdup(token->data); + command_elements = list_append(command_elements, word); token = PEEK_TOKEN(); } @@ -122,25 +140,13 @@ struct ast *parse_simple_command(void) // TODO check compliance with the grammar 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; - } + return parse_if_rule(); } -// TODO check compliance with the grammar struct ast *parse_if_rule(void) { - // If condition + // If keyword struct token *token = POP_TOKEN(); - if (token->type != TOKEN_IF) { puts("Internal error: expected a if rule but token has different " @@ -148,27 +154,43 @@ struct ast *parse_if_rule(void) return NULL; } + // Condition content struct ast *condition_content = parse_compound_list(); - // Then content + // Then keyword token = POP_TOKEN(); - if (token->type != TOKEN_THEN) { + ast_free(&condition_content); puts("Expected the 'then' keyword but token has different type"); return NULL; } + // Then content struct ast *then_content = parse_compound_list(); + if (then_content == NULL) + { + ast_free(&condition_content); + ast_free(&then_content); + return NULL; + } // Eventual else/elif clause(s) struct ast *else_content = parse_else_clause(); + if (else_content == NULL) + { + ast_free(&condition_content); + ast_free(&then_content); + return NULL; + } token = POP_TOKEN(); if (token->type != TOKEN_FI) { + ast_free(&condition_content); + ast_free(&then_content); + ast_free(&else_content); puts("Expected the 'fi' keyword but token has different type"); - // TODO free previous asts return NULL; } @@ -176,44 +198,60 @@ struct ast *parse_if_rule(void) ast_create_if(condition_content, then_content, else_content); if (result == NULL) { + ast_free(&condition_content); + ast_free(&then_content); + ast_free(&else_content); puts("Internal error: could not create a new AST (AST_IF)"); - // TODO free previous asts return NULL; } return result; } -// TODO comply with header's grammar struct ast *parse_compound_list(void) { struct list *result_list = NULL; // ast* list - struct list *command_elements = NULL; // token* list + struct ast *current_cmd = NULL; struct token *token = PEEK_TOKEN(); - while (token->type != TOKEN_THEN || token->type != TOKEN_ELIF - || token->type != TOKEN_ELSE) - { - // Parse simple command - if (token->type == TOKEN_SEMICOLON || token->type == TOKEN_NEWLINE) - { - // Stage (-> next command) - struct ast *command = ast_create_command(command_elements); - result_list = list_append(result_list, command); - command_elements = NULL; - } - - if (token->type == TOKEN_EOF) - { - puts("Syntax error: Unexpected end of stream"); // TODO pas très - // bien dit - return NULL; - } - - command_elements = list_append(command_elements, token->data); + // Skip newlines + while (token == TOKEN_NEWLINE) token = POP_TOKEN(); + + // and_or + current_cmd = parse_and_or(); + if (current_cmd == NULL) + return NULL; + list_append(result_list, current_cmd); + + // Following commands + token = PEEK_TOKEN(); + while (token->type == TOKEN_SEMICOLON || token->type TOKEN_NEWLINE) + { + POP_TOKEN(); + + // Skip newlines + while (token == TOKEN_NEWLINE) + token = POP_TOKEN(); + + // and_or + current_cmd = parse_and_or(); + if (current_cmd == NULL) + return NULL; + list_append(result_list, current_cmd); + + token = PEEK_TOKEN(); } + // Eventual semicolons + if (token->type == TOKEN_SEMICOLON) + token = POP_TOKEN(); + + // Skip newlines + while (token == TOKEN_NEWLINE) + token = POP_TOKEN(); + + struct ast *result = ast_create_list(result_list); return result; } @@ -222,7 +260,6 @@ struct ast *parse_else_clause(void) { struct token *token = PEEK_TOKEN(); - // TODO handle ELIF // Eventual elif content while (token->type == TOKEN_ELIF) {