/* See LICENSE file for copyright and license details. */ /* This file exist to help debugging */ #include #include #include #include #include #include "libparser.h" static int print_sentence(const union libparser_sentence *sentence, int indent) { size_t off, n; 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_ND_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_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_COMMITTED: printf("+("); indent = print_sentence(sentence->unary.sentence, indent + 2); printf(")"); indent += 1; break; case LIBPARSER_SENTENCE_TYPE_ND_OPTIONAL: printf("?"); /* fall through */ case LIBPARSER_SENTENCE_TYPE_OPTIONAL: printf("["); indent = print_sentence(sentence->unary.sentence, indent + 1); printf("]"); indent += 1; break; case LIBPARSER_SENTENCE_TYPE_ND_REPEATED: printf("?"); /* fall through */ case LIBPARSER_SENTENCE_TYPE_REPEATED: printf("{"); indent = print_sentence(sentence->unary.sentence, indent + 1); printf("}"); indent += 1; break; case LIBPARSER_SENTENCE_TYPE_STRING: printf("\"%n", &len); indent += len; off = 0; n = 0; while (off + n < sentence->string.length) { if (sentence->string.string[off + n] < ' ' || sentence->string.string[off + n] >= 0x7F || sentence->string.string[off + n] == '"' || sentence->string.string[off + n] == '\\') { printf("%.*s%n", (int)n, &sentence->string.string[off], &len); indent += len; off += n; n = 0; switch (sentence->string.string[off]) { case '\\': printf("\\\\%n", &len); break; case '\"': printf("\\\"%n", &len); break; case '\a': printf("\\a%n", &len); break; case '\b': printf("\\b%n", &len); break; case '\f': printf("\\f%n", &len); break; case '\n': printf("\\n%n", &len); break; case '\r': printf("\\r%n", &len); break; case '\t': printf("\\t%n", &len); break; case '\v': printf("\\v%n", &len); break; default: printf("\\x%02X%n", +(unsigned char)sentence->string.string[off], &len); break; } off++; } else if (n == 4096U) { printf("%.*s%n", (int)n, &sentence->string.string[off], &len); indent += len; off += n; n = 0; } else { n++; } } if (n) { printf("%.*s%n", (int)n, &sentence->string.string[off], &len); indent += len; } printf("\"%n", &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", "!<0x00, 0xFF>", &len); indent += len; break; case LIBPARSER_SENTENCE_TYPE_EPSILON: default: abort(); } return indent; } int main(int argc, char *argv[]) { 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 1 if (libparser_rule_table[i]->name[0] == '@') continue; #endif 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; }