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