diff options
| author | Mattias Andrée <m@maandree.se> | 2026-02-26 17:30:59 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-02-26 17:30:59 +0100 |
| commit | 7e216ab61ec8bd8397d55390c0f320fc81793a83 (patch) | |
| tree | 27f12a72f59fddf8f0b14aa6dd075b5454959751 | |
| parent | Right-associate operators (diff) | |
| download | libparser-7e216ab61ec8bd8397d55390c0f320fc81793a83.tar.gz libparser-7e216ab61ec8bd8397d55390c0f320fc81793a83.tar.bz2 libparser-7e216ab61ec8bd8397d55390c0f320fc81793a83.tar.xz | |
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
| -rw-r--r-- | libparser.c | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/libparser.c b/libparser.c index 2a925b7..fae37a5 100644 --- a/libparser.c +++ b/libparser.c @@ -10,6 +10,7 @@ #if PRINT_ACTIONS # include <ctype.h> # include <stdio.h> +# include <unistd.h> #endif @@ -251,6 +252,16 @@ static union libparser_sentence epsilon = {.type = LIBPARSER_SENTENCE_TYPE_EPSIL #if PRINT_ACTIONS +static int with_colour; + + +static const char * +str(const char *s) +{ + return s ? s : "(null)"; /* printing NULL with %s is undefined behaviour */ +} + + static const char * sentence_type_string(enum libparser_sentence_type type) { @@ -281,10 +292,10 @@ print_tree(struct libparser_unit *unit, int indent) for (; unit; unit = unit->next) { fprintf(stderr, "%*.s", indent, ""); fprintf(stderr, "%s: %s%s%s [%zu, %zu) {%p}\n", - unit->rule, sentence_type_string(unit->sentence->type), + str(unit->rule), sentence_type_string(unit->sentence->type), unit->sentence->type == LIBPARSER_SENTENCE_TYPE_RULE ? " " : "", unit->sentence->type == LIBPARSER_SENTENCE_TYPE_RULE - ? unit->sentence->rule.rule : "", + ? str(unit->sentence->rule.rule) : "", unit->start, unit->end, (void *)unit); print_tree(unit->in, indent + 2); } @@ -312,12 +323,12 @@ print_state(struct context *ctx) fprintf(stderr, "Have %zu choices:\n", ctx->choices.count); for (i = 0; i < ctx->choices.count; i++) { - fprintf(stderr, " For unit %zu with %zu followups at %zu: %s: %s, ", + fprintf(stderr, " For unit %zu with %zu follow-ups at %zu: %s: %s, ", ctx->choices.choices[i].unit_index, ctx->choices.choices[i].followups.count, ctx->choices.choices[i].position, sentence_type_string(ctx->choices.choices[i].sentence->type), - ctx->choices.choices[i].rule); + str(ctx->choices.choices[i].rule)); if (ctx->choices.choices[i].choice == EXHAUSTED) fprintf(stderr, "choices EXHAUSTED; "); else @@ -338,10 +349,10 @@ print_state(struct context *ctx) sentence = unit->sentence; fprintf(stderr, " Completion: unit %zu: %s: %s%s%s [%zu, %zu); ", ctx->followups.followups[i].unit_index, - unit->rule, sentence_type_string(sentence->type), + str(unit->rule), sentence_type_string(sentence->type), sentence->type == LIBPARSER_SENTENCE_TYPE_RULE ? " " : "", sentence->type == LIBPARSER_SENTENCE_TYPE_RULE - ? sentence->rule.rule : "", + ? str(sentence->rule.rule) : "", unit->start, unit->end); if (ctx->followups.followups[i].previous_rejection == SIZE_MAX) { fprintf(stderr, "no rejection stored\n"); @@ -352,11 +363,11 @@ print_state(struct context *ctx) } else { sentence = ctx->followups.followups[i].sentence; fprintf(stderr, " (%s, %s%s%s)\n", - ctx->followups.followups[i].rule, + str(ctx->followups.followups[i].rule), sentence_type_string(sentence->type), sentence->type == LIBPARSER_SENTENCE_TYPE_RULE ? " " : "", sentence->type == LIBPARSER_SENTENCE_TYPE_RULE - ? sentence->rule.rule : ""); + ? str(sentence->rule.rule) : ""); } } } @@ -429,7 +440,7 @@ print_sentence(const union libparser_sentence *sentence, int indent) case LIBPARSER_SENTENCE_TYPE_ND_ALTERNATION: fprintf(stderr, "("); print_sentence(sentence->binary.left, indent + 1); - fprintf(stderr, " ?| \n%*.s", indent + 1, ""); + fprintf(stderr, " ?|\n%*.s", indent + 1, ""); indent = print_sentence(sentence->binary.right, indent + 1); fprintf(stderr, ")"); indent += 1; @@ -438,24 +449,20 @@ print_sentence(const union libparser_sentence *sentence, int indent) case LIBPARSER_SENTENCE_TYPE_ALTERNATION: fprintf(stderr, "("); print_sentence(sentence->binary.left, indent + 1); - fprintf(stderr, " | \n%*.s", 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_REJECTION: - fprintf(stderr, "!("); - indent = print_sentence(sentence->unary.sentence, indent + 2); - fprintf(stderr, ")"); - indent += 1; + fprintf(stderr, "!"); + indent = print_sentence(sentence->unary.sentence, indent + 1); break; case LIBPARSER_SENTENCE_TYPE_COMMITTED: - fprintf(stderr, "+("); - indent = print_sentence(sentence->unary.sentence, indent + 2); - fprintf(stderr, ")"); - indent += 1; + fprintf(stderr, "+"); + indent = print_sentence(sentence->unary.sentence, indent + 1); break; case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: @@ -500,7 +507,7 @@ print_sentence(const union libparser_sentence *sentence, int indent) break; case LIBPARSER_SENTENCE_TYPE_RULE: - fprintf(stderr, "%s%n", sentence->rule.rule, &len); + fprintf(stderr, "%s%n", str(sentence->rule.rule), &len); indent += len; break; @@ -534,7 +541,7 @@ print_grammar(const struct libparser_rule *const *rules) int indent; fprintf(stderr, "Rules:\n"); for (i = 0; rules[i]; i++) { - fprintf(stderr, " %s = %n", rules[i]->name, &indent); + fprintf(stderr, " %s = %n", str(rules[i]->name), &indent); print_sentence(rules[i]->sentence, indent); fprintf(stderr, ";\n"); } @@ -559,7 +566,7 @@ embed_rule(struct libparser_unit **where, struct libparser_unit **last) struct libparser_unit *old = *where; #if PRINT_ACTIONS - fprintf(stderr, "Embedding %s: %s [%zu, %zu)\n", old->rule, + fprintf(stderr, "Embedding %s: %s [%zu, %zu)\n", str(old->rule), sentence_type_string(old->sentence->type), old->start, old->end); #endif @@ -724,8 +731,10 @@ push(const char *rule, const union libparser_sentence *sentence, struct context followup->rule = rule; #if PRINT_ACTIONS - fprintf(stderr, "Pushing follow-up sentence: %s: %s\n", - sentence_type_string(sentence->type), rule); + fprintf(stderr, "Pushing follow-up sentence: %s: %s\n ", + sentence_type_string(sentence->type), str(rule)); + print_sentence(sentence, 4); + fprintf(stderr, "\n"); #endif return 0; @@ -770,7 +779,7 @@ incomplete(const char *rule, const union libparser_sentence *sentence, size_t st #if PRINT_ACTIONS fprintf(stderr, "Pushing follow-up completion for unit %zu: %s: %s\n", - ctx->units.count, sentence_type_string(sentence->type), rule); + ctx->units.count, sentence_type_string(sentence->type), str(rule)); #endif unit_slot = new_unit(ctx); @@ -781,7 +790,8 @@ incomplete(const char *rule, const union libparser_sentence *sentence, size_t st *unit_slot = unit; #if PRINT_ACTIONS fprintf(stderr, "Writing unit to slot: %s: %s, spanning [%zu, %zu)\n", - unit->rule, sentence_type_string(unit->sentence->type), unit->start, unit->end); + str(unit->rule), sentence_type_string(unit->sentence->type), + unit->start, unit->end); #endif return 0; @@ -845,14 +855,14 @@ braching(const char *rule, const union libparser_sentence *sentence, size_t star #if PRINT_ACTIONS fprintf(stderr, "Adding branching point at %zu for unit %zu: %s: %s, at %zu in text\n", ctx->choices.next, ctx->units.count, - sentence_type_string(sentence->type), rule, start); + sentence_type_string(sentence->type), str(rule), start); } else { fprintf(stderr, "Revisiting branching point %zu at %zu in text for unit %zu: " "%s: %s, at %zu in text; choice value: %zu; ", ctx->choices.next, start, ctx->choices.choices[ctx->choices.next].unit_index, sentence_type_string(ctx->choices.choices[ctx->choices.next].sentence->type), - ctx->choices.choices[ctx->choices.next].rule, + str(ctx->choices.choices[ctx->choices.next].rule), ctx->choices.choices[ctx->choices.next].position, ctx->choices.choices[ctx->choices.next].choice); if (ctx->choices.choices[ctx->choices.next].previous_rejection == SIZE_MAX) { @@ -890,8 +900,10 @@ add_unit(const char *rule, const union libparser_sentence *sentence, struct cont size_t i, choice; #if PRINT_ACTIONS - fprintf(stderr, "Visiting %s: %s, at %zu in text\n", - sentence_type_string(sentence->type), rule, start); + fprintf(stderr, "Visiting %s: %s, at %zu in text\n ", + sentence_type_string(sentence->type), str(rule), start); + print_sentence(sentence, 4); + fprintf(stderr, "\n"); #endif switch (sentence->type) { @@ -1027,7 +1039,8 @@ add_unit(const char *rule, const union libparser_sentence *sentence, struct cont *unit_slot = unit; #if PRINT_ACTIONS fprintf(stderr, "Writing atomic unit to slot: %s: %s, spanning [%zu, %zu)\n", - sentence_type_string(unit->sentence->type), unit->rule, unit->start, unit->end); + sentence_type_string(unit->sentence->type), str(unit->rule), + unit->start, unit->end); #endif return 1; @@ -1084,7 +1097,7 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) #if PRINT_ACTIONS fprintf(stderr, "Unary unit: %s: %s [%zu, %zu)\n", sentence_type_string(unit->sentence->type), - unit->rule, unit->start, unit->end); + str(unit->rule), unit->start, unit->end); #endif unit->in = make_tree(ctx, unit_i, last); break; @@ -1093,7 +1106,7 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) #if PRINT_ACTIONS fprintf(stderr, "Unary lookahead unit: %s: %s [%zu, %zu)\n", sentence_type_string(unit->sentence->type), - unit->rule, unit->start, unit->end); + str(unit->rule), unit->start, unit->end); #endif unit->in = make_tree(ctx, unit_i, last); start = unit->start; @@ -1112,7 +1125,7 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) #if PRINT_ACTIONS fprintf(stderr, "Binary unit: %s: %s [%zu, %zu)\n", sentence_type_string(unit->sentence->type), - unit->rule, unit->start, unit->end); + str(unit->rule), unit->start, unit->end); #endif unit->in = make_tree(ctx, unit_i, &middle); if (IS_ANONYMOUS(unit->in->rule)) { @@ -1141,7 +1154,7 @@ make_tree(struct context *ctx, size_t *unit_i, struct libparser_unit **last) #if PRINT_ACTIONS fprintf(stderr, "Atomic unit: %s: %s [%zu, %zu)\n", sentence_type_string(unit->sentence->type), - unit->rule, unit->start, unit->end); + str(unit->rule), unit->start, unit->end); #endif goto out; default: @@ -1249,6 +1262,8 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat sentence = rules[i]->sentence; #if PRINT_ACTIONS + with_colour = isatty(STDERR_FILENO); + print_grammar(rules); fprintf(stderr, "Input text: \""); print_text(ctx.data, ctx.length); @@ -1259,7 +1274,11 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat /* TODO break REPEATED on empty match */ followup: #if PRINT_ACTIONS + if (with_colour) + fprintf(stderr, "\033[1m"); print_state(&ctx); + if (with_colour) + fprintf(stderr, "\033[m"); #endif match = add_unit(rule, sentence, &ctx); if (match < 0) { @@ -1276,7 +1295,7 @@ followup: #if PRINT_ACTIONS fprintf(stderr, "Popping completion of sentence: %s: %s, " "for unit %zu, at %zu, consuming %zu subunits\n", - sentence_type_string(sentence->type), unit->rule, + sentence_type_string(sentence->type), str(unit->rule), ctx.followups.followups[i].unit_index, ctx.position, ctx.units.count - ctx.followups.followups[i].unit_index - 1U); #endif @@ -1349,8 +1368,10 @@ followup: rule = ctx.followups.followups[i].rule; sentence = ctx.followups.followups[i].sentence; #if PRINT_ACTIONS - fprintf(stderr, "Popping follow-up sentence: %s: %s\n", - sentence_type_string(sentence->type), rule); + fprintf(stderr, "Popping follow-up sentence: %s: %s\n ", + sentence_type_string(sentence->type), str(rule)); + print_sentence(sentence, 4); + fprintf(stderr, "\n"); #endif goto followup; } else mismatch: if (ctx.choices.count && !choice_contains_rejection(&ctx)) { @@ -1379,7 +1400,7 @@ followup: #if PRINT_ACTIONS fprintf(stderr, "Mismatch: retrying from branching point %zu (%s, %s), " "and unit %zu, from %zu, now with choice %zu\n", - i, sentence_type_string(sentence->type), rule, ctx.position, + i, sentence_type_string(sentence->type), str(rule), ctx.position, ctx.units.count, ctx.choices.choices[i].choice); #endif goto followup; |
