aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc/simplify-tree.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/mds-kbdc/simplify-tree.c88
1 files changed, 62 insertions, 26 deletions
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index f032dd6..7ca0729 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -286,7 +286,7 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
else if (argument->type == MDS_KBDC_TREE_TYPE_ALTERNATION)
{
/* Alternation nesting. */
- NEW_ERROR(argument, WARNING, "alternation inside alternation is unnecessary");
+ NEW_ERROR(argument, WARNING, "alternation inside alternation is unnessary");
if (simplify_alternation(&(argument->alternation)))
return -1;
if (argument->type == MDS_KBDC_TREE_TYPE_ALTERNATION)
@@ -310,7 +310,59 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
redo = 1;
}
- /* TODO unordered */
+ /* TODO unordered (warn: discouraged) */
+
+ return 0;
+ pfail:
+ return -1;
+}
+
+
+/**
+ * Simplify an unordered subsequence-subtree
+ *
+ * @param tree The unordered subsequence-subtree
+ * @return Zero on success, -1 on error
+ */
+static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
+{
+ mds_kbdc_tree_t* argument;
+ mds_kbdc_tree_t* temp;
+ mds_kbdc_tree_t** here;
+
+ /* Test emptyness. */
+ if (tree->inner == NULL)
+ {
+ NEW_ERROR(tree, ERROR, "empty unordered subsequence");
+ tree->type = MDS_KBDC_TREE_TYPE_NOTHING;
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+ }
+
+ /* Test singletonness. */
+ if (tree->inner->next == NULL)
+ {
+ temp = tree->inner;
+ NEW_ERROR(tree, WARNING, "singleton unordered subsequence");
+ memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
+ free(temp);
+ return simplify((mds_kbdc_tree_t*)tree);
+ }
+
+ /* Remove ‘.’:s. */
+ for (here = &(tree->inner); *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;
+ NEW_ERROR(*here, WARNING, "‘.’ inside unordered subsequences has no effect");
+ mds_kbdc_tree_free(*here);
+ *here = argument;
+ }
+
+ /* TODO alternation, unordered (warn: unreadable) */
return 0;
pfail:
@@ -326,7 +378,8 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
*/
static int simplify(mds_kbdc_tree_t* restrict tree)
{
-#define s(expr) if ((r = simplify(tree->expr))) return r;
+#define s(expr) if ((r = simplify(tree->expr))) return r
+#define S(type) if ((r = simplify_##type(&(tree->type)))) return r
int r;
again:
if (tree == NULL)
@@ -339,29 +392,11 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
case MDS_KBDC_TREE_TYPE_MACRO: s (macro.inner); break;
case MDS_KBDC_TREE_TYPE_ASSUMPTION: s (assumption.inner); break;
case MDS_KBDC_TREE_TYPE_FOR: s (for_.inner); break;
- case MDS_KBDC_TREE_TYPE_IF:
- s (if_.inner);
- s (if_.otherwise);
- break;
-
- case MDS_KBDC_TREE_TYPE_MAP:
- /* TODO */
- break;
-
- case MDS_KBDC_TREE_TYPE_ALTERNATION:
- if ((r = simplify_alternation(&(tree->alternation))))
- return r;
- break;
-
- case MDS_KBDC_TREE_TYPE_UNORDERED:
- /* TODO find alternation and nothing, find singletons, error if empty, unordered */
- break;
-
- case MDS_KBDC_TREE_TYPE_MACRO_CALL:
- if ((r = simplify_macro_call(&(tree->macro_call))))
- return r;
- break;
-
+ case MDS_KBDC_TREE_TYPE_IF: s (if_.inner); s (if_.otherwise); break;
+ case MDS_KBDC_TREE_TYPE_MAP: /* TODO */ break;
+ case MDS_KBDC_TREE_TYPE_ALTERNATION: S (alternation); break;
+ case MDS_KBDC_TREE_TYPE_UNORDERED: S (unordered); break;
+ case MDS_KBDC_TREE_TYPE_MACRO_CALL: S (macro_call); break;
default:
break;
}
@@ -369,6 +404,7 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
#undef s
+#undef S
}