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