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