This repository has been archived by the owner on Jan 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast_policy_compressor_visitor.cc
112 lines (102 loc) · 4.74 KB
/
ast_policy_compressor_visitor.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright 2015-2018 RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ast_policy_compressor_visitor.hh"
void AstPolicyCompressorVisitor::visit(AstOperation &op) {
//check that the operation is not the unsupported negation (is moved into the relations)
if(op.type == AstOperationType::NOT)
throw "The not operation should be eliminated at the policy compression stage, since we here only support & and |.";
//store the AND and OR operations directly inside the RPN stack
if(op.type == AstOperationType::OR || op.type == AstOperationType::AND) {
//call the policy compressor also for the children of the node
//from left to right
for(uint8_t i = 0; i < op.getNumberOfChildren(); i++) {
op.getChild(i)->accept(*this);
}
//store the polcy in the reverse order as the RPN s.t. we can build the execution stack from first to last bit
if(op.type == AstOperationType::OR) {
StackOperation stackOp;
stackOp.type = PolicyStackOperationType::OR;
policyStack.push_back(stackOp);
} else { //must be AND
StackOperation stackOp;
stackOp.type = PolicyStackOperationType::AND;
policyStack.push_back(stackOp);
}
}
else if(op.type == AstOperationType::ELIMINATED_NOT) {
assert(op.getNumberOfChildren() == 1); //only NOT with one child are supported
op.getChild(0)->accept(*this);
#if DEBUG_POLICY_GENERATION
cout << " Eliminated NOT ";
#endif
}
//the remaining operations are all relations
else {
//add the children to the relation
op.getChild(0)->accept(*this);
if(op.type != AstOperationType::IS_TRUE && op.type != AstOperationType::IS_FALSE) {
assert(op.getNumberOfChildren() == 2); //we support only non binary operations, for IS_TRUE and IS_FALSE
op.getChild(1)->accept(*this);
}
//convert to AstOperationType to RelationSetType
RelationSetType relationType;
if(op.type == AstOperationType::EQUAL)
relationType = RelationSetType::EQUAL;
else if(op.type == AstOperationType::NEQ)
relationType = RelationSetType::NEQ;
else if(op.type == AstOperationType::LESS)
relationType = RelationSetType::LESS;
else if(op.type == AstOperationType::LEQ)
relationType = RelationSetType::LEQ;
else if(op.type == AstOperationType::GREATER)
relationType = RelationSetType::GREATER;
else if(op.type == AstOperationType::GEQ)
relationType = RelationSetType::GEQ;
else if(op.type == AstOperationType::IS_TRUE)
relationType = RelationSetType::IS_TRUE;
else if(op.type == AstOperationType::IS_FALSE)
relationType = RelationSetType::IS_FALSE;
else
throw "Compression for this RelationSetType is not implemented";
int64_t relationId = relationSet.addType(relationType);
#if DEBUG_POLICY_GENERATION
cout << " RelId:" << relationId;
#endif
//insert the new relation
StackOperation stackOp;
if(relationId == -1) //a normal, new relation
stackOp.type = PolicyStackOperationType::NEXT_RELATION;
else { //a redundant relation s.t. we use the specific relation feature to point to the previously stored one
stackOp.type = PolicyStackOperationType::SPECIFIC_RELATION;
stackOp.relationId = relationId;
}
policyStack.push_back(stackOp); //add the relation to the stack
}
}
void AstPolicyCompressorVisitor::visit(AstConstant &constant) {
//insert new relation inside the equation set
relationSet.addRelationElement(constant);
}
void AstPolicyCompressorVisitor::visit(AstId &id) {
//insert new relation inside the equation set
relationSet.addRelationElement(id);
}
void AstPolicyCompressorVisitor::visit(AstFunction &func) {
//insert new relation inside the equation set
relationSet.addRelationElement(func);
}
void AstPolicyCompressorVisitor::visit(Ast &ast) {
policyStack.addEndDelimiter(); //add the end delimiter to the policy stack end
ast.root->accept(*this); //check from the root the types
}