diff options
| author | Mattias Andrée <m@maandree.se> | 2026-01-05 14:35:26 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-02-23 07:53:08 +0100 |
| commit | 208594ca9f95a87f60ff052490a4d5824dc23801 (patch) | |
| tree | 915a17b51f62b289ba4115214a057610416d755e /libparser-generate.c | |
| parent | Add committed-operator (diff) | |
| download | libparser-208594ca9f95a87f60ff052490a4d5824dc23801.tar.gz libparser-208594ca9f95a87f60ff052490a4d5824dc23801.tar.bz2 libparser-208594ca9f95a87f60ff052490a4d5824dc23801.tar.xz | |
Make deterministic the default
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libparser-generate.c')
| -rw-r--r-- | libparser-generate.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/libparser-generate.c b/libparser-generate.c index a8761f8..0a91835 100644 --- a/libparser-generate.c +++ b/libparser-generate.c @@ -38,6 +38,7 @@ struct node { struct node *next; /* next element in list */ struct node *data; /* beginning of subsentence */ struct node **head; /* end of subsentence */ + int nondeterministic; }; @@ -65,15 +66,6 @@ emalloc(size_t n) } static void * -ecalloc(size_t n, size_t m) -{ - void *ret = calloc(n, m); - if (!ret) - eprintf("%s: calloc %zu %zu: %s\n", argv0, n, m, strerror(errno)); - return ret; -} - -static void * erealloc(void *ptr, size_t n) { void *ret = realloc(ptr, n); @@ -104,6 +96,20 @@ estrdup(char *s) } +static struct node * +new_node(void) +{ + struct node *ret = emalloc(sizeof(*ret)); + ret->token = NULL; + ret->parent = NULL; + ret->next = NULL; + ret->data = NULL; + ret->head = NULL; + ret->nondeterministic = 0; + return ret; +} + + static int strpcmp(const void *av, const void *bv) { @@ -120,6 +126,7 @@ isidentifier(char c) } + static int check_utf8(char *buf, size_t *ip, size_t len) { @@ -379,10 +386,11 @@ emit_and_free_sentence(struct node *node, size_t *indexp) case '!': type = "REJECTION"; unary: emit_and_free_sentence(node->data, indexp); printf("static union libparser_sentence sentence_%zu_%zu = {.unary = {" - ".type = LIBPARSER_SENTENCE_TYPE_%s, .sentence = &sentence_%zu_%zu" + ".type = LIBPARSER_SENTENCE_TYPE_%s%s, .sentence = &sentence_%zu_%zu" "}};\n", nrule_names, index, - type, nrule_names, index + 1u); + node->nondeterministic ? "ND_" : "", type, + nrule_names, index + 1u); break; case '<': @@ -412,11 +420,11 @@ emit_and_free_sentence(struct node *node, size_t *indexp) left = *indexp; emit_and_free_sentence(node->data, indexp); printf("static union libparser_sentence sentence_%zu_%zu = {.binary = {" - ".type = LIBPARSER_SENTENCE_TYPE_%s, " + ".type = LIBPARSER_SENTENCE_TYPE_%s%s, " ".left = &sentence_%zu_%zu, .right = &sentence_%zu_%zu" "}};\n", nrule_names, index, - type, + node->nondeterministic ? "ND_" : "", type, nrule_names, left, nrule_names, right); break; @@ -587,7 +595,7 @@ main(int argc, char *argv[]) struct node *stack = NULL, *parent_node, *node; char *data; struct token **tokens; - size_t i, j; + size_t i, j, nondeterministic; int cmp, err, val; if (argc) { @@ -613,6 +621,7 @@ main(int argc, char *argv[]) printf("#include <libparser.h>\n"); + nondeterministic = SIZE_MAX; i = 0; again: for (; tokens[i]; i++) { @@ -635,7 +644,7 @@ again: } /* Also remove any whitespace (the tokeniser - * simple and does not recognise mulltisymbol + * simple and does not recognise multisymbol * tokens (that is apart form strings and * identifiers) so it cannot ignore whitespace. */ if (isspace(tokens[i]->s[0])) { @@ -643,6 +652,16 @@ again: continue; } + /* Check if next token is non-deterministic */ + if (tokens[i]->s[0] == '?') { + if (tokens[i + 1u]->s[0] == '[' || + tokens[i + 1u]->s[0] == '{' || + tokens[i + 1u]->s[0] == '|') { + nondeterministic = i + 1u; + continue; + } + } + /* For the sake of code readability, identify * the token type */ if (tokens[i]->s[0] == '"') { @@ -661,7 +680,8 @@ again: eprintf("%s: expected an identifier on line %zu at column %zu (character %zu)\n", argv0, tokens[i]->lineno, tokens[i]->column, tokens[i]->character); } - stack = calloc(1, sizeof(*stack)); + stack = new_node(); + stack->nondeterministic = i == nondeterministic; stack->token = tokens[i]; stack->head = &stack->data; /* and then we expect an equals sign */ @@ -715,7 +735,8 @@ again: state = EXPECT_RANGE_LOW; push_stack: parent_node = stack; - stack = ecalloc(1, sizeof(*stack)); + stack = new_node(); + stack->nondeterministic = i == nondeterministic; stack->parent = parent_node; stack->token = tokens[i]; stack->head = &stack->data; @@ -756,7 +777,8 @@ again: * token to be an operand */ state = EXPECT_OPERAND; add_singleton: - node = calloc(1u, sizeof(*node)); + node = new_node(); + node->nondeterministic = i == nondeterministic; node->token = tokens[i]; *stack->head = node; stack->head = &node->next; |
