more edits
[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                 @DeclareStruct:
20                 @DeclareVar:
21                 @InitVar:
22                 @DefineFunc:
23                 ...
24                 @DefineFunc:
25         @Interface_cluster:
26                 ...
27         @Happens_before:
28                 ...
29         @Commutativity: // This is to define the admissibility condition
30                 // Enq <-> Enq (_M1.q != _M2.q)
31                 // Enq <-> Deq (_M1.q != _M2.q)
32                 // Deq <-> Deq (_M1.q != _M2.q)
33                 // Enq <-> Deq (_M1.q == _M2.q && _M2.__RET__ == NULL)
34         @End
35         
36         b) Interface construct
37         @Begin
38         @Interface_decl: ...
39         @Commit_point_set:
40                 IDENTIFIER | IDENTIFIER ...
41         @Condition: ... (Optional)
42         @HB_Condition:
43                 IDENTIFIER :: <C_CPP_Condition>
44         @HB_Condition: ...
45         @ID: ... (Optional, use default ID)
46         @Check: (Optional)
47                 ...
48         @Action: (Optional)
49                 ...
50         @Post_action: (Optional)
51         @Post_check: (Optional)
52         @End
53
54         c) Potential commit construct
55         @Begin
56         @Potential_commit_point_define: ...
57         @Label: ...
58         @End
59
60                 OR
61
62         @Begin
63         @Potential_additional_ordering_point_define: ...
64         @Label: ...
65         @End
66
67         d) Commit point define construct
68         @Begin
69         @Commit_point_define_check: ...
70         @Label: ...
71         @End
72
73                 OR
74         
75         # Addition ordering point is used to order operations when there are "equal"
76         # commit point operations on the same location and that we cannot decide
77         # which operation goes first, we will use additional ordering point to order
78         # them (it's just similar to commit points). In implementation, we can just
79         # treat them as commit points with a special flag.
80
81         @Begin
82         @Additional_ordering_point_define: ...
83         @Potential_additional_ordering_point_label: ...
84         @Label: ...
85         @End
86         
87                 OR
88         
89         @Begin
90         @Additional_ordering_point_define: ...
91         @Label: ...
92         @End
93
94                 OR
95
96         @Begin
97         @Additional_ordering_point_define_check: ...
98         @Label: ...
99         @End
100
101         // Commit point clear (just as a normal commit point, but it is used to
102         // clear all commit points)
103         @Begin
104         @Commit_point_clear: ...
105         @Label: ...
106         @End
107
108         e) Entry point construct
109         @Begin
110         @Entry_point
111         @End
112
113         f) Interface define construct
114         @Begin
115         @Interface_define: <Interface_Name>
116         @End
117
118         g) Interface declare & define construct
119         @Begin
120         @Interface_decl_define: <Interface_Name>
121         @Commit_point_set:
122                 IDENTIFIER | IDENTIFIER ...
123         @Condition: ... (Optional)
124         @HB_Condition:
125                 IDENTIFIER :: <C_CPP_Condition>
126         @HB_Condition: ...
127         @ID: ... (Optional, use default ID)
128         @Check: (Optional)
129                 ...
130         @Action: (Optional)
131                 ...
132         @Post_action: (Optional)
133         @Post_check: (Optional)
134         @End
135
136 */
137
138
139
140 options {
141         STATIC = false;
142         JAVA_UNICODE_ESCAPE = true;
143 }
144
145 PARSER_BEGIN(SpecParser)
146 package edu.uci.eecs.specCompiler.grammerParser;
147
148 import java.io.FileInputStream;
149 import java.io.FileNotFoundException;
150 import java.io.InputStream;
151 import java.io.ByteArrayInputStream;
152 import java.io.File;
153 import java.util.ArrayList;
154 import java.util.HashMap;
155 import java.util.HashSet;
156 import java.util.Arrays;
157
158 import edu.uci.eecs.specCompiler.specExtraction.Construct;
159 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
160 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
161 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
162 import edu.uci.eecs.specCompiler.specExtraction.CommutativityRule;
163 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
164 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
165 import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct;
166 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
167 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
168 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
169 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
170 import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
171 import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
172 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
173 import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
174 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
175 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
176
177         public class SpecParser {
178                 private static ArrayList<String> _content;
179                 private static File _file;
180                 private static ArrayList<Construct> _constructs;
181
182
183                 public static void main(String[] argvs)
184                 throws ParseException, TokenMgrError {
185                         try {
186                                 File f = new File("./grammer/spec1.txt");
187                                 FileInputStream fis = new FileInputStream(f);
188                                 SpecParser parser = new SpecParser(fis);
189                                 
190                                 ArrayList<String> content = new ArrayList<String>();
191                                 ArrayList<Construct> constructs = new ArrayList<Construct>();
192                                 ArrayList<String> headers = new ArrayList<String>();
193                                 parser.Parse(f, content, constructs, headers);
194                                 for (int i = 0; i < content.size(); i++) {
195                                         System.out.println(content.get(i));
196                                 }
197                                 
198                                 for (int i = 0; i < constructs.size(); i++) {
199                                         System.out.println(constructs.get(i));
200                                 }
201                                 
202                                 
203                                 //parser.Test();
204                                 System.out.println("Parsing finished!");
205                         } catch (FileNotFoundException e) {
206                                 e.printStackTrace();
207                         }
208                 }
209
210                 public static SourceFileInfo ParseFile(File f)
211                 throws ParseException, TokenMgrError {
212                         try {
213                                 InputStream input = new FileInputStream(f);
214                                 SpecParser parser = new SpecParser(input);
215                                 ArrayList<String> content = new ArrayList<String>(),
216                                         headers = new ArrayList<String>();
217                                 ArrayList<Construct> constructs = new ArrayList<Construct>();
218                                 parser.Parse(f, content, constructs, headers);
219                                 return new SourceFileInfo(f, content, headers, constructs);
220                         } catch (FileNotFoundException e) {
221                                 e.printStackTrace();
222                         }
223                         return null;
224                 }
225
226
227                 private static ArrayList<String> breakLines(String all) {
228                         String lines[] = all.split("[\\r\\n]+");
229                         return new ArrayList<String>(Arrays.asList(lines));
230                 }
231
232
233                 public static ArrayList<VariableDeclaration> getTemplateArg(String line)
234                 throws ParseException {
235                         InputStream input = new ByteArrayInputStream(line.getBytes());
236                         SpecParser parser = new SpecParser(input);
237                         return parser.TemplateParamList();
238                 }
239
240                 public static FunctionHeader parseFuncHeader(String line)
241                 throws ParseException {
242                         InputStream input = new ByteArrayInputStream(line.getBytes());
243                         SpecParser parser = new SpecParser(input);
244                         return parser.FuncDecl();
245                 }
246
247
248                 public static String stringArray2String(ArrayList<String> content) {
249                         StringBuilder sb = new StringBuilder();
250                         if (content.size() == 1)
251                                 return content.get(0);
252                         for (int i = 0; i < content.size(); i++) {
253                                 sb.append(content.get(i) + "\n");
254                         }
255                         return sb.toString();
256                 }
257
258                 /**
259                 boolean spaceSeparator(Token t) {
260                         switch (t.image) {
261                                 case "[":
262                                 case "]":
263                                 case "=":
264                                 case "(":
265                                 case ")":
266                                 case ",":
267                                 case ".":
268                                 case "*":
269                                 case "~":
270                                 case "!":
271                                 case "&":
272                                 case "|":
273                                 case "%":
274                                 case "+":
275                                 case "-":
276                                 case "/":
277                                 case "<":
278                                 case ">":
279                                 case "<=":
280                                 case ">=":
281                                 case "==":
282                                 case "!=":
283                                 case "&&":
284                                 case "||":
285                                 case "^":
286                                 case "?":
287                                 case ":":
288                                 case "::":
289                                 case "<<":
290                                 case ">>":
291                                 case ">>>":
292                                 case "+=":
293                                 case "-=":
294                                 case "*=":
295                                 case "/=":
296                                 case "%=":
297                                 case "^=":
298                                 case "&=":
299                                 case ";":
300                                         return false;
301                                 default:
302                                         return true;
303                         }
304                 }
305                 */
306
307         }
308 PARSER_END(SpecParser)
309
310
311
312 <IN_POTENTIAL_SPEC, IN_SPEC> SKIP :
313 {
314         " "
315 |
316         "\n"
317 |
318         "\r"
319 |
320         "\r\n"
321 |
322         "\t"
323 }
324
325 SKIP : {
326         "/**" : IN_POTENTIAL_SPEC
327 }
328
329 <IN_POTENTIAL_SPEC> TOKEN : {
330         <BEGIN: "@Begin"> : IN_SPEC
331 }
332
333 <IN_SPEC> SKIP : {
334         "*/" : DEFAULT
335 }
336
337 SKIP : {
338         "/*": IN_COMMENT
339 }
340
341 <DEFAULT> TOKEN: {
342         <ANY: ~[]>
343 }
344
345 <*> SKIP : {
346         // "//" comment for the specification
347         <"//" (~["\n", "\r"])* (["\n", "\r"])>
348 }
349
350 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
351         "*/": DEFAULT
352 }
353
354 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { <  ~[] > }
355
356 <IN_SPEC> SKIP :
357 {
358         // "#" comment for the specification
359         <"#" (~["\n", "\r"])* (["\n", "\r"])>
360 }
361
362
363 <IN_SPEC> TOKEN : {
364         <END: "@End">
365 |
366         <OPTIONS: "@Options:">
367 |
368         <GLOBAL_DEFINE: "@Global_define:">
369 |
370         <DECLARE_STRUCT: "@DeclareStruct:">
371 |
372         <DECLARE_VAR: "@DeclareVar:">
373 |
374         <INIT_VAR: "@InitVar:">
375 |
376         <CLEANUP: "@Finalize:">
377 |
378         <DEFINE_FUNC: "@DefineFunc:">
379 |
380         <INTERFACE_CLUSTER: "@Interface_cluster:">
381 |
382         <HAPPENS_BEFORE: "@Happens_before:">
383 |
384         <COMMUTATIVITY: "@Commutativity:">
385 |
386         <INTERFACE: "@Interface:">
387 |
388         <COMMIT_POINT_SET: "@Commit_point_set:">
389 |
390         <ENTRY_POINT: "@Entry_point">
391 |
392         <CLASS_BEGIN: "@Class_begin">
393 |
394         <CLASS_END: "@Class_end">
395 |
396         <INTERFACE_DEFINE: "@Interface_define:">
397 |
398         <CONDITION: "@Condition:">
399 |
400         <HB_CONDITION: "@HB_condition:">
401 |
402         <ID: "@ID:">
403 |
404         <CHECK: "@Check:">
405 |
406         <ACTION: "@Action:">
407 |
408         <CODE: "@Code:">
409 |
410         <POST_ACTION: "@Post_action:">
411 |
412         <POST_CHECK: "@Post_check:">
413 |
414         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
415 |
416         <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE: "@Potential_additional_ordering_point_define:">
417 |
418         <LABEL: "@Label:">
419 |
420         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
421 |
422         <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK: "@Additional_ordering_point_define_check:">
423 |
424         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
425 |
426         <ADDITIONAL_ORDERING_POINT_DEFINE: "@Additional_ordering_point_define:">
427 |
428         <COMMIT_POINT_CLEAR: "@Commit_point_clear:">
429 |
430         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
431 |
432         <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL: "@Potential_additional_ordering_point_label:">
433 }
434
435
436 <IN_SPEC> TOKEN :
437 {
438 /*   Specification & C/C++ shared tokens   */
439 // Reserved keywords
440         <CONST: "const">
441 |
442         <STRUCT: "struct">
443 |
444         <CLASS: "class">
445 |
446         <UNSIGNED: "unsigned">
447 |
448         <TEMPLATE: "template">
449 |
450         <INLINE: "inline">
451 |
452         <STATIC: "static">
453 |
454         <FOR: "for">
455 |
456         <#DIGIT: ["0"-"9"]>
457 |
458         <#LETTER: ["a"-"z", "A"-"Z"]>
459 |
460         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
461 |
462         <POUND: "#">
463 |
464         <OPEN_BRACKET: "[">
465 |
466         <CLOSE_BRACKET: "]">
467 |
468         <EQUALS: "=">
469 |
470         <OPEN_PAREN: "(">
471 |
472         <CLOSE_PAREN: ")">
473 |
474         <OPEN_BRACE: "{">
475 |
476         <CLOSE_BRACE: "}">
477 |
478         <HB_SYMBOL: "->">
479 |
480         <COMMUTATIVITY_SYMBOL: "<->">
481 |
482         <COMMA: ",">
483 |
484 /*   C/C++ only token*/
485         <DOT: ".">
486 |
487         <DOLLAR: "$">
488 |
489         <STAR: "*">
490 |
491         <NEGATE: "~">
492 |
493         <EXCLAMATION: "!">
494 |
495         <AND: "&">
496 |
497         <OR: "|">
498 |
499         <MOD: "%">
500 |
501         <PLUS: "+">
502 |
503         <PLUSPLUS: "++">
504 |
505         <MINUS: "-">
506 |
507         <MINUSMINUS: "--">
508 |
509         <DIVIDE: "/">
510 |
511         <BACKSLASH: "\\">
512 |
513         <LESS_THAN: "<">
514 |
515         <GREATER_THAN: ">">
516 |
517         <GREATER_EQUALS: ">=">
518 |
519         <LESS_EQUALS: "<=">
520 |
521         <LOGICAL_EQUALS: "==">
522 |
523         <NOT_EQUALS: "!=">
524 |
525         <LOGICAL_AND: "&&">
526 |
527         <LOGICAL_OR: "||">
528 |
529         <XOR: "^">
530 |
531         <QUESTION_MARK: "?">
532 |
533         <COLON: ":">
534 |
535         <DOUBLECOLON: "::">
536 |
537         <DOUBLELESSTHAN: "<<">
538 |
539         <DOUBLEGREATERTHAN: ">>">
540 |
541         <TRIPLEGREATERTHAN: ">>>">
542 |
543         <PLUS_EQUALS: "+=">
544 |
545         <MINUS_EQUALS: "-=">
546 |
547         <TIMES_EQUALS: "*=">
548 |
549         <DIVIDE_EQUALS: "/=">
550 |
551         <MOD_EQUALS: "%=">
552 |
553         <XOR_EQUALS: "^=">
554 |
555         <OR_EQUALS: "|=">
556 |
557         <AND_EQUALS: "&=">
558 |
559         <SEMI_COLON: ";">
560 |
561         <STRING_LITERAL:
562         "\""
563         ((~["\"","\\","\n","\r"])
564         | ("\\"
565                 ( ["n","t","b","r","f","\\","'","\""]
566                 | ["0"-"7"] ( ["0"-"7"] )?
567                 | ["0"-"3"] ["0"-"7"]
568                         ["0"-"7"]
569                 )
570                 )
571         )*
572         "\"">
573 |
574         <CHARACTER_LITERAL:
575         "'"
576         ((~["'","\\","\n","\r"])
577         | ("\\"
578                 (["n","t","b","r","f","\\","'","\""]
579                 | ["0"-"7"] ( ["0"-"7"] )?
580                 | ["0"-"3"] ["0"-"7"]
581                 ["0"-"7"]
582                 )
583                 )
584         )
585         "'">
586 |
587         < INTEGER_LITERAL:
588         <DECIMAL_LITERAL> (["l","L"])?
589       | <HEX_LITERAL> (["l","L"])?
590       | <OCTAL_LITERAL> (["l","L"])?>
591 |
592         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
593 |
594         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
595 |
596         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
597 |
598         < FLOATING_POINT_LITERAL:
599         <DECIMAL_FLOATING_POINT_LITERAL>
600       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
601 |
602         < #DECIMAL_FLOATING_POINT_LITERAL:
603         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
604       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
605       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
606       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
607 |
608         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
609 |
610         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
611         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
612       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
613 |
614         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
615 |
616         < #SPACE: (" " | "\t")+>
617 |
618         < #TO_END_OF_LINE: (~["\n"])+>
619 |
620         /* Macro token */
621         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
622 |
623         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
624 }
625
626 String Type() :
627 {
628         String type;
629         String str;
630         QualifiedName name;
631 }
632 {
633         { type = ""; }
634         (<CONST>
635         { type = "const"; }
636         )?
637         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
638         (
639         name = ParseQualifiedName() {
640                 if (!type.equals(""))
641                         type = type + " " + name.fullName;
642                 else
643                         type = name.fullName;
644         })
645         )
646         ((str = <CONST>.image {
647                 if (!type.equals(""))
648                         type = type + " " + str;
649                 else
650                         type = str;
651         }) |
652         (str = <STAR>.image {
653                 if (!type.equals(""))
654                         type = type + " " + str;
655                 else
656                         type = str;
657         }) |
658         (str = <AND>.image {
659                 if (!type.equals(""))
660                         type = type + " " + str;
661                 else
662                         type = str;
663         })
664         )*
665         {
666                 return type;
667         }
668 }
669
670
671 String ParameterizedName() :
672 {
673         String res = "";
674         String str;
675 }
676 {
677         (str = <IDENTIFIER>.image {res = str;})
678         (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
679         (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
680         { res = res + ">"; }
681         )?
682         {
683                 return res;
684         }
685 }
686
687 FunctionHeader FuncDecl() :
688 {
689         String ret;
690         QualifiedName funcName;
691         ArrayList<VariableDeclaration> args;
692 }
693 {
694         (<STATIC> | <INLINE>)*
695         ret = Type() 
696         funcName = ParseQualifiedName() 
697         args = FormalParamList() 
698         {
699                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
700                 //System.out.println(res);
701                 return res;
702         }
703 }
704
705 QualifiedName ParseQualifiedName() :
706 {
707         String qualifiedName, str;
708 }
709 {
710         { qualifiedName = ""; }
711         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
712         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
713         "::" + str; }  ))*
714         {
715                 QualifiedName res = new QualifiedName(qualifiedName);
716                 //System.out.println(res);
717                 return res;
718         }
719 }
720
721 ArrayList<VariableDeclaration> TemplateParamList() :
722 {
723         ArrayList<VariableDeclaration> params;
724         String type;
725         String name;
726 }
727 {
728         {
729                 params = new ArrayList<VariableDeclaration>();
730         }
731         <TEMPLATE>
732         <OPEN_BRACKET>
733         (type = <IDENTIFIER>.image 
734         name = <IDENTIFIER>.image
735         {
736                 params.add(new VariableDeclaration(type, name));
737         }
738         )
739
740         (<COMMA> type = <IDENTIFIER>.image 
741         name = <IDENTIFIER>.image
742         {
743                 params.add(new VariableDeclaration(type, name));
744         }
745         )*
746         <CLOSE_BRACKET>
747         {
748                 //System.out.println(params);
749                 return params;
750         }
751 }
752
753 ArrayList<VariableDeclaration > FormalParamList() :
754 {
755         ArrayList<VariableDeclaration > typeParams;
756         VariableDeclaration varDecl;
757 }
758 {
759         {
760                 typeParams = new ArrayList<VariableDeclaration >();
761         }
762         <OPEN_PAREN>
763         ((varDecl = TypeParam() {typeParams.add(varDecl);})
764         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
765         <CLOSE_PAREN>
766         {
767                 return typeParams;
768         }
769 }
770
771 VariableDeclaration TypeParam() :
772 {
773         String type, param;
774 }
775 {
776         (type = Type()) (param = <IDENTIFIER>.image)
777         {
778                 return new VariableDeclaration(type, param);
779         }
780 }
781
782
783
784 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
785 {
786         String text;
787         Token t;
788         boolean newLine = false;
789         boolean newSpace = true;
790         boolean inTemplate = false;
791         boolean inForLoop = false;
792         ArrayList<String> content;
793         String header;
794 }
795 {
796         {
797                 text = "";
798                 t = new Token();
799                 content = new ArrayList<String>();
800         }
801         (
802         LOOKAHEAD(2)
803         (
804         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
805         (t = <TEMPLATE> { inTemplate = true;  })|
806         t = <STATIC> | t = <INLINE> |
807         (t = <FOR> { inForLoop = true; })|
808         (t = <INCLUDE>
809         {
810                 header = t.image;
811                 newLine = true;
812                 if (headers != null) {
813                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
814                 }
815         })
816         | t = <IDENTIFIER> | t = <POUND> |
817         (t = <OPEN_BRACE>  { newLine = true; } ) |
818         (t = <CLOSE_BRACE>  { newLine = true; inForLoop = false;} ) | 
819         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
820         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
821         | t = <HB_SYMBOL> | t = <COMMA> |
822         t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
823         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
824         t = <LESS_THAN> |
825         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
826         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
827         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
828         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
829         t = <DOUBLELESSTHAN> | 
830         t = <DOUBLEGREATERTHAN> |
831         t = <TRIPLEGREATERTHAN> | 
832
833         t = <PLUS_EQUALS> |
834         t = <MINUS_EQUALS> |
835         t = <TIMES_EQUALS> |
836         t = <DIVIDE_EQUALS> |
837         t = <MOD_EQUALS> |
838         t = <XOR_EQUALS> |
839         t = <OR_EQUALS> |
840         t = <AND_EQUALS> |
841
842         (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
843         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
844         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
845         (t = <DEFINE> { newLine = true; } )
846         )
847         {
848                 if (text.equals("")) {
849                         text = t.image;
850                         newSpace = true;
851                 } else {
852                         text = text + " " + t.image;
853                         /*
854                         if (newSpace && spaceSeparator(t)) {
855                                 text = text + " " + t.image;
856                         } else {
857                                 text = text + t.image;
858                                 if (spaceSeparator(t))
859                                         newSpace = true;
860                         }*/
861                 }
862                 if (newLine) {
863                         content.add(text);
864                         text = "";
865                         newLine = false;
866                         inTemplate = false;
867                 }
868         }
869         )+
870
871         {
872                 if (content.size() == 0) {
873                         content.add(text);
874                 }
875                 return content;
876         }
877 }
878
879
880 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
881 {
882         Construct inst;
883         StringBuilder sb;
884         boolean flushSB;
885 }
886 {
887         {
888                 _file = f;
889                 _content = content;
890                 _constructs = constructs;
891                 sb = new StringBuilder();
892         }
893         (
894         (inst = ParseSpec()
895         {
896                 _constructs.add(inst);
897         }
898         ) |
899         //((code = C_CPP_CODE(headers)) { _content.addAll(code); })
900         (
901         flushSB = OriginalCode(sb)
902         {
903                 if (flushSB) {
904                         sb = new StringBuilder();
905                 }
906         }
907         )
908         )* 
909         // For the last piece of code
910         {
911                 _content.add(sb.toString());
912         }
913         <EOF>
914 }
915
916 // If true, there's a new line and sb should be flushed
917 boolean OriginalCode(StringBuilder sb) :
918 {
919         String str;
920 }
921 {
922         str = <ANY>.image
923         {
924                 if (!str.equals("\n")) {
925                         sb.append(str);
926                         return false;
927                 } else {
928                         _content.add(sb.toString());
929                         return true;
930                 }
931         }
932 }
933
934 Construct ParseSpec() :
935 {
936         Construct res;  
937 }
938 {
939         (
940         LOOKAHEAD(2) res = Global_construct() |
941         LOOKAHEAD(2) res = Interface() |
942         LOOKAHEAD(2) res = Potential_commit_point_define() |
943         LOOKAHEAD(2) res = Commit_point_define() |
944         LOOKAHEAD(2) res = Commit_point_define_check() |
945         LOOKAHEAD(2) res = Potential_additional_ordering_point_define() |
946         LOOKAHEAD(2) res = Additional_ordering_point_define() |
947         LOOKAHEAD(2) res = Additional_ordering_point_define_check() |
948         LOOKAHEAD(2) res = Commit_point_clear() |
949         LOOKAHEAD(2) res = Entry_point() |
950         LOOKAHEAD(2) res = Class_begin() |
951         LOOKAHEAD(2) res = Class_end() |
952         LOOKAHEAD(2) res = Interface_define()
953         )
954         {
955                 //System.out.println(res);
956                 return res;
957         }
958 }
959
960 GlobalConstruct Global_construct() :
961 {
962         GlobalConstruct res;
963         SequentialDefineSubConstruct code;
964         HashMap<String, String> options;
965         String key, value;
966 }
967 {
968         {
969                 res = null;
970                 options = new HashMap<String, String>();
971         }
972                 <BEGIN> 
973                         (<OPTIONS>
974                                 ((key = <IDENTIFIER>.image)
975                                 <EQUALS>
976                                 (value = <IDENTIFIER>.image)
977                                 {
978                                         if (options.containsKey(key)) {
979                                                 throw new ParseException("Duplicate options!");
980                                         }
981                                         options.put(key, value);
982                                 }
983                                 <SEMI_COLON>
984                                 )*
985                         )?
986                         (code = Global_define())
987                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
988                         (Interface_clusters(res))?
989                         (Happens_before(res))?
990                         (Commutativity(res))?
991                 <END>
992         {
993                 res.unfoldInterfaceCluster();
994                 return res;
995         }
996 }
997
998 SequentialDefineSubConstruct Global_define() :
999 {
1000         ArrayList<String> initVar, cleanup, defineFunc, code, declareStruct;
1001         ArrayList<ArrayList<String>> defineFuncs;
1002         ArrayList<VariableDeclaration> declareVars;
1003         ArrayList<ArrayList<String>> declareStructs;
1004         VariableDeclaration declareVar;
1005
1006 }
1007 {
1008         {
1009                 declareVars = new ArrayList<VariableDeclaration>();
1010                 initVar = new ArrayList<String>();
1011                 cleanup = new ArrayList<String>();
1012                 defineFuncs = new ArrayList<ArrayList<String>>();
1013                 declareStructs = new ArrayList<ArrayList<String>>();
1014         }
1015         <GLOBAL_DEFINE>
1016         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
1017                 declareStructs.add(declareStruct); }))*
1018                 (<DECLARE_VAR> ((declareVar = TypeParam() <SEMI_COLON> {
1019                         declareVars.add(declareVar); } )*))?
1020         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
1021         (<CLEANUP> (code = C_CPP_CODE(null) { cleanup = code; } ))?
1022         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
1023         {
1024                 SequentialDefineSubConstruct res = new
1025                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, cleanup, defineFuncs);
1026                 //System.out.println(res);
1027                 return res;
1028         }
1029 }
1030
1031 ConditionalInterface Conditional_interface() :
1032 {
1033         String interfaceName, hbConditionLabel;
1034 }
1035 {
1036         {
1037                 hbConditionLabel = "";
1038         }
1039         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
1040         <IDENTIFIER>.image <CLOSE_PAREN>)?
1041         {
1042                 return new ConditionalInterface(interfaceName, hbConditionLabel);
1043         }
1044 }
1045
1046 void Interface_cluster(GlobalConstruct inst) :
1047 {
1048         String clusterName;
1049         ConditionalInterface condInterface;
1050 }
1051 {
1052         (clusterName= <IDENTIFIER>.image)
1053         <EQUALS> <OPEN_BRACE>
1054                 (condInterface = Conditional_interface()
1055                 { inst.addInterface2Cluster(clusterName, condInterface); } 
1056                 )
1057                 (<COMMA> condInterface = Conditional_interface()
1058                 { inst.addInterface2Cluster(clusterName, condInterface); } 
1059                 )*
1060         <CLOSE_BRACE>
1061 }
1062
1063 void Interface_clusters(GlobalConstruct inst) :
1064 {}
1065 {
1066         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
1067 }
1068
1069 void Happens_before(GlobalConstruct inst) :
1070 {
1071         ConditionalInterface left, right;       
1072 }
1073 {
1074         <HAPPENS_BEFORE> 
1075         (
1076         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
1077         { inst.addHBCondition(left, right); }
1078         )+
1079 }
1080
1081 void Commutativity(GlobalConstruct inst) :
1082 {
1083         String method1, method2, condition;
1084         ArrayList<String> content;
1085 }
1086 {
1087         {
1088                 content = new ArrayList<String>();
1089         }
1090
1091         (
1092         <COMMUTATIVITY>
1093         method1 = <IDENTIFIER>.image  <COMMUTATIVITY_SYMBOL>
1094         method2 = <IDENTIFIER>.image
1095         <COLON>
1096         content = C_CPP_CODE(null)
1097         { condition = stringArray2String(content); }
1098         {
1099                 inst.addCommutativityRule(method1, method2, condition);
1100         }
1101         )+
1102 }
1103
1104 InterfaceConstruct Interface() :
1105 {
1106         InterfaceConstruct res;
1107         String interfaceName, condition, idCode, check,
1108                 postCheck, commitPoint, hbLabel, hbCondition;
1109         ArrayList<String> commitPointSet;
1110         ArrayList<String> action, postAction;
1111         HashMap<String, String> hbConditions;
1112         ArrayList<String> content;
1113 }
1114 {
1115         {
1116                 res = null;
1117                 action = new ArrayList<String>();
1118                 condition = "";
1119                 idCode = "";
1120                 check = "";
1121                 postCheck = "";
1122                 commitPointSet = new ArrayList<String>();
1123                 hbConditions = new HashMap<String, String>();
1124                 postAction = new ArrayList<String>();
1125         }
1126                 <BEGIN>
1127                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1128                         <COMMIT_POINT_SET>
1129                                 (commitPoint = <IDENTIFIER>.image
1130                                 { commitPointSet.add(commitPoint); }
1131                                 )
1132                                 (<OR>
1133                                         (commitPoint = <IDENTIFIER>.image)
1134                                         {
1135                                                 if (commitPointSet.contains(commitPoint)) {
1136                                                         throw new ParseException(interfaceName + " has" +
1137                                                                 "duplicate commit point labels");
1138                                                 }
1139                                                 commitPointSet.add(commitPoint);
1140                                         }
1141                                 )*
1142
1143                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1144                         (
1145                                 <HB_CONDITION>
1146                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1147                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1148                                 {
1149                                         if (hbConditions.containsKey(hbLabel)) {
1150                                                 throw new ParseException(interfaceName + " has" +
1151                                                         "duplicate happens-before condtion labels");
1152                                         }
1153                                         hbConditions.put(hbLabel, hbCondition);
1154                                 }
1155                         )*
1156                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1157                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1158                         (<ACTION> action = C_CPP_CODE(null))?
1159                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1160                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1161                 <END>
1162         {
1163                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1164                         hbConditions, idCode, check, action, postAction, postCheck);
1165                 return res;
1166         }
1167 }
1168
1169
1170 PotentialCPDefineConstruct Potential_commit_point_define() :
1171 {
1172         PotentialCPDefineConstruct res;
1173         String label, condition;
1174         ArrayList<String> content;
1175 }
1176 {
1177
1178         { res = null; }
1179                 <BEGIN>
1180                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1181                         <LABEL> (label = <IDENTIFIER>.image)
1182                 <END>
1183         {
1184                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
1185                 return res;
1186         }
1187 }
1188
1189 PotentialCPDefineConstruct Potential_additional_ordering_point_define() :
1190 {
1191         PotentialCPDefineConstruct res;
1192         String label, condition;
1193         ArrayList<String> content;
1194 }
1195 {
1196
1197         { res = null; }
1198                 <BEGIN>
1199                         <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1200                         <LABEL> (label = <IDENTIFIER>.image)
1201                 <END>
1202         {
1203                 // Set the boolean flag isAdditionalOrderingPoint to be true
1204                 res = new PotentialCPDefineConstruct(_file, _content.size(), true, label, condition); 
1205                 return res;
1206         }
1207 }
1208
1209
1210 CPDefineConstruct Commit_point_define() :
1211 {
1212         CPDefineConstruct res;
1213         String label, potentialCPLabel, condition;
1214         ArrayList<String> content;
1215 }
1216 {
1217
1218         { res = null; }
1219                 <BEGIN>
1220                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1221                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1222                         <LABEL> (label = <IDENTIFIER>.image)
1223                 <END>
1224         {
1225                 res = new CPDefineConstruct(_file, _content.size(), false, label, potentialCPLabel, condition);
1226                 return res;
1227         }
1228 }
1229
1230 CPDefineConstruct Additional_ordering_point_define() :
1231 {
1232         CPDefineConstruct res;
1233         String label, potentialCPLabel, condition;
1234         ArrayList<String> content;
1235 }
1236 {
1237
1238         { res = null; }
1239                 <BEGIN>
1240                         <ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1241                         <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1242                         <LABEL> (label = <IDENTIFIER>.image)
1243                 <END>
1244         {
1245                 // Set the boolean flag isAdditionalOrderingPoint to be true
1246                 res = new CPDefineConstruct(_file, _content.size(), true, label, potentialCPLabel, condition);
1247                 return res;
1248         }
1249 }
1250
1251 CPClearConstruct Commit_point_clear() :
1252 {
1253         CPClearConstruct res;   
1254         String label, condition;
1255         ArrayList<String> content;
1256 }
1257 {
1258
1259         { res = null; }
1260                 <BEGIN> 
1261                         <COMMIT_POINT_CLEAR> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1262                         <LABEL> (label = <IDENTIFIER>.image)
1263                 <END>
1264         {
1265                 res = new CPClearConstruct(_file, _content.size(), label, condition);
1266                 return res;
1267         }
1268 }
1269
1270
1271 CPDefineCheckConstruct Commit_point_define_check() :
1272 {
1273         CPDefineCheckConstruct res;     
1274         String label, condition;
1275         ArrayList<String> content;
1276 }
1277 {
1278
1279         { res = null; }
1280                 <BEGIN> 
1281                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1282                         <LABEL> (label = <IDENTIFIER>.image)
1283                 <END>
1284         {
1285                 res = new CPDefineCheckConstruct(_file, _content.size(), false, label, condition);
1286                 return res;
1287         }
1288 }
1289
1290 CPDefineCheckConstruct Additional_ordering_point_define_check() :
1291 {
1292         CPDefineCheckConstruct res;     
1293         String label, condition;
1294         ArrayList<String> content;
1295 }
1296 {
1297
1298         { res = null; }
1299                 <BEGIN> 
1300                         <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1301                         <LABEL> (label = <IDENTIFIER>.image)
1302                 <END>
1303         {
1304                 // Set the boolean flag isAdditionalOrderingPoint to be true
1305                 res = new CPDefineCheckConstruct(_file, _content.size(), true, label, condition);
1306                 return res;
1307         }
1308 }
1309
1310 EntryPointConstruct Entry_point() :
1311 {}
1312 {
1313
1314                 <BEGIN> 
1315                         <ENTRY_POINT>
1316                 <END>
1317         {
1318                 return new EntryPointConstruct(_file, _content.size());
1319         }
1320 }
1321
1322 ClassBeginConstruct Class_begin() :
1323 {}
1324 {
1325
1326                 <BEGIN> 
1327                         <CLASS_BEGIN>
1328                 <END>
1329         {
1330                 return new ClassBeginConstruct(_file, _content.size());
1331         }
1332 }
1333
1334 ClassEndConstruct Class_end() :
1335 {}
1336 {
1337
1338                 <BEGIN> 
1339                         <CLASS_END>
1340                 <END>
1341         {
1342                 return new ClassEndConstruct(_file, _content.size());
1343         }
1344 }
1345
1346 InterfaceDefineConstruct Interface_define() :
1347 {
1348         String name;    
1349 }
1350 {
1351                 <BEGIN>
1352                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1353                 <END>
1354         {
1355                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1356         }
1357 }