aboutsummaryrefslogtreecommitdiffstats
path: root/print-syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'print-syntax.c')
-rw-r--r--print-syntax.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/print-syntax.c b/print-syntax.c
new file mode 100644
index 0000000..5f2e5e3
--- /dev/null
+++ b/print-syntax.c
@@ -0,0 +1,131 @@
+/* See LICENSE file for copyright and license details. */
+
+/* This file exist to help debugging */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libparser.h"
+
+
+static int
+print_sentence(const union libparser_sentence *sentence, int indent)
+{
+ int len;
+
+ switch (sentence->type) {
+ case LIBPARSER_SENTENCE_TYPE_CONCATENATION:
+ printf("(");
+ indent = print_sentence(sentence->binary.left, indent + 1);
+ printf(", ");
+ indent = print_sentence(sentence->binary.right, indent + 2);
+ printf(")");
+ indent + 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_ALTERNATION:
+ printf("(");
+ print_sentence(sentence->binary.left, indent + 1);
+ printf(" | \n%*.s", indent + 1, "");
+ indent = print_sentence(sentence->binary.right, indent + 1);
+ printf(")");
+ indent + 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_REJECTION:
+ printf("!(");
+ indent = print_sentence(sentence->unary.sentence, indent + 2);
+ printf(")");
+ indent + 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_OPTIONAL:
+ printf("[");
+ indent = print_sentence(sentence->unary.sentence, indent + 1);
+ printf("]");
+ indent + 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_REPEATED:
+ printf("{");
+ indent = print_sentence(sentence->unary.sentence, indent + 1);
+ printf("}");
+ indent += 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_STRING:
+ printf("\"%.*s\"%n", (int)sentence->string.length, sentence->string.string, &len);
+ indent += len;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_CHAR_RANGE:
+ if (isprint(sentence->char_range.low) && isprint(sentence->char_range.high))
+ printf("<\"%c\", \"%c\">%n", sentence->char_range.low, sentence->char_range.high, &len);
+ else if (isprint(sentence->char_range.low))
+ printf("<\"%c\", 0x%02x>%n", sentence->char_range.low, sentence->char_range.high, &len);
+ else if (isprint(sentence->char_range.high))
+ printf("<0x%02x, \"%c\">%n", sentence->char_range.low, sentence->char_range.high, &len);
+ else
+ printf("<0x%02x, 0x%02x>%n", sentence->char_range.low, sentence->char_range.high, &len);
+ indent += len;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_RULE:
+ printf("%s%n", sentence->rule.rule, &len);
+ indent += len;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_EXCEPTION:
+ printf("-");
+ indent += 1;
+ break;
+
+ case LIBPARSER_SENTENCE_TYPE_EOF:
+ printf("%s%n", "(* end of file *)", &len);
+ indent += len;
+ break;
+
+ default:
+ abort();
+ }
+
+ return indent;
+}
+
+
+int
+main(int argc, char *argv[0])
+{
+ size_t i;
+ int indent, first = 1;
+
+ if (argc != 1) {
+ fprintf(stderr, "usage: %s\n", argv[0]);
+ return 1;
+ }
+
+ for (i = 0; libparser_rule_table[i]; i++) {
+ if (libparser_rule_table[i]->name[0] == '@')
+ continue;
+
+ if (!first) {
+ printf("\n");
+ } else {
+ first = 0;
+ }
+
+ printf("%s = %n", libparser_rule_table[i]->name, &indent);
+ print_sentence(libparser_rule_table[i]->sentence, indent);
+ printf(";\n");
+
+ }
+
+ if (fflush(stdout) || ferror(stdout) || fclose(stdout)) {
+ fprintf(stderr, "%s: printf: %s\n", argv[0], strerror(errno));
+ return 1;
+ }
+ return 0;
+}