1 package iotpolicy.tree;
3 import java_cup.runtime.ComplexSymbolFactory;
4 import java_cup.runtime.ScannerBuffer;
6 import iotpolicy.tree.ParseNodeVector;
7 import iotpolicy.tree.ParseNode;
10 import java.util.ArrayList;
12 /** Class ParseTreeHandler handles the parse tree generated by the
13 * parser (and lexer) from the policy file.
14 * This class accepts the AST in the form of ParseNode and
15 * ParseNodeVector class objects.
16 * It gives interfaces to extract the 4 types of policy file:
17 * 1) Interface and capabilities definition
18 * 2) Generated interface list ("requires" statements)
20 * 4) Struct declaration
22 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
26 public final class ParseTreeHandler {
31 private ParseNode pnPol; // Policy: interface and capabilities
32 private ParseNode pnReq; // Policy: "requires" statements
33 private InterfaceDecl intDecl;
34 private CapabilityDecl capDecl;
35 private RequiresDecl reqDecl;
36 private EnumDecl enumDecl;
37 private StructDecl structDecl;
43 public ParseTreeHandler() {
47 intDecl = new InterfaceDecl();
48 capDecl = new CapabilityDecl();
49 reqDecl = new RequiresDecl();
50 enumDecl = new EnumDecl();
51 structDecl = new StructDecl();
55 public ParseTreeHandler(String _intFace, ParseNode _pnPol, ParseNode _pnReq) {
59 intDecl = new InterfaceDecl(_intFace);
60 capDecl = new CapabilityDecl(_intFace);
61 reqDecl = new RequiresDecl(_intFace);
62 enumDecl = new EnumDecl();
63 structDecl = new StructDecl();
68 * processInterfaceDecl() processes interface declaration part
70 public void processInterfaceDecl() {
72 ParseNodeVector pnv = pnPol.getChildren();
73 ParseNode pnRoot = pnv.elementAt(0);
74 ParseNodeVector pnvGen2 = pnRoot.getChildren();
75 if (pnvGen2.size() == 0) {
76 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
78 ParseNode pnGen2 = pnvGen2.elementAt(1);
79 ParseNodeVector pnvGen3 = pnGen2.getChildren();
80 for(int i = 0; i < pnvGen3.size(); i++) { // Loop on methods
82 ParseNode pnGen3 = pnvGen3.elementAt(i);
83 ParseNodeVector pnvGen4 = pnGen3.getChildren();
84 // Method type, identifier, and param node
85 ParseNode pnGen4_type = pnvGen4.elementAt(0);
86 ParseNode pnGen4_ident = pnvGen4.elementAt(1);
87 ParseNode pnGen4_params = pnvGen4.elementAt(2);
88 ParseNodeVector pnvGen5 = pnGen4_params.getChildren();
89 // First loop - create a key without spaces, e.g. MethodA(intA,SpeakerB)
90 String methodKey = pnGen4_ident.getLiteral().toString() + "(";
91 List<String> paramTypes = new ArrayList<String>();
92 List<String> params = new ArrayList<String>();
93 for(int j = 0; j < pnvGen5.size(); j++) { // Loop on params
95 ParseNode pnGen5 = pnvGen5.elementAt(j);
96 ParseNodeVector pnvGen6 = pnGen5.getChildren();
97 // Param type and identifier
98 ParseNode pnGen6_type = pnvGen6.elementAt(0);
99 ParseNode pnGen6_ident = pnvGen6.elementAt(1);
100 methodKey = methodKey + pnGen6_type.getLiteral().toString();
101 methodKey = methodKey + pnGen6_ident.getLiteral().toString();
102 // Keep the parameters temporarily
103 paramTypes.add(pnGen6_type.getLiteral().toString());
104 params.add(pnGen6_ident.getLiteral().toString());
105 // Don't add comma for the last parameter
106 if (j != pnvGen5.size() - 1) {
107 methodKey = methodKey + ",";
110 methodKey = methodKey + ")";
111 // Add a new method (signature key, identifier, and type)
112 intDecl.addNewMethod(methodKey, pnGen4_ident.getLiteral().toString(),
113 pnGen4_type.getLiteral().toString());
114 // Second loop - add the method parameters
115 for(int j = 0; j < params.size(); j++) {
116 intDecl.addMethodParam(methodKey, params.get(j), paramTypes.get(j));
123 * processCapabilityDecl() processes capability declaration part
125 public void processCapabilityDecl() {
127 // Get the root - capability list (element 1)
128 ParseNodeVector pnv = pnPol.getChildren();
129 ParseNode pnRoot = pnv.elementAt(0);
130 ParseNodeVector pnvGen2 = pnRoot.getChildren();
131 // Get the third child of root for "capab_list"
132 ParseNode pnGen2 = pnvGen2.elementAt(2);
133 ParseNodeVector pnvGen3 = pnGen2.getChildren();
134 if (pnvGen3.size() == 0) {
135 throw new Error("ParseTreeHandler: Capability declaration is missing! Please check your policy file...");
137 // Iterate over the list of capabilities
138 for(int i = 0; i < pnvGen3.size(); i++) {
140 ParseNode pnGen3 = pnvGen3.elementAt(i);
141 // Get the next level child for capabilities
142 ParseNodeVector pnvGen4 = pnGen3.getChildren();
143 // Get the capability name, e.g. ImageCapture for Camera.ImageCapture
144 ParseNode pnGen4_capab = pnvGen4.elementAt(0);
145 // Add new capability
146 capDecl.addNewCapability(pnGen4_capab.getLiteral().toString());
147 // Get the capability contents, i.e. descriptions and methods
148 ParseNode pnGen4_capab_cont = pnvGen4.elementAt(1);
149 ParseNodeVector pnvGen5 = pnGen4_capab_cont.getChildren();
150 // Iterate over the list of capability contents
151 for(int j = 0; j < pnvGen5.size(); j++) {
153 ParseNode pnGen5 = pnvGen5.elementAt(j);
154 ParseNodeVector pnvGen6 = pnGen5.getChildren();
155 ParseNode pnGen6 = pnvGen6.elementAt(0);
156 // Check the label and separate between description (capab_desc)
157 // and method name (capab_ident)
158 String label = pnGen6.getLabel().toString();
159 if (label.equals("capab_desc")) {
160 capDecl.addNewDescription(pnGen4_capab.getLiteral().toString(),
161 pnGen6.getLiteral().toString());
162 } else if (label.equals("capab_meth")) {
163 capDecl.addNewMethod(pnGen4_capab.getLiteral().toString(),
164 pnGen6.getLiteral().toString().replaceAll("\\s+",""));
166 throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
174 * processRequiresDecl() processes "requires" declaration part
176 public void processRequiresDecl() {
178 // Get the root - requires list (element 2)
179 ParseNodeVector pnv = pnReq.getChildren();
180 ParseNode pnRoot = pnv.elementAt(0);
181 // Get the second child of root for "reqlist"
182 ParseNodeVector pnvGen2 = pnRoot.getChildren();
183 if (pnvGen2.size() == 0) {
184 throw new Error("ParseTreeHandler: 'Requires' declaration is missing! Please check your policy file...");
186 // Iterate over the list of requires statements
187 for(int i = 0; i < pnvGen2.size(); i++) {
189 ParseNode pnGen2 = pnvGen2.elementAt(i);
190 ParseNodeVector pnvGen3 = pnGen2.getChildren();
191 // Get the new interface that we want to generate
192 ParseNode pnGen3_intface = pnvGen3.elementAt(2);
193 reqDecl.addNewIntface(pnGen3_intface.getLiteral().toString());
194 // Get capability list at element 1
195 ParseNode pnGen3_capab_list = pnvGen3.elementAt(1);
196 ParseNodeVector pnvGen4 = pnGen3_capab_list.getChildren();
197 // Browse through capabilities
198 for (int j = 0; j < pnvGen4.size(); j++) {
199 ParseNode pnGen4 = pnvGen4.elementAt(j);
200 reqDecl.addNewCapability(pnGen3_intface.getLiteral().toString(),
201 pnGen4.getLiteral().toString());
208 * processEnumDecl() processes "enum" declaration part
210 public void processEnumDecl() {
212 ParseNodeVector pnv = pnPol.getChildren();
213 ParseNode pnRoot = pnv.elementAt(0);
214 ParseNodeVector pnvGen2 = pnRoot.getChildren();
215 // Get the third child of root for "enum"
216 ParseNode pnGen2 = pnvGen2.elementAt(3);
217 ParseNodeVector pnvGen3 = pnGen2.getChildren();
218 // Iterate over a list of enum declaration - can be empty too
219 for(int i = 0; i < pnvGen3.size(); i++) {
221 ParseNode pnGen4 = pnvGen3.elementAt(i);
222 ParseNodeVector pnvGen5 = pnGen4.getChildren();
223 // Get the type of the enum
224 ParseNode pnGen5_enum_ident = pnvGen5.elementAt(0);
225 ParseNode pnGen5_enum_list = pnvGen5.elementAt(1);
226 ParseNodeVector pnvGen6_members = pnGen5_enum_list.getChildren();
227 // Browse through enum declarations
228 for (int j = 0; j < pnvGen6_members.size(); j++) {
229 ParseNode pnGen6 = pnvGen6_members.elementAt(j);
230 ParseNodeVector pnvGen7 = pnGen6.getChildren();
231 ParseNode pnGen7 = pnvGen7.elementAt(0);
232 enumDecl.addNewMember(pnGen5_enum_ident.getLiteral().toString(),
233 pnGen7.getLiteral().toString());
240 * processStructDecl() processes "struct" declaration part
242 public void processStructDecl() {
244 ParseNodeVector pnv = pnPol.getChildren();
245 ParseNode pnRoot = pnv.elementAt(0);
246 ParseNodeVector pnvGen2 = pnRoot.getChildren();
247 // Get the fourth child of root for "struct"
248 ParseNode pnGen2 = pnvGen2.elementAt(4);
249 ParseNodeVector pnvGen3 = pnGen2.getChildren();
250 // Iterate over a list of struct declaration - can be empty too
251 for(int i = 0; i < pnvGen3.size(); i++) {
253 ParseNode pnGen4 = pnvGen3.elementAt(i);
254 ParseNodeVector pnvGen5 = pnGen4.getChildren();
255 // Get the type of the enum
256 ParseNode pnGen5_enum_ident = pnvGen5.elementAt(0);
257 ParseNode pnGen5_enum_list = pnvGen5.elementAt(1);
258 ParseNodeVector pnvGen6_members = pnGen5_enum_list.getChildren();
259 // Browse through enum declarations
260 for (int j = 0; j < pnvGen6_members.size(); j++) {
261 ParseNode pnGen6 = pnvGen6_members.elementAt(j);
262 ParseNodeVector pnvGen7 = pnGen6.getChildren();
263 ParseNode pnGen7_type = pnvGen7.elementAt(0);
264 ParseNode pnGen7_ident = pnvGen7.elementAt(1);
265 structDecl.addNewMember(pnGen5_enum_ident.getLiteral().toString(),
266 pnGen7_type.getLiteral().toString(), pnGen7_ident.getLiteral().toString());
273 * getInterfaceDecl() returns InterfaceDecl object
275 public InterfaceDecl getInterfaceDecl() {
282 * getCapabilityDecl() returns CapabilityDecl object
284 public CapabilityDecl getCapabilityDecl() {
291 * getRequiresDecl() returns RequiresDecl object
293 public RequiresDecl getRequiresDecl() {
300 * getEnumDecl() returns EnumDecl object
302 public EnumDecl getEnumDecl() {
309 * getStructDecl() returns StructDecl object
311 public StructDecl getStructDecl() {
318 * getOrigIntface() returns the original interface in policy, e.g. Camera
320 * The ParseNode object should be the one returned from <Parser>.parse().value
322 public static String getOrigIntface(ParseNode pn) {
324 // Get the root: just keyword "interface"
325 ParseNodeVector pnv = pn.getChildren();
326 ParseNode pnRoot = pnv.elementAt(0);
327 // Get the child: intface_ident = original interface identifier, e.g. Camera
328 ParseNodeVector pnvGen2 = pnRoot.getChildren();
329 if (pnvGen2.size() == 0) {
330 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
333 ParseNode pnGen2 = pnvGen2.elementAt(0);
334 // Confirm that this is "intface_ident"
335 if (pnGen2.getLabel().equals("intface_ident")) {
336 if (pnGen2.getLiteral() != null) {
337 return pnGen2.getLiteral().toString();
339 throw new Error("ParseTreeHandler: No interface name found! Please fix policy file!");
341 throw new Error("ParseTreeHandler: Label 'intface_ident' is not found! Instead, '" + pnGen2.getLabel() + "' was found...");