2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 22:35:35 +00:00

Improve tree normalization

- reduce the amount it is called, and the amount of recursion it does
- fix a bug that would prevent trees from being fully normalized
This commit is contained in:
John Johansen
2008-11-19 16:54:26 +00:00
parent 77eb67b5a0
commit 91eb71e9fa

View File

@@ -487,13 +487,12 @@
* a | (b | c) -> (a | b) | c * a | (b | c) -> (a | b) | c
* a(bc) -> (ab)c * a(bc) -> (ab)c
*/ */
bool normalize_tree(Node *t, int dir) void normalize_tree(Node *t, int dir)
{ {
bool update = false;
if (dynamic_cast<ImportantNode *>(t)) if (dynamic_cast<ImportantNode *>(t))
return false; return;
for (;; update=true) { for (;;) {
if ((dynamic_cast<AltNode *>(t) && if ((dynamic_cast<AltNode *>(t) &&
dynamic_cast<EpsNode *>(t->child[dir])) || dynamic_cast<EpsNode *>(t->child[dir])) ||
(dynamic_cast<CatNode *>(t) && (dynamic_cast<CatNode *>(t) &&
@@ -503,8 +502,7 @@ bool normalize_tree(Node *t, int dir)
Node *c = t->child[dir]; Node *c = t->child[dir];
t->child[dir] = t->child[!dir]; t->child[dir] = t->child[!dir];
t->child[!dir] = c; t->child[!dir] = c;
} } else if ((dynamic_cast<AltNode *>(t) &&
if ((dynamic_cast<AltNode *>(t) &&
dynamic_cast<AltNode *>(t->child[dir])) || dynamic_cast<AltNode *>(t->child[dir])) ||
(dynamic_cast<CatNode *>(t) && (dynamic_cast<CatNode *>(t) &&
dynamic_cast<CatNode *>(t->child[dir]))) { dynamic_cast<CatNode *>(t->child[dir]))) {
@@ -516,14 +514,13 @@ bool normalize_tree(Node *t, int dir)
c->child[!dir] = t->child[!dir]; c->child[!dir] = t->child[!dir];
t->child[!dir] = c; t->child[!dir] = c;
} else { } else {
if (t->child[dir] && normalize_tree(t->child[dir], dir))
continue;
if (t->child[!dir] && normalize_tree(t->child[!dir], dir))
continue;
break; break;
} }
} }
return update; if (t->child[dir])
normalize_tree(t->child[dir], dir);
if (t->child[!dir])
normalize_tree(t->child[!dir], dir);
} }
/* /*
@@ -647,7 +644,7 @@ Node *simplify_tree_base(Node *t, int dir)
} }
i->child[dir] = cnode; i->child[dir] = cnode;
normalize_tree(i, dir); // normalize_tree(i, dir);
return i->dup(); return i->dup();
} }
no_alt_factor: no_alt_factor:
@@ -663,7 +660,7 @@ no_alt_factor:
t->child[dir] = c->child[!dir]; t->child[dir] = c->child[!dir];
t->child[!dir] = new EpsNode(); t->child[!dir] = new EpsNode();
c->child[!dir] = t->dup(); c->child[!dir] = t->dup();
normalize_tree(c, dir); // normalize_tree(c, dir);
return c; return c;
} }
} }
@@ -678,7 +675,7 @@ no_alt_factor:
t->child[dir] = c->child[!dir]; t->child[dir] = c->child[!dir];
t->child[!dir] = new EpsNode(); t->child[!dir] = new EpsNode();
c->child[!dir] = t->dup(); c->child[!dir] = t->dup();
normalize_tree(c, dir); // normalize_tree(c, dir);
return c; return c;
} }
} }
@@ -695,7 +692,7 @@ no_alt_factor:
t->child[!dir] = right->child[!dir]->dup(); t->child[!dir] = right->child[!dir]->dup();
left->child[!dir] = t->dup(); left->child[!dir] = t->dup();
right->release(); right->release();
normalize_tree(left, dir); // normalize_tree(left, dir);
return left; return left;
} }
} }
@@ -731,12 +728,13 @@ Node *simplify_tree(Node *t)
// the dfa having about 7 thousands states, // the dfa having about 7 thousands states,
// and it having about 1.25 million states // and it having about 1.25 million states
for (int dir = 1; dir >= 0 ; dir--) { for (int dir = 1; dir >= 0 ; dir--) {
while (normalize_tree(t, dir)); normalize_tree(t, dir);
for (Node *c = simplify_tree_base(t, dir); for (Node *c = simplify_tree_base(t, dir);
c != t; c != t;
c = simplify_tree_base(t, dir)) { c = simplify_tree_base(t, dir)) {
t->release(); t->release();
t = c; t = c;
normalize_tree(t, dir);
update = 1; update = 1;
} }
} }