From 208594ca9f95a87f60ff052490a4d5824dc23801 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 5 Jan 2026 14:35:26 +0100 Subject: Make deterministic the default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libparser.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'libparser.c') diff --git a/libparser.c b/libparser.c index 7ef7267..5ecb7ee 100644 --- a/libparser.c +++ b/libparser.c @@ -267,6 +267,9 @@ sentence_type_string(enum libparser_sentence_type type) case LIBPARSER_SENTENCE_TYPE_EOF: return "EOF"; case LIBPARSER_SENTENCE_TYPE_EPSILON: return "EPSILON"; case LIBPARSER_SENTENCE_TYPE_COMMITTED: return "COMMITTED"; + case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: return "ND_OPTIONAL"; + case LIBPARSER_SENTENCE_TYPE_ND_REPEATED: return "ND_REPEATED"; + case LIBPARSER_SENTENCE_TYPE_ND_ALTERNATION: return "ND_ALTERNATION"; default: return ""; } } @@ -375,6 +378,15 @@ print_sentence(const union libparser_sentence *sentence, int indent) indent += 1; break; + case LIBPARSER_SENTENCE_TYPE_ND_ALTERNATION: + fprintf(stderr, "("); + print_sentence(sentence->binary.left, indent + 1); + fprintf(stderr, " ?| \n%*.s", indent + 1, ""); + indent = print_sentence(sentence->binary.right, indent + 1); + fprintf(stderr, ")"); + indent += 1; + break; + case LIBPARSER_SENTENCE_TYPE_ALTERNATION: fprintf(stderr, "("); print_sentence(sentence->binary.left, indent + 1); @@ -398,6 +410,9 @@ print_sentence(const union libparser_sentence *sentence, int indent) indent += 1; break; + case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: + fprintf(stderr, "?"); + /* fall through */ case LIBPARSER_SENTENCE_TYPE_OPTIONAL: fprintf(stderr, "["); indent = print_sentence(sentence->unary.sentence, indent + 1); @@ -405,6 +420,9 @@ print_sentence(const union libparser_sentence *sentence, int indent) indent += 1; break; + case LIBPARSER_SENTENCE_TYPE_ND_REPEATED: + fprintf(stderr, "?"); + /* fall through */ case LIBPARSER_SENTENCE_TYPE_REPEATED: fprintf(stderr, "{"); indent = print_sentence(sentence->unary.sentence, indent + 1); @@ -827,6 +845,7 @@ add_unit(const char *rule, const union libparser_sentence *sentence, struct cont #endif switch (sentence->type) { + case LIBPARSER_SENTENCE_TYPE_ND_ALTERNATION: case LIBPARSER_SENTENCE_TYPE_ALTERNATION: if (braching(rule, sentence, start, ctx, &choice)) return -1; @@ -837,6 +856,7 @@ add_unit(const char *rule, const union libparser_sentence *sentence, struct cont return -1; return 1; + case LIBPARSER_SENTENCE_TYPE_ND_REPEATED: case LIBPARSER_SENTENCE_TYPE_REPEATED: if (braching(rule, sentence, start, ctx, &choice)) return -1; @@ -860,6 +880,7 @@ add_unit(const char *rule, const union libparser_sentence *sentence, struct cont } return 1; + case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: case LIBPARSER_SENTENCE_TYPE_OPTIONAL: if (braching(rule, sentence, start, ctx, &choice)) return -1; @@ -1005,7 +1026,9 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) switch (unit->sentence->type) { case LIBPARSER_SENTENCE_TYPE_RULE: + case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: case LIBPARSER_SENTENCE_TYPE_OPTIONAL: + case LIBPARSER_SENTENCE_TYPE_ND_ALTERNATION: case LIBPARSER_SENTENCE_TYPE_ALTERNATION: case LIBPARSER_SENTENCE_TYPE_COMMITTED: #if PRINT_ACTIONS @@ -1033,6 +1056,7 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) *last = unit; goto out; + case LIBPARSER_SENTENCE_TYPE_ND_REPEATED: case LIBPARSER_SENTENCE_TYPE_REPEATED: case LIBPARSER_SENTENCE_TYPE_CONCATENATION: #if PRINT_ACTIONS @@ -1179,7 +1203,6 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat #endif /* TODO guard against left-side recursion */ - /* TODO make branching opt-in ("?") */ /* TODO break REPEATED on empty match */ followup: #if PRINT_ACTIONS @@ -1249,9 +1272,13 @@ followup: } if (!match) goto mismatch; - if (sentence->type == LIBPARSER_SENTENCE_TYPE_COMMITTED) { + if (sentence->type == LIBPARSER_SENTENCE_TYPE_COMMITTED || + sentence->type == LIBPARSER_SENTENCE_TYPE_ALTERNATION || + sentence->type == LIBPARSER_SENTENCE_TYPE_OPTIONAL || + sentence->type == LIBPARSER_SENTENCE_TYPE_REPEATED) { #if PRINT_ACTIONS - fprintf(stderr, "Removing interior choices for matched COMMITTED\n"); + fprintf(stderr, "Removing interior choices for matched %s\n", + sentence_type_string(sentence->type)); #endif j = ctx.followups.followups[i].unit_index; while (ctx.choices.count && -- cgit v1.2.3-70-g09d2