From 39f19113d30e87c1604ed4e8e39ea95f87296767 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 28 Nov 2014 08:54:40 +0100 Subject: m + macro call alternation elimination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- doc/info/mds.texinfo | 6 +-- src/mds-kbdc/make-tree.c | 2 +- src/mds-kbdc/mds-kbdc.c | 6 ++- src/mds-kbdc/parsed.c | 1 + src/mds-kbdc/simplify-tree.c | 29 +++++++---- src/mds-kbdc/tree.c | 16 +++--- src/mds-kbdc/tree.h | 14 ++--- test-files/mds-kbdc/make-tree/README | 4 ++ test-files/mds-kbdc/simplify-tree/README | 4 ++ test-files/mds-kbdc/simplify-tree/valid/macro_call | 12 +++++ .../simplify-tree/valid/macro_call_alternation | 59 ++++++++++++++++++++++ .../valid/macro_call_alternation_with_nothing | 25 +++++++++ .../simplify-tree/valid/macro_call_with_nothing | 19 +++++++ 13 files changed, 169 insertions(+), 28 deletions(-) create mode 100644 test-files/mds-kbdc/make-tree/README create mode 100644 test-files/mds-kbdc/simplify-tree/README create mode 100644 test-files/mds-kbdc/simplify-tree/valid/macro_call create mode 100644 test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation create mode 100644 test-files/mds-kbdc/simplify-tree/valid/macro_call_alternation_with_nothing create mode 100644 test-files/mds-kbdc/simplify-tree/valid/macro_call_with_nothing 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 @@ -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(. .) +# ^ + -- cgit v1.2.3-70-g09d2