From 71e245e74c8c09c0b19cd2c99e3c348f8ee7477a Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 3 Jan 2022 12:27:39 +0100 Subject: Fix reject and char-range support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- LICENSE | 2 +- config.mk | 4 +- libparser-generate.c | 6 ++- print-syntax.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 print-syntax.c diff --git a/LICENSE b/LICENSE index c44b2d9..c90d3cc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -© 2021 Mattias Andrée +© 2021, 2022 Mattias Andrée Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/config.mk b/config.mk index dac7c46..accd17b 100644 --- a/config.mk +++ b/config.mk @@ -4,5 +4,5 @@ MANPREFIX = $(PREFIX)/share/man CC = cc CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -I"$$(pwd)" -CFLAGS = -std=c99 -Wall -Og -g -LDFLAGS = +CFLAGS = -std=c99 -Wall -O2 +LDFLAGS = -s diff --git a/libparser-generate.c b/libparser-generate.c index 9f82a2e..3f544c3 100644 --- a/libparser-generate.c +++ b/libparser-generate.c @@ -454,6 +454,8 @@ order_sentences(struct node *node) goto again_operators; } } else { + if (node->token->s[0] == '!') + node->data = order_sentences(node->data); *head = node; head = &node->next; } @@ -474,6 +476,7 @@ order_sentences(struct node *node) prev = stack->next->next->next; stack->data = stack->next->next; stack->data->next = stack->next; + stack->next->next = NULL; /* for debugging */ stack->next = prev; } } @@ -487,8 +490,7 @@ emit_and_free_rule(struct node *rule) { size_t index = 0; - if (rule->data->token->s[0] != '<') - rule->data = order_sentences(rule->data); + rule->data = order_sentences(rule->data); emit_and_free_sentence(rule->data, &index); printf("static struct libparser_rule rule_%zu = {\"%s\", &sentence_%zu_0};\n", nrule_names, rule->token->s, nrule_names); 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 +#include +#include +#include +#include + +#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; +} -- cgit v1.2.3-70-g09d2