Completing parser to parse generic/template return types; adding standard method...
[iot2.git] / others / javacup / iotparser.cup
1 /* Minijava Grammar */
2 import java_cup.runtime.ComplexSymbolFactory;
3 import java_cup.runtime.ScannerBuffer;
4 import java_cup.runtime.XMLElement;
5 import javax.xml.stream.XMLOutputFactory;
6 import javax.xml.stream.XMLStreamWriter;
7 import java.io.*;
8
9 import javax.xml.transform.*;
10 import javax.xml.transform.stream.*;
11
12 parser code {:
13   public Parser(Lexer lex, ComplexSymbolFactory sf) {
14     super(lex,sf);
15   }
16   public static void main(String[] args) throws Exception {
17       // initialize the symbol factory
18       ComplexSymbolFactory csf = new ComplexSymbolFactory();
19       // create a buffering scanner wrapper
20       ScannerBuffer lexer = new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csf));
21       // start parsing
22       Parser p = new Parser(lexer,csf);
23       ParseNode pn = (ParseNode) p.parse().value;
24   }
25 :};
26
27 terminal SEMICOLON, COMMA, LPAR, RPAR, LANG, RANG, BEGIN, END, ASSIGN;
28 terminal PUBLIC, INTERFACE, CAPABILITY, DESCRIPTION, METHOD, REQUIRES, WITH, AS, ENUM, STRUCT; 
29 terminal TYPE;
30 terminal IDENT, STRINGCONST;
31
32 non terminal ParseNode policy;
33 non terminal ParseNode intface, methlist, meth, paramlist, param, paramtype;
34 non terminal ParseNode capablist, capab, capabcont, cont;
35 non terminal ParseNode reqlist, require, capintlist;
36 non terminal ParseNode enumdec, enumlist, enummem;
37 non terminal ParseNode structdec, structlist, structmem;
38
39
40 /**
41  * A policy file normally consists of:
42  * 1) Interface 
43  *    - Interface definition
44  *    - List of capabilities and their contents
45  *
46  * We also define "requires" statements for users
47  * to declare their required capabilities in the
48  * generated interfaces
49  * 2) List of generated interfaces (requires)
50  *
51  * Additionally we support declarations for these
52  * data types:
53  * 3) Enumeration
54  * 4) Struct
55  */
56 policy     ::= intface:in
57         {:
58                 ParseNode pn = new ParseNode("policy");
59                 pn.addChild(in);
60                 RESULT = pn;
61         :}
62         | reqlist:rl
63         {:
64                 ParseNode pn = new ParseNode("policy");
65                 pn.addChild(rl);
66                 RESULT = pn;
67         :}
68         | enumdec:en
69         {:
70                 ParseNode pn = new ParseNode("policy");
71                 pn.addChild(en);
72                 RESULT = pn;
73         :}
74         | structdec:st
75         {:
76                 ParseNode pn = new ParseNode("policy");
77                 pn.addChild(st);
78                 RESULT = pn;
79         :}
80     ;
81
82 //1) Interface class definition
83 // 1) Interface definition
84 // 2) Library list
85 // 3) Driver list
86
87 // Interface
88 intface    ::= PUBLIC INTERFACE IDENT:idint BEGIN methlist:ml capablist:cl END
89         {:
90                 ParseNode pn = new ParseNode("interface");
91                 pn.addChild("intface_ident").setLiteral(idint);
92                 pn.addChild(ml);
93                 pn.addChild(cl);
94                 RESULT = pn;
95         :}
96     ;
97 methlist   ::= methlist:ml meth:m
98         {:
99                 ml.addChild(m);
100                 RESULT = ml;
101         :}
102     | /* empty */
103         {:
104                 ParseNode pn = new ParseNode("method_list");
105                 RESULT = pn;
106         :}
107     ;
108 meth       ::= PUBLIC TYPE:typemeth IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON
109         {:
110                 ParseNode pn = new ParseNode("method");
111                 pn.addChild("method_type").setLiteral(typemeth);
112                 pn.addChild("method_ident").setLiteral(idmeth);
113                 pn.addChild(pl);
114                 RESULT = pn;
115         :}
116     | PUBLIC IDENT:clsmeth IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON
117         {:
118                 ParseNode pn = new ParseNode("method");
119                 pn.addChild("method_class").setLiteral(clsmeth);
120                 pn.addChild("method_ident").setLiteral(idmeth);
121                 pn.addChild(pl);
122                 RESULT = pn;
123         :}
124         /* generic/template return value with one type, e.g. set<int> */
125     | PUBLIC IDENT:clsmeth LANG TYPE:typegen RANG IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON
126         {:
127                 ParseNode pn = new ParseNode("method");
128                 pn.addChild("method_class").setLiteral((String)clsmeth + "<" + typegen + ">");
129                 pn.addChild("method_ident").setLiteral(idmeth);
130                 pn.addChild(pl);
131                 RESULT = pn;
132         :}
133     | PUBLIC IDENT:clsmeth LANG IDENT:clsgen RANG IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON
134         {:
135                 ParseNode pn = new ParseNode("method");
136                 pn.addChild("method_class").setLiteral((String)clsmeth + "<" + clsgen + ">");
137                 pn.addChild("method_ident").setLiteral(idmeth);
138                 pn.addChild(pl);
139                 RESULT = pn;
140         :}
141     ;
142 paramlist  ::= paramlist:pl param:p
143         {:
144                 pl.addChild(p);
145                 RESULT = pl;
146         :}
147     | /* empty */
148         {:
149                 ParseNode pn = new ParseNode("param_list");
150                 RESULT = pn;
151         :}
152     ;
153 param      ::= TYPE:typeprm IDENT:idprm COMMA
154         {:
155                 ParseNode pn = new ParseNode("param");
156                 pn.addChild("param_type").setLiteral(typeprm);
157                 pn.addChild("param_ident").setLiteral(idprm);
158                 RESULT = pn;
159         :}
160     | TYPE:typeprm IDENT:idprm
161         {:
162                 ParseNode pn = new ParseNode("param");
163                 pn.addChild("param_type").setLiteral(typeprm);
164                 pn.addChild("param_ident").setLiteral(idprm);
165                 RESULT = pn;
166         :}
167     | IDENT:clsprm IDENT:idprm COMMA
168         {:
169                 ParseNode pn = new ParseNode("param");
170                 pn.addChild("param_class").setLiteral(clsprm);
171                 pn.addChild("param_ident").setLiteral(idprm);
172                 RESULT = pn;
173         :}
174     | IDENT:clsprm IDENT:idprm
175         {:
176                 ParseNode pn = new ParseNode("param");
177                 pn.addChild("param_class").setLiteral(clsprm);
178                 pn.addChild("param_ident").setLiteral(idprm);
179                 RESULT = pn;
180         :}
181         /* generic/template with one type, e.g. set<int> */
182     | IDENT:clsprm LANG TYPE:typegen RANG IDENT:idprm
183         {:
184                 ParseNode pn = new ParseNode("param");
185                 pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + ">");
186                 pn.addChild("param_ident").setLiteral(idprm);
187                 RESULT = pn;
188         :}
189     | IDENT:clsprm LANG IDENT:clsgen RANG IDENT:idprm
190         {:
191                 ParseNode pn = new ParseNode("param");
192                 pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + ">");
193                 pn.addChild("param_ident").setLiteral(idprm);
194                 RESULT = pn;
195         :}
196         /* Add comma at the end... */
197         /* generic/template with one type, e.g. set<int> */
198     | IDENT:clsprm LANG TYPE:typegen RANG IDENT:idprm COMMA
199         {:
200                 ParseNode pn = new ParseNode("param");
201                 pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + ">");
202                 pn.addChild("param_ident").setLiteral(idprm);
203                 RESULT = pn;
204         :}
205     | IDENT:clsprm LANG IDENT:clsgen RANG IDENT:idprm COMMA
206         {:
207                 ParseNode pn = new ParseNode("param");
208                 pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + ">");
209                 pn.addChild("param_ident").setLiteral(idprm);
210                 RESULT = pn;
211         :}
212     ;
213
214 //2) List of capabilities and their respective contents, i.e. description, method, etc.
215 capablist  ::= capablist:cl capab:cap
216         {:
217                 cl.addChild(cap);
218                 RESULT = cl;
219         :}
220         | /* empty */
221         {:
222                 ParseNode pn = new ParseNode("capab_list");
223                 RESULT = pn;
224         :}
225         ;
226 capab      ::= CAPABILITY IDENT:idcap BEGIN capabcont:ccont END
227         {:
228                 ParseNode pn = new ParseNode("capability");
229                 pn.addChild("capab_ident").setLiteral(idcap);
230                 pn.addChild(ccont);
231                 RESULT = pn;
232         :}
233     ;
234 capabcont  ::= capabcont:ccont cont:cnt
235         {:
236                 ccont.addChild(cnt);
237                 RESULT = ccont;
238         :}
239         | /* empty */
240         {:
241                 ParseNode pn = new ParseNode("capab_content");
242                 RESULT = pn;
243         :}
244         ;
245 cont       ::= DESCRIPTION:dsc ASSIGN STRINGCONST:strdsc SEMICOLON
246         {:
247                 ParseNode pn = new ParseNode("capab_content");
248                 pn.addChild("capab_desc").setLiteral(strdsc);
249                 RESULT = pn;
250         :}
251         | METHOD:mtd ASSIGN STRINGCONST:strmeth SEMICOLON
252         {:
253                 ParseNode pn = new ParseNode("capab_content");
254                 pn.addChild("capab_meth").setLiteral(strmeth);
255                 RESULT = pn;
256         :}
257         ;
258
259 //3) List of interface generation definitions ("requires" statements)
260 reqlist    ::= reqlist:rl require:req
261         {:
262                 rl.addChild(req);
263                 RESULT = rl;
264         :}
265         | /* empty */
266         {:
267                 ParseNode pn = new ParseNode("reqlist");
268                 RESULT = pn;
269         :}
270         ;
271 require    ::= REQUIRES IDENT:idint WITH capintlist:cil AS INTERFACE IDENT:idnewint SEMICOLON
272         {:
273                 ParseNode pn = new ParseNode("requires");
274                 pn.addChild("intface_ident").setLiteral(idint);
275                 pn.addChild(cil);
276                 pn.addChild("new_intface_ident").setLiteral(idnewint);
277                 RESULT = pn;
278         :}
279         ;
280 capintlist ::= IDENT:idcap
281         {:
282                 ParseNode pn = new ParseNode("capab_ident_list");
283                 pn.addChild("capab_ident").setLiteral(idcap);
284                 RESULT = pn;
285         :}
286         | capintlist:cil COMMA IDENT:idcap
287         {:
288                 cil.addChild("capab_ident").setLiteral(idcap);
289                 RESULT = cil;
290         :}
291         | /* empty */
292         {:
293                 ParseNode pn = new ParseNode("capab_ident_list");
294                 RESULT = pn;
295         :}
296         ;
297
298 //4) Enumeration declaration
299 enumdec         ::= ENUM IDENT:idenumdec BEGIN enumlist:el END
300         {:
301                 ParseNode pn = new ParseNode("enum_dec");
302                 pn.addChild("enum_dec_ident").setLiteral(idenumdec);
303                 pn.addChild(el);
304                 RESULT = pn;
305         :}
306     ;
307 enumlist        ::= enumlist:el enummem:e
308         {:
309                 el.addChild(e);
310                 RESULT = el;
311         :}
312     | /* empty */
313         {:
314                 ParseNode pn = new ParseNode("enum_list");
315                 RESULT = pn;
316         :}
317     ;
318 enummem         ::= IDENT:idenum COMMA
319         {:
320                 ParseNode pn = new ParseNode("enum_mem");
321                 pn.addChild("enum_ident").setLiteral(idenum);
322                 RESULT = pn;
323         :}
324     | IDENT:idenum
325         {:
326                 ParseNode pn = new ParseNode("enum_mem");
327                 pn.addChild("enum_ident").setLiteral(idenum);
328                 RESULT = pn;
329         :}
330     ;
331
332 //5) Struct declaration
333 structdec       ::= STRUCT IDENT:idstructdec BEGIN structlist:sl END
334         {:
335                 ParseNode pn = new ParseNode("struct_dec");
336                 pn.addChild("struct_dec_ident").setLiteral(idstructdec);
337                 pn.addChild(sl);
338                 RESULT = pn;
339         :}
340     ;
341 structlist      ::= structlist:sl structmem:s
342         {:
343                 sl.addChild(s);
344                 RESULT = sl;
345         :}
346     | /* empty */
347         {:
348                 ParseNode pn = new ParseNode("enum_list");
349                 RESULT = pn;
350         :}
351     ;
352 structmem       ::= TYPE:typestr IDENT:idstr SEMICOLON
353         {:
354                 ParseNode pn = new ParseNode("struct_mem");
355                 pn.addChild("struct_type").setLiteral(typestr);
356                 pn.addChild("struct_ident").setLiteral(idstr);
357                 RESULT = pn;
358         :}
359     | IDENT:clsstr IDENT:idstr SEMICOLON
360         {:
361                 ParseNode pn = new ParseNode("struct_mem");
362                 pn.addChild("struct_class").setLiteral(clsstr);
363                 pn.addChild("struct_ident").setLiteral(idstr);
364                 RESULT = pn;
365         :}
366     | IDENT:clsstr LANG IDENT:clsgen RANG IDENT:idstr SEMICOLON
367         {:
368                 ParseNode pn = new ParseNode("struct_mem");
369                 pn.addChild("struct_class").setLiteral((String)clsstr + "<" + clsgen + ">");
370                 pn.addChild("struct_ident").setLiteral(idstr);
371                 RESULT = pn;
372         :}
373     ;