save more
[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
614 String ParameterizedName() :
615 {
616         String res = "";
617         String str;
618 }
619 {
620         (str = <IDENTIFIER>.image {res = str;})
621         (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
622         (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
623         { res = res + ">"; }
624         )?
625         {
626                 return res;
627         }
628 }
629
630 FunctionHeader FuncDecl() :
631 {
632         String ret;
633         QualifiedName funcName;
634         ArrayList<VariableDeclaration> args;
635 }
636 {
637         (<STATIC> | <INLINE>)*
638         ret = Type() 
639         funcName = ParseQualifiedName() 
640         args = FormalParamList() 
641         {
642                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
643                 //System.out.println(res);
644                 return res;
645         }
646 }
647
648 QualifiedName ParseQualifiedName() :
649 {
650         String qualifiedName, str;
651 }
652 {
653         { qualifiedName = ""; }
654         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
655         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
656         "::" + str; }  ))*
657         {
658                 QualifiedName res = new QualifiedName(qualifiedName);
659                 //System.out.println(res);
660                 return res;
661         }
662 }
663
664 ArrayList<VariableDeclaration> TemplateParamList() :
665 {
666         ArrayList<VariableDeclaration> params;
667         String type;
668         String name;
669 }
670 {
671         {
672                 params = new ArrayList<VariableDeclaration>();
673         }
674         <TEMPLATE>
675         <OPEN_BRACKET>
676         (type = <IDENTIFIER>.image 
677         name = <IDENTIFIER>.image
678         {
679                 params.add(new VariableDeclaration(type, name));
680         }
681         )
682
683         (<COMMA> type = <IDENTIFIER>.image 
684         name = <IDENTIFIER>.image
685         {
686                 params.add(new VariableDeclaration(type, name));
687         }
688         )*
689         <CLOSE_BRACKET>
690         {
691                 //System.out.println(params);
692                 return params;
693         }
694 }
695
696 ArrayList<VariableDeclaration > FormalParamList() :
697 {
698         ArrayList<VariableDeclaration > typeParams;
699         VariableDeclaration varDecl;
700 }
701 {
702         {
703                 typeParams = new ArrayList<VariableDeclaration >();
704         }
705         <OPEN_PAREN>
706         ((varDecl = TypeParam() {typeParams.add(varDecl);})
707         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
708         <CLOSE_PAREN>
709         {
710                 return typeParams;
711         }
712 }
713
714 VariableDeclaration TypeParam() :
715 {
716         String type, param;
717 }
718 {
719         (type = Type()) (param = <IDENTIFIER>.image)
720         {
721                 return new VariableDeclaration(type, param);
722         }
723 }
724
725
726
727 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
728 {
729         String text;
730         Token t;
731         boolean newLine = false;
732         boolean newSpace = true;
733         boolean inTemplate = false;
734         boolean inForLoop = false;
735         ArrayList<String> content;
736         String header;
737 }
738 {
739         {
740                 text = "";
741                 t = new Token();
742                 content = new ArrayList<String>();
743         }
744         (
745         LOOKAHEAD(2)
746         (
747         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
748         (t = <TEMPLATE> { inTemplate = true;  })|
749         t = <STATIC> | t = <INLINE> |
750         (t = <FOR> { inForLoop = true; })|
751         (t = <INCLUDE>
752         {
753                 header = t.image;
754                 newLine = true;
755                 if (headers != null) {
756                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
757                 }
758         })
759         | t = <IDENTIFIER> | t = <POUND> |
760         (t = <OPEN_BRACE>  { newLine = true; } ) |
761         (t = <CLOSE_BRACE>  { newLine = true; inForLoop = false;} ) | 
762         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
763         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
764         | t = <HB_SYMBOL> | t = <COMMA> |
765         t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
766         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
767         t = <LESS_THAN> |
768         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
769         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
770         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
771         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
772         t = <DOUBLELESSTHAN> | 
773         t = <DOUBLEGREATERTHAN> |
774         t = <TRIPLEGREATERTHAN> | 
775
776         t = <PLUS_EQUALS> |
777         t = <MINUS_EQUALS> |
778         t = <TIMES_EQUALS> |
779         t = <DIVIDE_EQUALS> |
780         t = <MOD_EQUALS> |
781         t = <XOR_EQUALS> |
782         t = <OR_EQUALS> |
783         t = <AND_EQUALS> |
784
785         (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
786         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
787         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
788         (t = <DEFINE> { newLine = true; } )
789         )
790         {
791                 if (text.equals("")) {
792                         text = t.image;
793                         newSpace = true;
794                 } else {
795                         text = text + " " + t.image;
796                         /*
797                         if (newSpace && spaceSeparator(t)) {
798                                 text = text + " " + t.image;
799                         } else {
800                                 text = text + t.image;
801                                 if (spaceSeparator(t))
802                                         newSpace = true;
803                         }*/
804                 }
805                 if (newLine) {
806                         content.add(text);
807                         text = "";
808                         newLine = false;
809                         inTemplate = false;
810                 }
811         }
812         )+
813
814         {
815                 if (content.size() == 0) {
816                         content.add(text);
817                 }
818                 return content;
819         }
820 }
821
822
823 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
824 {
825         Construct inst;
826         StringBuilder sb;
827         boolean flushSB;
828 }
829 {
830         {
831                 _file = f;
832                 _content = content;
833                 _constructs = constructs;
834                 sb = new StringBuilder();
835         }
836         (
837         (inst = ParseSpec()
838         {
839                 _constructs.add(inst);
840         }
841         ) |
842         //((code = C_CPP_CODE(headers)) { _content.addAll(code); })
843         (
844         flushSB = OriginalCode(sb)
845         {
846                 if (flushSB) {
847                         sb = new StringBuilder();
848                 }
849         }
850         )
851         )* 
852         // For the last piece of code
853         {
854                 _content.add(sb.toString());
855         }
856         <EOF>
857 }
858
859 // If true, there's a new line and sb should be flushed
860 boolean OriginalCode(StringBuilder sb) :
861 {
862         String str;
863 }
864 {
865         str = <ANY>.image
866         {
867                 if (!str.equals("\n")) {
868                         sb.append(str);
869                         return false;
870                 } else {
871                         _content.add(sb.toString());
872                         return true;
873                 }
874         }
875 }
876
877 Construct ParseSpec() :
878 {
879         Construct res;  
880 }
881 {
882         (
883         LOOKAHEAD(2) res = Global_construct() |
884         LOOKAHEAD(2) res = Interface() |
885         LOOKAHEAD(2) res = Potential_commit_point_define() |
886         LOOKAHEAD(2) res = Commit_point_define() |
887         LOOKAHEAD(2) res = Commit_point_define_check() |
888         LOOKAHEAD(2) res = Entry_point() |
889         LOOKAHEAD(2) res = Class_begin() |
890         LOOKAHEAD(2) res = Class_end() |
891         LOOKAHEAD(2) res = Interface_define()
892         )
893         {
894                 //System.out.println(res);
895                 return res;
896         }
897 }
898
899 GlobalConstruct Global_construct() :
900 {
901         GlobalConstruct res;
902         SequentialDefineSubConstruct code;
903         HashMap<String, String> options;
904         String key, value;
905 }
906 {
907         {
908                 res = null;
909                 options = new HashMap<String, String>();
910         }
911                 <BEGIN> 
912                         (<OPTIONS>
913                                 ((key = <IDENTIFIER>.image)
914                                 <EQUALS>
915                                 (value = <IDENTIFIER>.image)
916                                 {
917                                         if (options.containsKey(key)) {
918                                                 throw new ParseException("Duplicate options!");
919                                         }
920                                         options.put(key, value);
921                                 }
922                                 <SEMI_COLON>
923                                 )*
924                         )?
925                         (code = Global_define())
926                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
927                         (Interface_clusters(res))?
928                         (Happens_before(res))?
929                 <END>
930         {
931                 res.unfoldInterfaceCluster();
932                 return res;
933         }
934 }
935
936 SequentialDefineSubConstruct Global_define() :
937 {
938         ArrayList<String> initVar, defineFunc, code, declareStruct;
939         ArrayList<ArrayList<String>> defineFuncs;
940         ArrayList<VariableDeclaration> declareVars;
941         ArrayList<ArrayList<String>> declareStructs;
942         VariableDeclaration declareVar;
943
944 }
945 {
946         {
947                 declareVars = new ArrayList<VariableDeclaration>();
948                 initVar = null;
949                 defineFuncs = new ArrayList<ArrayList<String>>();
950                 declareStructs = new ArrayList<ArrayList<String>>();
951         }
952         <GLOBAL_DEFINE>
953         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
954                 declareStructs.add(declareStruct); }))*
955                 (<DECLARE_VAR> ((declareVar = TypeParam() <SEMI_COLON> {
956                         declareVars.add(declareVar); } )*))?
957         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
958         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
959         {
960                 SequentialDefineSubConstruct res = new
961                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
962                 //System.out.println(res);
963                 return res;
964         }
965 }
966
967 ConditionalInterface Conditional_interface() :
968 {
969         String interfaceName, hbConditionLabel;
970 }
971 {
972         {
973                 hbConditionLabel = "";
974         }
975         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
976         <IDENTIFIER>.image <CLOSE_PAREN>)?
977         {
978                 return new ConditionalInterface(interfaceName, hbConditionLabel);
979         }
980 }
981
982 void Interface_cluster(GlobalConstruct inst) :
983 {
984         String clusterName;
985         ConditionalInterface condInterface;
986 }
987 {
988         (clusterName= <IDENTIFIER>.image)
989         <EQUALS> <OPEN_BRACE>
990                 (condInterface = Conditional_interface()
991                 { inst.addInterface2Cluster(clusterName, condInterface); } 
992                 )
993                 (<COMMA> condInterface = Conditional_interface()
994                 { inst.addInterface2Cluster(clusterName, condInterface); } 
995                 )*
996         <CLOSE_BRACE>
997 }
998
999 void Interface_clusters(GlobalConstruct inst) :
1000 {}
1001 {
1002         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
1003 }
1004
1005 void Happens_before(GlobalConstruct inst) :
1006 {
1007         ConditionalInterface left, right;       
1008 }
1009 {
1010         <HAPPENS_BEFORE> 
1011         (
1012         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
1013         { inst.addHBCondition(left, right); }
1014         )+
1015 }
1016
1017 InterfaceConstruct Interface() :
1018 {
1019         InterfaceConstruct res;
1020         String interfaceName, condition, idCode, check,
1021                 postCheck, commitPoint, hbLabel, hbCondition;
1022         ArrayList<String> commitPointSet;
1023         ArrayList<String> action, postAction;
1024         HashMap<String, String> hbConditions;
1025         ArrayList<String> content;
1026 }
1027 {
1028         {
1029                 res = null;
1030                 action = new ArrayList<String>();
1031                 condition = "";
1032                 idCode = "";
1033                 check = "";
1034                 postCheck = "";
1035                 commitPointSet = new ArrayList<String>();
1036                 hbConditions = new HashMap<String, String>();
1037                 postAction = new ArrayList<String>();
1038         }
1039                 <BEGIN>
1040                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1041                         <COMMIT_POINT_SET>
1042                                 (commitPoint = <IDENTIFIER>.image
1043                                 { commitPointSet.add(commitPoint); }
1044                                 )
1045                                 (<OR>
1046                                         (commitPoint = <IDENTIFIER>.image)
1047                                         {
1048                                                 if (commitPointSet.contains(commitPoint)) {
1049                                                         throw new ParseException(interfaceName + " has" +
1050                                                                 "duplicate commit point labels");
1051                                                 }
1052                                                 commitPointSet.add(commitPoint);
1053                                         }
1054                                 )*
1055
1056                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1057                         (
1058                                 <HB_CONDITION>
1059                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1060                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1061                                 {
1062                                         if (hbConditions.containsKey(hbLabel)) {
1063                                                 throw new ParseException(interfaceName + " has" +
1064                                                         "duplicate happens-before condtion labels");
1065                                         }
1066                                         hbConditions.put(hbLabel, hbCondition);
1067                                 }
1068                         )*
1069                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1070                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1071                         (<ACTION> action = C_CPP_CODE(null))?
1072                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1073                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1074                 <END>
1075         {
1076                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1077                         hbConditions, idCode, check, action, postAction, postCheck);
1078                 return res;
1079         }
1080 }
1081
1082
1083 PotentialCPDefineConstruct Potential_commit_point_define() :
1084 {
1085         PotentialCPDefineConstruct res;
1086         String label, condition;
1087         ArrayList<String> content;
1088 }
1089 {
1090
1091         { res = null; }
1092                 <BEGIN>
1093                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1094                         <LABEL> (label = <IDENTIFIER>.image)
1095                 <END>
1096         {
1097                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
1098                 return res;
1099         }
1100 }
1101
1102
1103 CPDefineConstruct Commit_point_define() :
1104 {
1105         CPDefineConstruct res;
1106         String label, potentialCPLabel, condition;
1107         ArrayList<String> content;
1108 }
1109 {
1110
1111         { res = null; }
1112                 <BEGIN>
1113                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1114                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1115                         <LABEL> (label = <IDENTIFIER>.image)
1116                 <END>
1117         {
1118                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
1119                 return res;
1120         }
1121 }
1122
1123
1124 CPDefineCheckConstruct Commit_point_define_check() :
1125 {
1126         CPDefineCheckConstruct res;     
1127         String label, condition;
1128         ArrayList<String> content;
1129 }
1130 {
1131
1132         { res = null; }
1133                 <BEGIN> 
1134                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1135                         <LABEL> (label = <IDENTIFIER>.image)
1136                 <END>
1137         {
1138                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1139                 return res;
1140         }
1141 }
1142
1143 EntryPointConstruct Entry_point() :
1144 {}
1145 {
1146
1147                 <BEGIN> 
1148                         <ENTRY_POINT>
1149                 <END>
1150         {
1151                 return new EntryPointConstruct(_file, _content.size());
1152         }
1153 }
1154
1155 ClassBeginConstruct Class_begin() :
1156 {}
1157 {
1158
1159                 <BEGIN> 
1160                         <CLASS_BEGIN>
1161                 <END>
1162         {
1163                 return new ClassBeginConstruct(_file, _content.size());
1164         }
1165 }
1166
1167 ClassEndConstruct Class_end() :
1168 {}
1169 {
1170
1171                 <BEGIN> 
1172                         <CLASS_END>
1173                 <END>
1174         {
1175                 return new ClassEndConstruct(_file, _content.size());
1176         }
1177 }
1178
1179 InterfaceDefineConstruct Interface_define() :
1180 {
1181         String name;    
1182 }
1183 {
1184                 <BEGIN>
1185                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1186                 <END>
1187         {
1188                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1189         }
1190 }