aboutsummaryrefslogtreecommitdiffstats
path: root/libparser-generate.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparser-generate.c')
-rw-r--r--libparser-generate.c58
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;