From e79945a3983d5528fb37a6482eae2cef31deadd1 Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Thu, 16 Dec 2021 22:07:18 +0100 Subject: [PATCH] Continue work on parser - Simplify return types: Many functions that returned `enum parse_fragment_result` only ever returned PF_OK or PF_ERROR. Changing these functions to return bool simplifies things a lot. This also helped in identifying some places where I didn't handle all parse_fragment_result values properly. - More cleaning up - Allow linebreaks inside parenthesis --- src/parser.c | 204 ++++++++++++++++++++++++--------------------------- 1 file changed, 95 insertions(+), 109 deletions(-) diff --git a/src/parser.c b/src/parser.c index db08a03..5659b4f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -362,14 +362,6 @@ err_unexpected_token(enum apfl_token_type token_type, struct apfl_position pos) #define ERR_UNEXPECTED_TOKEN(t) (err_unexpected_token((t).type, (t).position)) -// Must only be called after an PF_CANT_HANDLE! -static enum parse_fragment_result -unexpected_cant_handle(apfl_parser_ptr p) -{ - p->error = ERR_UNEXPECTED_TOKEN(p->token); - return PF_ERROR; -} - static enum parse_fragment_result parse_fragment_into_list(apfl_parser_ptr p, struct fragment_list *list, bool need, enum parse_fragment_flags flags) { @@ -405,62 +397,67 @@ static bool fragments_to_call( struct apfl_expr * ); -static enum parse_fragment_result -parse_parens_head(apfl_parser_ptr p, struct fragment_list *children) -{ - return parse_fragment_into_list(p, children, true, FFLAG_NO_EXPAND); // \mystuff\TODO:more flags? -} - -static enum parse_fragment_result -parse_parens_tail(apfl_parser_ptr p, struct fragment_list *children, struct apfl_position position) -{ - enum parse_fragment_result result; - for (;;) { - result = parse_fragment_into_list(p, children, true, 0); // \mystuff\TODO:more flags? - if (result != PF_OK) { - break; - } - } - - switch (result) { +static bool +parse_parens_head( + apfl_parser_ptr p, + struct fragment_list *children, + struct apfl_position position +) { + switch (parse_fragment_into_list(p, children, true, FFLAG_NO_EXPAND)) { case PF_OK: - assert(false); // already handled + return true; case PF_EOF: p->error = err_unexpected_eof_after(APFL_TOK_LPAREN, position); - return PF_ERROR; + return false; case PF_CANT_HANDLE: - break; + read_token_after_cant_handle(p); + p->error = ERR_UNEXPECTED_TOKEN(p->token); + return false; case PF_ERROR: - return PF_ERROR; + return false; } - assert(result == PF_CANT_HANDLE); - read_token_after_cant_handle(p); + assert(false); +} - if (p->token.type == APFL_TOK_RPAREN) { - return PF_OK; - // \mystuff\TODO:finalize list somehow? - } else { - p->error = ERR_UNEXPECTED_TOKEN(p->token); - return PF_ERROR; +static bool +parse_parens_tail(apfl_parser_ptr p, struct fragment_list *children, struct apfl_position position) +{ + for (;;) { + switch (parse_fragment_into_list(p, children, true, 0)) { + case PF_OK: + break; + case PF_EOF: + p->error = err_unexpected_eof_after(APFL_TOK_LPAREN, position); + return false; + case PF_CANT_HANDLE: + read_token_after_cant_handle(p); + if (p->token.type == APFL_TOK_RPAREN) { + return true; + } else if (p->token.type == APFL_TOK_LINEBREAK) { + // Ignore linebreaks inside (...) + break; + } else { + p->error = ERR_UNEXPECTED_TOKEN(p->token); + return false; + } + case PF_ERROR: + return false; + } } } -static enum parse_fragment_result +static bool parse_parens(apfl_parser_ptr p, struct fragment *out, struct apfl_position position) { struct fragment_list children; apfl_resizable_init(APFL_RESIZABLE_ARGS(children, children)); - enum parse_fragment_result result; - - result = parse_parens_head(p, &children); - if (result != PF_OK) { + if (!parse_parens_head(p, &children, position)) { goto error; } - result = parse_parens_tail(p, &children, position); - if (result != PF_OK) { + if (!parse_parens_tail(p, &children, position)) { goto error; } @@ -471,15 +468,15 @@ parse_parens(apfl_parser_ptr p, struct fragment *out, struct apfl_position posit goto error; } - return PF_OK; + return true; error: - // \mystuff\TODO:cleanup + fragment_list_deinit(&children); - return result; + return false; } -static enum parse_fragment_result +static bool skip_inner_bracket_separators(apfl_parser_ptr p) { for (;;) { @@ -494,25 +491,23 @@ skip_inner_bracket_separators(apfl_parser_ptr p) } unread_token(p); - return PF_OK; + return true; case APFL_PARSE_EOF: - return PF_OK; + return true; case APFL_PARSE_ERROR: - return PF_ERROR; + return false; } } } -static enum parse_fragment_result +static bool parse_empty_dict(apfl_parser_ptr p, struct fragment *out, struct apfl_position position) { // We already got `[ ->`, we now read another (non separator) token and return success, if it's an `]`. // Else it's a syntax error - enum parse_fragment_result result; - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { - return result; + if (!skip_inner_bracket_separators(p)) { + return false; } switch (read_token(p, true)) { @@ -520,15 +515,14 @@ parse_empty_dict(apfl_parser_ptr p, struct fragment *out, struct apfl_position p break; case APFL_PARSE_EOF: p->error = apfl_error_simple(APFL_ERR_UNEXPECTED_EOF); - return PF_ERROR; - + return false; case APFL_PARSE_ERROR: - return PF_ERROR; + return false; } if (p->token.type != APFL_TOK_RBRACKET) { p->error = ERR_UNEXPECTED_TOKEN(p->token); - return PF_ERROR; + return false; } out->type = FRAG_EXPR; @@ -539,11 +533,11 @@ parse_empty_dict(apfl_parser_ptr p, struct fragment *out, struct apfl_position p .position = position, }; out->position = position; - return PF_OK; + return true; } // Must only be called after PF_CANT_HANDLE -static enum parse_fragment_result +static bool parse_empty_list_or_dict(apfl_parser_ptr p, struct fragment *out, struct apfl_position position) { read_token_after_cant_handle(p); @@ -556,12 +550,12 @@ parse_empty_list_or_dict(apfl_parser_ptr p, struct fragment *out, struct apfl_po .len = 0, }; out->position = position; - return PF_OK; + return true; case APFL_TOK_MAPSTO: return parse_empty_dict(p, out, position); default: p->error = ERR_UNEXPECTED_TOKEN(p->token); - return PF_ERROR; + return false; } } @@ -656,7 +650,7 @@ fragment_to_expr_allocated(apfl_parser_ptr p, struct fragment fragment) return out; } -static enum parse_fragment_result +static bool parse_dict( apfl_parser_ptr p, struct fragment *out, @@ -669,8 +663,6 @@ parse_dict( bool cleanup_key = true; bool cleanup_value = false; - enum parse_fragment_result result; - struct apfl_expr_dict dict = { .items = NULL, .len = 0, @@ -680,18 +672,16 @@ parse_dict( goto after_mapsto; for (;;) { - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { + if (!skip_inner_bracket_separators(p)) { goto error; } - switch ((result = parse_fragment(p, &key, true, FFLAG_NO_EXPAND))) { + switch (parse_fragment(p, &key, true, FFLAG_NO_EXPAND)) { case PF_OK: cleanup_key = true; break; case PF_EOF: p->error = err_unexpected_eof_after(APFL_TOK_LBRACKET, start); - result = PF_ERROR; goto error; case PF_CANT_HANDLE: goto maybe_end; @@ -699,8 +689,7 @@ parse_dict( goto error; } - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { + if (!skip_inner_bracket_separators(p)) { goto error; } @@ -709,10 +698,8 @@ parse_dict( break; case APFL_PARSE_EOF: p->error = err_unexpected_eof_after(APFL_TOK_LBRACKET, start); - result = PF_ERROR; goto error; case APFL_PARSE_ERROR: - result = PF_ERROR; goto error; } @@ -724,22 +711,21 @@ parse_dict( mapsto_pos = p->token.position; after_mapsto: - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { + if (!skip_inner_bracket_separators(p)) { goto error; } struct fragment value; - switch ((result = parse_fragment(p, &value, true, FFLAG_NO_EXPAND))) { + switch (parse_fragment(p, &value, true, FFLAG_NO_EXPAND)) { case PF_OK: cleanup_value = true; break; case PF_EOF: p->error = err_unexpected_eof_after(APFL_TOK_MAPSTO, mapsto_pos); - result = PF_ERROR; goto error; case PF_CANT_HANDLE: - result = unexpected_cant_handle(p); + read_token_after_cant_handle(p); + p->error = ERR_UNEXPECTED_TOKEN(p->token); goto error; case PF_ERROR: goto error; @@ -747,10 +733,9 @@ after_mapsto: struct apfl_expr_dict_pair pair; if ( - (pair.k = fragment_to_expr_allocated(p, key)) == NULL - || (pair.v = fragment_to_expr_allocated(p, value)) == NULL + (pair.k = fragment_to_expr_allocated(p, fragment_move(&key))) == NULL + || (pair.v = fragment_to_expr_allocated(p, fragment_move(&value))) == NULL ) { - result = PF_ERROR; goto error; } @@ -769,7 +754,7 @@ after_mapsto: )) { // \mystuff\TODO:destroy pair! p->error = apfl_error_simple(APFL_ERR_MALLOC_FAILED); - return PF_ERROR; + return false; } } @@ -789,7 +774,7 @@ maybe_end: .position = start, }; out->position = start; - return PF_OK; + return true; error: if (cleanup_key) { @@ -799,10 +784,10 @@ error: fragment_deinit(&value); } free(dict.items); // \mystuff\TODO:also destroy all items! - return result; + return false; } -static enum parse_fragment_result +static bool parse_list( apfl_parser_ptr p, struct fragment *out, @@ -815,7 +800,7 @@ parse_list( if (!append_fragment(&list, first)) { fragment_deinit(&first); p->error = apfl_error_simple(APFL_ERR_MALLOC_FAILED); - return PF_ERROR; + return false; } for (;;) { @@ -843,20 +828,18 @@ maybe_end: out->list = list; out->position = start; - return PF_OK; + return true; error: // \mystuff\TODO:clean up list - return PF_ERROR; + return false; } -static enum parse_fragment_result +static bool parse_brackets(apfl_parser_ptr p, struct fragment *out, struct apfl_position start) { - enum parse_fragment_result result; - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { - return result; + if (!skip_inner_bracket_separators(p)) { + return false; } struct fragment first; @@ -867,13 +850,12 @@ parse_brackets(apfl_parser_ptr p, struct fragment *out, struct apfl_position sta return parse_empty_list_or_dict(p, out, start); case PF_EOF: p->error = err_unexpected_eof_after(APFL_TOK_LBRACKET, start); - return PF_ERROR; + return false; case PF_ERROR: - return PF_ERROR; + return false; } - result = skip_inner_bracket_separators(p); - if (result != PF_OK) { + if (!skip_inner_bracket_separators(p)) { goto error; } @@ -882,10 +864,8 @@ parse_brackets(apfl_parser_ptr p, struct fragment *out, struct apfl_position sta break; case APFL_PARSE_EOF: p->error = err_unexpected_eof_after(APFL_TOK_LBRACKET, start); - result = PF_ERROR; goto error; case APFL_PARSE_ERROR: - result = PF_ERROR; goto error; } @@ -899,7 +879,7 @@ parse_brackets(apfl_parser_ptr p, struct fragment *out, struct apfl_position sta error: fragment_deinit(&first); - return result; + return false; } static bool @@ -1567,7 +1547,7 @@ error: // \mystuff\TODO:also on other non ok results??? return PF_ERROR; } -static enum parse_fragment_result +static bool parse_braces( apfl_parser_ptr p, struct fragment *out, @@ -1668,7 +1648,7 @@ parse_braces( DEINIT_LIST(fragments.children, fragments.len, fragment_deinit); - return PF_OK; + return true; case APFL_TOK_MAPSTO: if (body.len > 0 && !has_params) { p->error = (struct apfl_error) { @@ -1717,7 +1697,7 @@ parse_braces( error: // \mystuff\TODO:cleanup - return PF_ERROR; + return false; } static enum parse_fragment_result @@ -1739,13 +1719,19 @@ parse_fragment(apfl_parser_ptr p, struct fragment *fragment, bool need, enum par switch (p->token.type) { case APFL_TOK_LPAREN: - result = parse_parens(p, fragment, p->token.position); + if (!parse_parens(p, fragment, p->token.position)) { + goto error; + } break; case APFL_TOK_LBRACKET: - result = parse_brackets(p, fragment, p->token.position); + if (!parse_brackets(p, fragment, p->token.position)) { + goto error; + } break; case APFL_TOK_LBRACE: - result = parse_braces(p, fragment, p->token.position); + if (!parse_braces(p, fragment, p->token.position)) { + goto error; + } break; case APFL_TOK_EXPAND: if (flags & FFLAG_NO_EXPAND) {