ca38b5facb925cb5208d3bf36b535214c16c3c1f
[cdsspec-compiler.git] / grammer / spec-compiler.jj
1 /* spec-compiler.jj Grammer definition for the specification */
2
3
4 /*
5         SPEC constructs:
6         Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
7         Within there, any line beginning with a "#" is a comment of the annotation.
8         Each constrcut should begin with @Begin and end with @End. Otherwise, the
9         annotation would be considered as normal comments of the source.
10         
11         a) Global construct
12         @Begin
13         @Global_define:
14                 ...
15         @Interface_cluster:
16                 ...
17         @Happens-before:
18                 ...
19         @End
20         
21         b) Interface construct
22         @Begin
23         @Interface: ...
24         @Commit_point_set:
25                 IDENTIFIER | IDENTIFIER ...
26         @Condition: ... (Optional)
27         @HB_Condition:
28                 IDENTIFIER :: <C_CPP_Condition>
29         @HB_Condition: ...
30         @ID: ... (Optional, use default ID)
31         @Check: (Optional)
32                 ...
33         @Action: (Optional)
34                 ...
35         @Post_action: (Optional)
36         @Post_check: (Optional)
37         @End
38
39         c) Potential commit construct
40         @Begin
41         @Potential_commit_point_define: ...
42         @Label: ...
43         @End
44
45         d) Commit point define construct
46         @Begin
47         @Commit_point_define_check: ...
48         @Label: ...
49         @End
50         
51                 OR
52
53         @Begin
54         @Commit_point_define: ...
55         @Potential_commit_point_label: ...
56         @Label: ...
57         @End
58 */
59
60
61
62 options {
63         STATIC = false;
64         JAVA_UNICODE_ESCAPE = true;
65 }
66
67 PARSER_BEGIN(SpecParser)
68 package edu.uci.eecs.specCompiler.grammerParser;
69
70 import java.io.FileInputStream;
71 import java.io.FileNotFoundException;
72 import java.util.ArrayList;
73 import java.util.HashMap;
74 import java.util.HashSet;
75
76 import edu.uci.eecs.specCompiler.specExtraction.Construct;
77 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
78 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
79 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
80 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
81 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
82 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
83
84         public class SpecParser {
85                 public static void main(String[] argvs)
86                 throws ParseException, TokenMgrError {
87                         try {
88                                 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
89                                 SpecParser parser = new SpecParser(fis);
90                                 parser.Start();
91                                 System.out.println("Parsing finished!");
92                         } catch (FileNotFoundException e) {
93                                 e.printStackTrace();
94                         }
95                 }
96         }
97 PARSER_END(SpecParser)
98
99 SKIP :
100 {
101         " "
102 |
103         "\n"
104 |
105         "\r"
106 |
107         "\r\n"
108 |
109         "\t"
110 |
111         // "#" comment for the specification
112         <"#" (~["\n", "\r"])* (["\n", "\r"])>
113 |
114         // "//" comment for the specification
115         <"//" (~["\n", "\r"])* (["\n", "\r"])>
116 }
117
118 TOKEN :
119 {
120 /*   Above are specification-only tokens   */
121         <HEAD: "/**">
122 |
123         <TAIL: "*/">
124 |
125         <BEGIN: "@Begin">
126 |
127         <END: "@End">
128 |
129         <GLOBAL_DEFINE: "@Global_define:">
130 |
131         <INTERFACE_CLUSTER: "@Interface_cluster:">
132 |
133         <HAPPENS_BEFORE: "@Happens_before:">
134 |
135         <INTERFACE: "@Interface:">
136 |
137         <COMMIT_POINT_SET: "@Commit_point_set:">
138 |
139         <CONDITION: "@Condition:">
140 |
141         <HB_CONDITION: "@HB_condition:">
142 |
143         <ID: "@ID:">
144 |
145         <CHECK: "@Check:">
146 |
147         <ACTION: "@Action:">
148 |
149         <POST_ACTION: "@Post_action:">
150 |
151         <POST_CHECK: "@Post_check:">
152 |
153         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
154 |
155         <LABEL: "@Label:">
156 |
157         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
158 |
159         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
160 |
161         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
162
163
164 /*   Specification & C/C++ shared tokens   */
165 |
166         <#DIGIT: ["0"-"9"]>
167 |
168         <#LETTER: ["a"-"z", "A"-"Z"]>
169 |
170         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
171 |
172         <EQUALS: "=">
173 |
174         <OPEN_PAREN: "{">
175 |
176         <CLOSE_PAREN: "}">
177 |
178         <OPEN_BRACKET: "(">
179 |
180         <CLOSE_BRACKET: ")">
181 |
182         <HB_SYMBOL: "->">
183 |
184         <COMMA: ",">
185
186 |
187 /*   C/C++ only token*/
188         <DOT: ".">
189 |
190         <STAR: "*">
191 |
192         <NEGATE: "~">
193 |
194         <AND: "&">
195 |
196         <OR: "|">
197 |
198         <MOD: "%">
199 |
200         <PLUS: "+">
201 |
202         <PLUSPLUS: "++">
203 |
204         <MINUS: "-">
205 |
206         <MINUSMINUS: "--">
207 |
208         <DIVIDE: "/">
209 |
210         <BACKSLASH: "\\">
211 |
212         <LESS_THAN: "<">
213 |
214         <GREATER_THAN: ">">
215 |
216         <GREATER_EQUALS: ">=">
217 |
218         <LESS_EQUALS: "<=">
219 |
220         <LOGICAL_EQUALS: "==">
221 |
222         <NOT_EQUALS: "!=">
223 |
224         <LOGICAL_AND: "&&">
225 |
226         <LOGICAL_OR: "||">
227 |
228         <XOR: "^">
229 |
230         <QUESTION_MARK: "?">
231 |
232         <COLON: ":">
233 |
234         <DOUBLECOLON: "::">
235 |
236         <SEMI_COLON: ";">
237 |
238         <STRING_LITERAL:
239         "\""
240         ((~["\"","\\","\n","\r"])
241         | ("\\"
242                 ( ["n","t","b","r","f","\\","'","\""]
243                 | ["0"-"7"] ( ["0"-"7"] )?
244                 | ["0"-"3"] ["0"-"7"]
245                         ["0"-"7"]
246                 )
247                 )
248         )*
249         "\"">
250 |
251         <CHARACTER_LITERAL:
252         "'"
253         ((~["'","\\","\n","\r"])
254         | ("\\"
255                 (["n","t","b","r","f","\\","'","\""]
256                 | ["0"-"7"] ( ["0"-"7"] )?
257                 | ["0"-"3"] ["0"-"7"]
258                 ["0"-"7"]
259                 )
260                 )
261         )
262         "'">
263 |
264         < INTEGER_LITERAL:
265         <DECIMAL_LITERAL> (["l","L"])?
266       | <HEX_LITERAL> (["l","L"])?
267       | <OCTAL_LITERAL> (["l","L"])?>
268 |
269         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
270 |
271         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
272 |
273         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
274 |
275         < FLOATING_POINT_LITERAL:
276         <DECIMAL_FLOATING_POINT_LITERAL>
277       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
278 |
279         < #DECIMAL_FLOATING_POINT_LITERAL:
280         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
281       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
282       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
283       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
284 |
285         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
286 |
287         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
288         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
289       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
290 |
291         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
292 }
293
294 Construct Start() :
295 {
296         Construct res;  
297 }
298 {
299         (
300         LOOKAHEAD(3) res = Global_construct() |
301         LOOKAHEAD(3) res = Interface() |
302         LOOKAHEAD(3) res = Potential_commit_point_define() |
303         LOOKAHEAD(3) res = Commit_point_define() |
304         LOOKAHEAD(3) res = Commit_point_define_check()
305         )
306         <EOF>
307         {
308                 System.out.println(res);
309                 return res;
310         }
311 }
312
313 GlobalConstruct Global_construct() :
314 {
315         GlobalConstruct res;
316         String code;
317 }
318 {
319         { res = null; }
320         <HEAD>
321                 <BEGIN> 
322                         (code = Global_define())
323                         { res = new GlobalConstruct(code); }
324                         (Interface_clusters(res))?
325                         (Happens_before(res))?
326                 <END>
327         <TAIL>
328         {
329                 res.unfoldInterfaceCluster();
330                 return res;
331         }
332 }
333
334 String C_CPP_CODE() :
335 {
336         StringBuilder text;
337         Token t;
338 }
339 {
340         {
341                 text = new StringBuilder();
342                 t = new Token();
343         }
344         ((
345         t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
346         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
347         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
348         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
349         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
350         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR>
351         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
352         t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
353         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
354         )
355         {
356                 text.append(t.image);
357                 if (t.image.equals(";") || t.image.equals("\\")
358                         || t.image.equals("{") || t.image.equals("}"))
359                         text.append("\n");
360                 else
361                         text.append(" ");
362         }
363         )+
364         {
365                 //System.out.println(text);
366                 return text.toString();
367         }
368 }
369
370 String Global_define() :
371 {
372         String code;    
373 }
374 {
375         <GLOBAL_DEFINE> (code = C_CPP_CODE())
376         {
377                 return code;
378         }
379 }
380
381 ConditionalInterface Conditional_interface() :
382 {
383         String interfaceName, hbConditionLabel;
384 }
385 {
386         {
387                 hbConditionLabel = "";
388         }
389         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
390         <IDENTIFIER>.image <CLOSE_BRACKET>)?
391         {
392                 return new ConditionalInterface(interfaceName, hbConditionLabel);
393         }
394 }
395
396 void Interface_cluster(GlobalConstruct inst) :
397 {
398         String clusterName;
399         ConditionalInterface condInterface;
400 }
401 {
402         (clusterName= <IDENTIFIER>.image)
403         <EQUALS> <OPEN_PAREN>
404                 (condInterface = Conditional_interface()
405                 { inst.addInterface2Cluster(clusterName, condInterface); } 
406                 )
407                 (<COMMA> condInterface = Conditional_interface()
408                 { inst.addInterface2Cluster(clusterName, condInterface); } 
409                 )*
410         <CLOSE_PAREN>
411 }
412
413 void Interface_clusters(GlobalConstruct inst) :
414 {}
415 {
416         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
417 }
418
419 void Happens_before(GlobalConstruct inst) :
420 {
421         ConditionalInterface left, right;       
422 }
423 {
424         <HAPPENS_BEFORE> 
425         (
426         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
427         { inst.addHBCondition(left, right); }
428         )+
429 }
430
431 InterfaceConstruct Interface() :
432 {
433         InterfaceConstruct res;
434         String interfaceName, condition, idCode, check, action, postAction,
435                 postCheck, commitPoint, hbLabel, hbCondition;
436         ArrayList<String> commitPointSet;
437         HashMap<String, String> hbConditions;
438 }
439 {
440         {
441                 res = null;
442                 condition = "";
443                 idCode = "";
444                 check = "";
445                 action = "";
446                 postAction = "";
447                 postCheck = "";
448                 commitPointSet = new ArrayList<String>();
449                 hbConditions = new HashMap<String, String>();
450         }
451         <HEAD> 
452                 <BEGIN>
453                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
454                         <COMMIT_POINT_SET>
455                                 (commitPoint = <IDENTIFIER>.image
456                                 { commitPointSet.add(commitPoint); }
457                                 )
458                                 (<OR>
459                                         (commitPoint = <IDENTIFIER>.image)
460                                         {
461                                                 if (commitPointSet.contains(commitPoint)) {
462                                                         throw new ParseException(interfaceName + " has" +
463                                                                 "duplicate commit point labels");
464                                                 }
465                                                 commitPointSet.add(commitPoint);
466                                         }
467                                 )*
468
469                         (<CONDITION> (condition = C_CPP_CODE()))?
470                         (
471                                 <HB_CONDITION>
472                                 (hbLabel = <IDENTIFIER>.image)
473                                 (hbCondition = C_CPP_CODE())
474                                 {
475                                         if (hbConditions.containsKey(hbLabel)) {
476                                                 throw new ParseException(interfaceName + " has" +
477                                                         "duplicate happens-before condtion labels");
478                                         }
479                                         hbConditions.put(hbLabel, hbCondition);
480                                 }
481                         )*
482                         (<ID> (idCode = C_CPP_CODE()))?
483                         (<CHECK> (check = C_CPP_CODE()))?
484                         (<ACTION> (action = C_CPP_CODE()))?
485                         (<POST_ACTION> (postAction = C_CPP_CODE()))?
486                         (<POST_CHECK> (postCheck = C_CPP_CODE()))?
487                 <END>
488         <TAIL>
489         {
490                 res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
491                         hbConditions, idCode, check, action, postAction, postCheck);
492                 return res;
493         }
494 }
495
496 PotentialCPDefineConstruct Potential_commit_point_define() :
497 {
498         PotentialCPDefineConstruct res;
499         String label, condition;
500 }
501 {
502
503         { res = null; }
504         <HEAD> 
505                 <BEGIN>
506                         <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
507                         <LABEL> (label = <IDENTIFIER>.image)
508                 <END>
509         <TAIL>
510         {
511                 res = new PotentialCPDefineConstruct(label, condition); 
512                 return res;
513         }
514 }
515
516
517 CPDefineConstruct Commit_point_define() :
518 {
519         CPDefineConstruct res;
520         String label, potentialCPLabel, condition;
521 }
522 {
523
524         { res = null; }
525         <HEAD> 
526                 <BEGIN>
527                         <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
528                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
529                         <LABEL> (label = <IDENTIFIER>.image)
530                 <END>
531         <TAIL>
532         {
533                 res = new CPDefineConstruct(label, potentialCPLabel, condition);
534                 return res;
535         }
536 }
537
538
539 CPDefineCheckConstruct Commit_point_define_check() :
540 {
541         CPDefineCheckConstruct res;     
542         String label, condition;
543 }
544 {
545
546         { res = null; }
547         <HEAD> 
548                 <BEGIN> 
549                         <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
550                         <LABEL> (label = <IDENTIFIER>.image)
551                 <END>
552         <TAIL>
553         {
554                 res = new CPDefineCheckConstruct(label, condition);
555                 return res;
556         }
557 }