aboutsummaryrefslogtreecommitdiffstats
path: root/libparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparser.c')
-rw-r--r--libparser.c33
1 files changed, 30 insertions, 3 deletions
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 "<invalid>";
}
}
@@ -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 &&