#include "parser/parser_functions.h" #include "parser/parser_utils.h" struct ast *parse_and_or(struct lexer *lexer, enum parser_state *state) { struct ast *node = parse_pipeline(lexer, state); struct token next = lexer_peek(lexer); if (error_check(node, state, next)) { QUICK_CLEANUP } while (next.type == TOKEN_AND || next.type == TOKEN_OR) { struct ast *logical = ast_create(AST_LOGICAL); if (logical == NULL) { cleanup(node, state); return NULL; } ((struct ast_logical *)logical)->type = next.type; lexer_pop(lexer); next = lexer_peek(lexer); while (next.type == TOKEN_NEWLINE) { lexer_pop(lexer); next = lexer_peek(lexer); } set_left(logical, node); struct ast *right = parse_pipeline(lexer, state); // So it's ready for next iteration + usable in error_check() next = lexer_peek(lexer); // If there IS an error, then it MUST have returned NULL // So no need to free 'right' if (error_check(logical, state, next)) { return NULL; } set_right(logical, right); node = logical; } return node; } struct ast *parse_pipeline(struct lexer *lexer, enum parser_state *state) { struct ast *negation = NULL; struct token next = lexer_peek(lexer); if (next.type == TOKEN_NEG) { negation = ast_create(AST_LOGICAL); if (negation == NULL) { QUICK_CLEANUP } union ast_caster cast; cast.ast = negation; cast.ast_lo->type = next.type; lexer_pop(lexer); next = lexer_peek(lexer); } struct ast *node = parse_command(lexer, state); next = lexer_peek(lexer); if (negation != NULL) { set_left(negation, node); node = negation; } // If there is an error here (aka node failed), just negation is alloc'ed if (error_check(negation, state, next)) { return NULL; } while (next.type == TOKEN_PIPE) { lexer_pop(lexer); struct ast *pipe = ast_create(AST_PIPELINE); if (pipe == NULL) { cleanup(node, state); return NULL; } set_left(pipe, node); while (next.type == TOKEN_NEWLINE) { lexer_pop(lexer); next = lexer_peek(lexer); } set_right(pipe, parse_command(lexer, state)); next = lexer_peek(lexer); if (error_check(pipe, state, next)) { return NULL; } node = pipe; } return node; }