aboutsummaryrefslogtreecommitdiffstats
path: root/libparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparser.c')
-rw-r--r--libparser.c97
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;