aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-11-28 08:54:40 +0100
committerMattias Andrée <maandree@operamail.com>2014-11-28 08:54:40 +0100
commit39f19113d30e87c1604ed4e8e39ea95f87296767 (patch)
tree8ee097832aae5f7346eb51a12b7aabd2066aac20
parentm (diff)
downloadmds-39f19113d30e87c1604ed4e8e39ea95f87296767.tar.gz
mds-39f19113d30e87c1604ed4e8e39ea95f87296767.tar.bz2
mds-39f19113d30e87c1604ed4e8e39ea95f87296767.tar.xz
m + macro call alternation elimination
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--doc/info/mds.texinfo6
-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
-rw-r--r--test-files/mds-kbdc/make-tree/README4
-rw-r--r--test-files/mds-kbdc/simplify-tree/README4
-rw-r--r--test-files/mds-kbdc/simplify-tree/valid/macro_call12
-rw-r--r--test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation59
-rw-r--r--test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation_with_nothing25
-rw-r--r--test-files/mds-kbdc/simplify-tree/valid/macro_call_with_nothing19
13 files changed, 169 insertions, 28 deletions
diff --git a/doc/info/mds.texinfo b/doc/info/mds.texinfo
index c6b7f0b..74e1720 100644
--- a/doc/info/mds.texinfo
+++ b/doc/info/mds.texinfo
@@ -5418,11 +5418,11 @@ you can write
It is undefined in which order alternations
and unordered subsequences are expanded;
neither sequencewise or levelwise.
-Thus, there should not side-effects where
+Thus, there should not be side-effects where
either one is used, nor does it make since
to nest the two constructs in any other
-way than alternation inside unordered
-subsequence.
+way than alternation or unordered subsequence
+inside unordered subsequence.
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
diff --git a/test-files/mds-kbdc/make-tree/README b/test-files/mds-kbdc/make-tree/README
new file mode 100644
index 0000000..97fc927
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/README
@@ -0,0 +1,4 @@
+When testing these files it is important to
+`goto stop;` after `parse_to_tree` been called
+in `mds-kbdc.c`.
+
diff --git a/test-files/mds-kbdc/simplify-tree/README b/test-files/mds-kbdc/simplify-tree/README
new file mode 100644
index 0000000..33776bb
--- /dev/null
+++ b/test-files/mds-kbdc/simplify-tree/README
@@ -0,0 +1,4 @@
+When testing these files it is important to
+`goto stop;` after `simplify_tree` been called
+in `mds-kbdc.c`.
+
diff --git a/test-files/mds-kbdc/simplify-tree/valid/macro_call b/test-files/mds-kbdc/simplify-tree/valid/macro_call
new file mode 100644
index 0000000..9341a8b
--- /dev/null
+++ b/test-files/mds-kbdc/simplify-tree/valid/macro_call
@@ -0,0 +1,12 @@
+my_macro()
+my_macro(1)
+
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments nil)
+# )
+# (macro_call (@ 2 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 2 9-10) ‘1’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation b/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation
new file mode 100644
index 0000000..0122c06
--- /dev/null
+++ b/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation
@@ -0,0 +1,59 @@
+my_macro([1 2] [3 4] [5 6])
+
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# (string (@ 1 16-17) ‘3’)
+# (string (@ 1 22-23) ‘5’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# (string (@ 1 16-17) ‘3’)
+# (string (@ 1 24-25) ‘6’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# (string (@ 1 18-19) ‘4’)
+# (string (@ 1 22-23) ‘5’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# (string (@ 1 18-19) ‘4’)
+# (string (@ 1 24-25) ‘6’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# (string (@ 1 16-17) ‘3’)
+# (string (@ 1 22-23) ‘5’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# (string (@ 1 16-17) ‘3’)
+# (string (@ 1 24-25) ‘6’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# (string (@ 1 18-19) ‘4’)
+# (string (@ 1 22-23) ‘5’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# (string (@ 1 18-19) ‘4’)
+# (string (@ 1 24-25) ‘6’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation_with_nothing b/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation_with_nothing
new file mode 100644
index 0000000..0c7096e
--- /dev/null
+++ b/test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation_with_nothing
@@ -0,0 +1,25 @@
+my_macro([1 2] [3 .])
+
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# (string (@ 1 16-17) ‘3’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 10-11) ‘1’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# (string (@ 1 16-17) ‘3’)
+# )
+# )
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments
+# (string (@ 1 12-13) ‘2’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/simplify-tree/valid/macro_call_with_nothing b/test-files/mds-kbdc/simplify-tree/valid/macro_call_with_nothing
new file mode 100644
index 0000000..f067b27
--- /dev/null
+++ b/test-files/mds-kbdc/simplify-tree/valid/macro_call_with_nothing
@@ -0,0 +1,19 @@
+my_macro(.)
+my_macro(. .)
+
+# (macro_call (@ 1 0-8) ‘my_macro’
+# (.arguments nil)
+# )
+# (macro_call (@ 2 0-8) ‘my_macro’
+# (.arguments nil)
+# )
+# :1:9–10: warning: ‘.’ outside alternation has no effect
+# my_macro(.)
+# ^
+# :2:9–10: warning: ‘.’ outside alternation has no effect
+# my_macro(. .)
+# ^
+# :2:11–12: warning: ‘.’ outside alternation has no effect
+# my_macro(. .)
+# ^
+