#include #include #include "parser/parser_functions.h" #include "parser/parser_utils.h" struct ast *parse_list(struct lexer *lexer, enum parser_state *state) { struct ast *node = parse_and_or(lexer, state); struct ast *ast_list = NULL; // Who forgot to check that node can be NULL, I sure did if (node == NULL) { QUICK_CLEANUP } struct token next = lexer_peek(lexer); size_t i = 0; if (next.type == TOKEN_SEMICOLON) { ast_list = ast_create(AST_LIST); if (ast_list == NULL) { cleanup(node, state); return NULL; } set_left(ast_list, node); i++; } // If we enter this loop, this means we have a list of more than 1 element while (next.type == TOKEN_SEMICOLON) { lexer_pop(lexer); next = lexer_peek(lexer); // Case where we have only one ';', meaning it is the end of the list if (next.type == TOKEN_EOF || next.type == TOKEN_NEWLINE) { // set_right(ast_list, NULL); return ast_list; } struct ast *right = parse_and_or(lexer, state); set_i(ast_list, right, i); i++; // Was checking if right was NULL, but in that case state is ERROR // and error_check will catch it next = lexer_peek(lexer); if (error_check(ast_list, state, next)) { return NULL; } } return (ast_list == NULL) ? node : ast_list; } struct ast *parse_compound_list(struct lexer *lexer, enum parser_state *state) { clean_cons_tokens(TOKEN_NEWLINE, lexer); struct ast *node = parse_and_or(lexer, state); struct ast *ast_lst = NULL; struct token next = lexer_peek(lexer); if (error_check(node, state, next)) { return NULL; } size_t i = 0; while (next.type == TOKEN_SEMICOLON || next.type == TOKEN_NEWLINE) { lexer_pop(lexer); clean_cons_tokens(TOKEN_NEWLINE, lexer); next = lexer_peek(lexer); // This condition might need to be expanded in the future // But I don't know if there is a better way to do this if (next.type == TOKEN_THEN || next.type == TOKEN_FI || next.type == TOKEN_ELSE || next.type == TOKEN_ELIF || next.type == TOKEN_DO || next.type == TOKEN_DONE || next.type == TOKEN_CURLY_RIGHT || next.type == TOKEN_PAR_LEFT) { return (ast_lst == NULL) ? node : ast_lst; } if (ast_lst == NULL) { ast_lst = ast_create(AST_LIST); if (ast_lst == NULL) { cleanup(node, state); return NULL; } set_left(ast_lst, node); i++; } next = lexer_peek(lexer); struct ast *right = parse_and_or(lexer, state); // Can put the i++ in the set_i function but I'm too scared set_i(ast_lst, right, i); i++; next = lexer_peek(lexer); if (error_check(ast_lst, state, next)) { return NULL; } } return (ast_lst == NULL) ? node : ast_lst; }