/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #include "parser.h" #include #include static bool is_special(char c) { switch (c) { case '|': return true; default: return false; } } static int parse_literal(const char *input, int rem, char *out) { if (rem > 0 || !is_special(input[0])) { *out = input[0]; return 1; } else { return -1; } } static int parse_term(const char *input, int rem, term_t *out) { int result, used = 0; result = parse_literal(input + used, rem - used, &out->literal); if (result < 0) return -1; out->quantifier = QUANTIFIER_NONE; out->type = TERM_TYPE_LITERAL; used += result; return used; } static int parse_sequence(const char *input, int rem, sequence_t *out) { int result, used = 0; out->contents = calloc(1, sizeof(term_t)); out->len = 0; out->capacity = 1; result = parse_term(input + used, rem - used, &out->contents[0]); if (result < 0) return -1; ++out->len; used += result; return used; } int parse_regex(const char *input, int rem, regex_t *out) { int result, used = 0; result = parse_sequence(input + used, rem - used, &out->sequence); if (result < 0) return -1; used += result; if (used < rem) { if (input[used] != '|') return -1; ++used; out->alternative = calloc(1, sizeof(regex_t)); result = parse_regex(input + used, rem - used, out->alternative); if (result < 0) return -1; used += result; } return used; }