From c48adb1306d7a2d69c45e841733ebbce0925191f Mon Sep 17 00:00:00 2001 From: omicron Date: Tue, 1 Apr 2025 20:03:28 +0200 Subject: [PATCH] Add basic parser utilities --- src/parser/util.c | 35 +++++++++++++++++++++++++++++++++++ src/parser/util.h | 25 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/parser/util.c create mode 100644 src/parser/util.h diff --git a/src/parser/util.c b/src/parser/util.c new file mode 100644 index 0000000..9b3cd18 --- /dev/null +++ b/src/parser/util.c @@ -0,0 +1,35 @@ +#include "util.h" +#include "../tokenlist.h" + +error_t *err_parse_no_match = + &(error_t){.message = "parsing failed to find the correct token sequence"}; + +parse_result_t parse_error(error_t *err) { + return (parse_result_t){.err = err}; +} + +parse_result_t parse_no_match() { + return parse_error(err_parse_no_match); +} + +parse_result_t parse_success(ast_node_t *ast, tokenlist_entry_t *next) { + next = tokenlist_skip_trivia(next); + return (parse_result_t){.node = ast, .next = next}; +} + +parse_result_t parse_token(tokenlist_entry_t *current, + lexer_token_id_t token_id, node_id_t ast_id, + token_validator_t is_valid) { + if (current->token.id != token_id || + (is_valid && !is_valid(¤t->token))) + return parse_no_match(); + + ast_node_t *node; + error_t *err = ast_node_alloc(&node); + if (err) + return parse_error(err); + node->id = ast_id; + node->token_entry = current; + + return parse_success(node, current->next); +} diff --git a/src/parser/util.h b/src/parser/util.h new file mode 100644 index 0000000..ee5a315 --- /dev/null +++ b/src/parser/util.h @@ -0,0 +1,25 @@ +#ifndef INCLUDE_PARSER_UTIL_H_ +#define INCLUDE_PARSER_UTIL_H_ + +#include "../ast.h" +#include "../error.h" +#include "../tokenlist.h" + +typedef struct parse_result { + error_t *err; + tokenlist_entry_t *next; + ast_node_t *node; +} parse_result_t; + +typedef bool (*token_validator_t)(lexer_token_t *); + +parse_result_t parse_error(error_t *err); +parse_result_t parse_no_match(); +parse_result_t parse_success(ast_node_t *ast, tokenlist_entry_t *next); +parse_result_t parse_token(tokenlist_entry_t *current, + lexer_token_id_t token_id, node_id_t ast_id, + token_validator_t is_valid); + +extern error_t *err_parse_no_match; + +#endif // INCLUDE_PARSER_UTIL_H_