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:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user