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