aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mds-kbdc/make-tree.c2
-rw-r--r--src/mds-kbdc/mds-kbdc.c6
-rw-r--r--src/mds-kbdc/parsed.c1
-rw-r--r--src/mds-kbdc/simplify-tree.c29
-rw-r--r--src/mds-kbdc/tree.c16
-rw-r--r--src/mds-kbdc/tree.h14
6 files changed, 43 insertions, 25 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 1d91a57..d4686a9 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -896,7 +896,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res
NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
NEXT;
}
- else if (strchr("\"<([0123456789", *line))
+ else if (strchr("\\\"<([0123456789", *line))
{
size_t stack_orig = stack_ptr + 1;
#define node supernode
diff --git a/src/mds-kbdc/mds-kbdc.c b/src/mds-kbdc/mds-kbdc.c
index f7bfb06..55e3587 100644
--- a/src/mds-kbdc/mds-kbdc.c
+++ b/src/mds-kbdc/mds-kbdc.c
@@ -19,6 +19,7 @@
#include "globals.h"
#include "make-tree.h"
+#include "simplify-tree.h"
#include <libmdsserver/macros.h>
@@ -46,7 +47,10 @@ int main(int argc_, char** argv_)
mds_kbdc_parsed_initialise(&result);
fail_if (parse_to_tree(argv[1], &result) < 0);
- fatal = mds_kbdc_parsed_is_fatal(&result);
+ if (fatal = mds_kbdc_parsed_is_fatal(&result), fatal)
+ goto stop;
+ fail_if (simplify_tree(&result) < 0);
+ stop:
mds_kbdc_tree_print(result.tree, stderr);
mds_kbdc_parsed_print_errors(&result, stderr);
mds_kbdc_parsed_destroy(&result);
diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c
index 6b4160f..81b1f04 100644
--- a/src/mds-kbdc/parsed.c
+++ b/src/mds-kbdc/parsed.c
@@ -42,6 +42,7 @@ void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
{
mds_kbdc_tree_free(this->tree);
mds_kbdc_source_code_destroy(this->source_code);
+ free(this->source_code);
free(this->pathname);
mds_kbdc_parse_error_free_all(this->errors);
memset(this, 0, sizeof(mds_kbdc_parsed_t));
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index 44ae51b..1dd5a00 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -77,21 +77,26 @@ static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
mds_kbdc_tree_t* dup_argument;
mds_kbdc_tree_t** here;
size_t i, argument_index = 0;
+ long processed;
/* Simplify arguments. */
for (argument = tree->arguments; argument; argument = argument->next)
simplify(argument);
/* Remove ‘.’:s. */
- for (here = &(tree->arguments); *here; here = &((*here)->next))
- while (*here && (*here)->type == MDS_KBDC_TREE_TYPE_NOTHING)
- {
- mds_kbdc_tree_t* temp = (*here)->next;
- (*here)->next = NULL;
- NEW_ERROR(*here, WARNING, "‘.’ outside alternation has no effect");
- mds_kbdc_tree_free(*here);
- *here = temp;
- }
+ processed = tree->processed, tree->processed = 2;
+ for (here = &(tree->arguments); *here;)
+ if ((*here)->type != MDS_KBDC_TREE_TYPE_NOTHING)
+ here = &((*here)->next);
+ else
+ while (*here && (*here)->type == MDS_KBDC_TREE_TYPE_NOTHING)
+ {
+ argument = (*here)->next, (*here)->next = NULL;
+ if (processed != 2)
+ NEW_ERROR(*here, WARNING, "‘.’ outside alternation has no effect");
+ mds_kbdc_tree_free(*here);
+ *here = argument;
+ }
/* Copy arguments. */
if (tree->arguments == NULL)
@@ -137,8 +142,8 @@ static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
}
mds_kbdc_tree_destroy((mds_kbdc_tree_t*)tree);
memcpy(tree, first, sizeof(mds_kbdc_tree_t));
- tree->next = first;
last->next = next_statement;
+ free(first);
}
mds_kbdc_tree_free(dup_argument);
@@ -209,6 +214,8 @@ static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
* my_macro(2 2 2) ## call 8
*
* no difference after simplify_macro_call on call 8
+ *
+ * Nothings (‘.’) are removed before processing the alternations.
*/
return 0;
@@ -252,7 +259,7 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
break;
case MDS_KBDC_TREE_TYPE_UNORDERED:
- /* TODO find alternation, unordered and nothing, find singletons, multiple nothings, error if empty */
+ /* TODO find alternation, unordered and nothing, find singletons, error if empty */
break;
case MDS_KBDC_TREE_TYPE_MACRO_CALL:
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index b11bb6c..5d00601 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -229,8 +229,8 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define T(member) \
- if (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL) goto fail
+#define T(member) \
+ if (t->member && (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL)) goto fail
/**
@@ -238,8 +238,8 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define S(member) \
- if (n->member = strdup(t->member), n->member == NULL) goto fail
+#define S(member) \
+ if (t->member && (n->member = strdup(t->member), n->member == NULL)) goto fail
/**
@@ -273,8 +273,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this)
node->loc_line = this->loc_line;
node->loc_start = this->loc_start;
node->loc_end = this->loc_end;
- node->next = mds_kbdc_tree_dup(this->next);
- if (node->next == NULL) goto fail;
+ node->processed = this->processed;
+ if (this->next)
+ {
+ node->next = mds_kbdc_tree_dup(this->next);
+ if (node->next == NULL) goto fail;
+ }
switch (this->type)
{
diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h
index d12adea..e529dfc 100644
--- a/src/mds-kbdc/tree.h
+++ b/src/mds-kbdc/tree.h
@@ -170,18 +170,20 @@ typedef union mds_kbdc_tree mds_kbdc_tree_t;
* tree structures.
*
* It defines:
- * - int type; -- Integer that specifies which structure is used
- * - mds_kbdc_tree_t*; -- The next node in the tree, at the same level; a sibling
- * - loc_line; -- The line in the source code where this is found
- * - loc_start; -- The first byte in the source code where this is found, inclusive
- * - loc_end; -- The last byte in the source code where this is found, exclusive
+ * - int type; -- Integer that specifies which structure is used
+ * - mds_kbdc_tree_t* next; -- The next node in the tree, at the same level; a sibling
+ * - size_t loc_line; -- The line in the source code where this is found
+ * - size_t loc_start; -- The first byte in the source code where this is found, inclusive
+ * - size_t loc_end; -- The last byte in the source code where this is found, exclusive
+ * - long processed; -- The lasted step where the statement has already been processed once
*/
#define MDS_KBDC_TREE_COMMON \
int type; \
mds_kbdc_tree_t* next; \
size_t loc_line; \
size_t loc_start; \
- size_t loc_end
+ size_t loc_end; \
+ long processed
/**
* This macro is used in this header file, and is then