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         <CLEANUP: "@Cleanup:">
371 |
372         <DEFINE_FUNC: "@DefineFunc:">
373 |
374         <INTERFACE_CLUSTER: "@Interface_cluster:">
375 |
376         <HAPPENS_BEFORE: "@Happens_before:">
377 |
378         <INTERFACE: "@Interface:">
379 |
380         <COMMIT_POINT_SET: "@Commit_point_set:">
381 |
382         <ENTRY_POINT: "@Entry_point">
383 |
384         <CLASS_BEGIN: "@Class_begin">
385 |
386         <CLASS_END: "@Class_end">
387 |
388         <INTERFACE_DEFINE: "@Interface_define:">
389 |
390         <CONDITION: "@Condition:">
391 |
392         <HB_CONDITION: "@HB_condition:">
393 |
394         <ID: "@ID:">
395 |
396         <CHECK: "@Check:">
397 |
398         <ACTION: "@Action:">
399 |
400         <CODE: "@Code:">
401 |
402         <POST_ACTION: "@Post_action:">
403 |
404         <POST_CHECK: "@Post_check:">
405 |
406         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
407 |
408         <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE: "@Potential_additional_ordering_point_define:">
409 |
410         <LABEL: "@Label:">
411 |
412         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
413 |
414         <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK: "@Additional_ordering_point_define_check:">
415 |
416         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
417 |
418         <ADDITIONAL_ORDERING_POINT_DEFINE: "@Additional_ordering_point_define:">
419 |
420         <COMMIT_POINT_CLEAR: "@Commit_point_clear:">
421 |
422         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
423 |
424         <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL: "@Potential_additional_ordering_point_label:">
425 }
426
427
428 <IN_SPEC> TOKEN :
429 {
430 /*   Specification & C/C++ shared tokens   */
431 // Reserved keywords
432         <CONST: "const">
433 |
434         <STRUCT: "struct">
435 |
436         <CLASS: "class">
437 |
438         <UNSIGNED: "unsigned">
439 |
440         <TEMPLATE: "template">
441 |
442         <INLINE: "inline">
443 |
444         <STATIC: "static">
445 |
446         <FOR: "for">
447 |
448         <#DIGIT: ["0"-"9"]>
449 |
450         <#LETTER: ["a"-"z", "A"-"Z"]>
451 |
452         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
453 |
454         <POUND: "#">
455 |
456         <OPEN_BRACKET: "[">
457 |
458         <CLOSE_BRACKET: "]">
459 |
460         <EQUALS: "=">
461 |
462         <OPEN_PAREN: "(">
463 |
464         <CLOSE_PAREN: ")">
465 |
466         <OPEN_BRACE: "{">
467 |
468         <CLOSE_BRACE: "}">
469 |
470         <HB_SYMBOL: "->">
471 |
472         <COMMA: ",">
473 |
474 /*   C/C++ only token*/
475         <DOT: ".">
476 |
477         <DOLLAR: "$">
478 |
479         <STAR: "*">
480 |
481         <NEGATE: "~">
482 |
483         <EXCLAMATION: "!">
484 |
485         <AND: "&">
486 |
487         <OR: "|">
488 |
489         <MOD: "%">
490 |
491         <PLUS: "+">
492 |
493         <PLUSPLUS: "++">
494 |
495         <MINUS: "-">
496 |
497         <MINUSMINUS: "--">
498 |
499         <DIVIDE: "/">
500 |
501         <BACKSLASH: "\\">
502 |
503         <LESS_THAN: "<">
504 |
505         <GREATER_THAN: ">">
506 |
507         <GREATER_EQUALS: ">=">
508 |
509         <LESS_EQUALS: "<=">
510 |
511         <LOGICAL_EQUALS: "==">
512 |
513         <NOT_EQUALS: "!=">
514 |
515         <LOGICAL_AND: "&&">
516 |
517         <LOGICAL_OR: "||">
518 |
519         <XOR: "^">
520 |
521         <QUESTION_MARK: "?">
522 |
523         <COLON: ":">
524 |
525         <DOUBLECOLON: "::">
526 |
527         <DOUBLELESSTHAN: "<<">
528 |
529         <DOUBLEGREATERTHAN: ">>">
530 |
531         <TRIPLEGREATERTHAN: ">>>">
532 |
533         <PLUS_EQUALS: "+=">
534 |
535         <MINUS_EQUALS: "-=">
536 |
537         <TIMES_EQUALS: "*=">
538 |
539         <DIVIDE_EQUALS: "/=">
540 |
541         <MOD_EQUALS: "%=">
542 |
543         <XOR_EQUALS: "^=">
544 |
545         <OR_EQUALS: "|=">
546 |
547         <AND_EQUALS: "&=">
548 |
549         <SEMI_COLON: ";">
550 |
551         <STRING_LITERAL:
552         "\""
553         ((~["\"","\\","\n","\r"])
554         | ("\\"
555                 ( ["n","t","b","r","f","\\","'","\""]
556                 | ["0"-"7"] ( ["0"-"7"] )?
557                 | ["0"-"3"] ["0"-"7"]
558                         ["0"-"7"]
559                 )
560                 )
561         )*
562         "\"">
563 |
564         <CHARACTER_LITERAL:
565         "'"
566         ((~["'","\\","\n","\r"])
567         | ("\\"
568                 (["n","t","b","r","f","\\","'","\""]
569                 | ["0"-"7"] ( ["0"-"7"] )?
570                 | ["0"-"3"] ["0"-"7"]
571                 ["0"-"7"]
572                 )
573                 )
574         )
575         "'">
576 |
577         < INTEGER_LITERAL:
578         <DECIMAL_LITERAL> (["l","L"])?
579       | <HEX_LITERAL> (["l","L"])?
580       | <OCTAL_LITERAL> (["l","L"])?>
581 |
582         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
583 |
584         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
585 |
586         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
587 |
588         < FLOATING_POINT_LITERAL:
589         <DECIMAL_FLOATING_POINT_LITERAL>
590       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
591 |
592         < #DECIMAL_FLOATING_POINT_LITERAL:
593         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
594       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
595       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
596       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
597 |
598         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
599 |
600         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
601         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
602       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
603 |
604         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
605 |
606         < #SPACE: (" " | "\t")+>
607 |
608         < #TO_END_OF_LINE: (~["\n"])+>
609 |
610         /* Macro token */
611         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
612 |
613         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
614 }
615
616 String Type() :
617 {
618         String type;
619         String str;
620         QualifiedName name;
621 }
622 {
623         { type = ""; }
624         (<CONST>
625         { type = "const"; }
626         )?
627         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
628         (
629         name = ParseQualifiedName() {
630                 if (!type.equals(""))
631                         type = type + " " + name.fullName;
632                 else
633                         type = name.fullName;
634         })
635         )
636         ((str = <CONST>.image {
637                 if (!type.equals(""))
638                         type = type + " " + str;
639                 else
640                         type = str;
641         }) |
642         (str = <STAR>.image {
643                 if (!type.equals(""))
644                         type = type + " " + str;
645                 else
646                         type = str;
647         }) |
648         (str = <AND>.image {
649                 if (!type.equals(""))
650                         type = type + " " + str;
651                 else
652                         type = str;
653         })
654         )*
655         {
656                 return type;
657         }
658 }
659
660
661 String ParameterizedName() :
662 {
663         String res = "";
664         String str;
665 }
666 {
667         (str = <IDENTIFIER>.image {res = str;})
668         (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
669         (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
670         { res = res + ">"; }
671         )?
672         {
673                 return res;
674         }
675 }
676
677 FunctionHeader FuncDecl() :
678 {
679         String ret;
680         QualifiedName funcName;
681         ArrayList<VariableDeclaration> args;
682 }
683 {
684         (<STATIC> | <INLINE>)*
685         ret = Type() 
686         funcName = ParseQualifiedName() 
687         args = FormalParamList() 
688         {
689                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
690                 //System.out.println(res);
691                 return res;
692         }
693 }
694
695 QualifiedName ParseQualifiedName() :
696 {
697         String qualifiedName, str;
698 }
699 {
700         { qualifiedName = ""; }
701         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
702         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
703         "::" + str; }  ))*
704         {
705                 QualifiedName res = new QualifiedName(qualifiedName);
706                 //System.out.println(res);
707                 return res;
708         }
709 }
710
711 ArrayList<VariableDeclaration> TemplateParamList() :
712 {
713         ArrayList<VariableDeclaration> params;
714         String type;
715         String name;
716 }
717 {
718         {
719                 params = new ArrayList<VariableDeclaration>();
720         }
721         <TEMPLATE>
722         <OPEN_BRACKET>
723         (type = <IDENTIFIER>.image 
724         name = <IDENTIFIER>.image
725         {
726                 params.add(new VariableDeclaration(type, name));
727         }
728         )
729
730         (<COMMA> type = <IDENTIFIER>.image 
731         name = <IDENTIFIER>.image
732         {
733                 params.add(new VariableDeclaration(type, name));
734         }
735         )*
736         <CLOSE_BRACKET>
737         {
738                 //System.out.println(params);
739                 return params;
740         }
741 }
742
743 ArrayList<VariableDeclaration > FormalParamList() :
744 {
745         ArrayList<VariableDeclaration > typeParams;
746         VariableDeclaration varDecl;
747 }
748 {
749         {
750                 typeParams = new ArrayList<VariableDeclaration >();
751         }
752         <OPEN_PAREN>
753         ((varDecl = TypeParam() {typeParams.add(varDecl);})
754         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
755         <CLOSE_PAREN>
756         {
757                 return typeParams;
758         }
759 }
760
761 VariableDeclaration TypeParam() :
762 {
763         String type, param;
764 }
765 {
766         (type = Type()) (param = <IDENTIFIER>.image)
767         {
768                 return new VariableDeclaration(type, param);
769         }
770 }
771
772
773
774 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
775 {
776         String text;
777         Token t;
778         boolean newLine = false;
779         boolean newSpace = true;
780         boolean inTemplate = false;
781         boolean inForLoop = false;
782         ArrayList<String> content;
783         String header;
784 }
785 {
786         {
787                 text = "";
788                 t = new Token();
789                 content = new ArrayList<String>();
790         }
791         (
792         LOOKAHEAD(2)
793         (
794         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
795         (t = <TEMPLATE> { inTemplate = true;  })|
796         t = <STATIC> | t = <INLINE> |
797         (t = <FOR> { inForLoop = true; })|
798         (t = <INCLUDE>
799         {
800                 header = t.image;
801                 newLine = true;
802                 if (headers != null) {
803                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
804                 }
805         })
806         | t = <IDENTIFIER> | t = <POUND> |
807         (t = <OPEN_BRACE>  { newLine = true; } ) |
808         (t = <CLOSE_BRACE>  { newLine = true; inForLoop = false;} ) | 
809         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
810         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
811         | t = <HB_SYMBOL> | t = <COMMA> |
812         t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
813         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
814         t = <LESS_THAN> |
815         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
816         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
817         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
818         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
819         t = <DOUBLELESSTHAN> | 
820         t = <DOUBLEGREATERTHAN> |
821         t = <TRIPLEGREATERTHAN> | 
822
823         t = <PLUS_EQUALS> |
824         t = <MINUS_EQUALS> |
825         t = <TIMES_EQUALS> |
826         t = <DIVIDE_EQUALS> |
827         t = <MOD_EQUALS> |
828         t = <XOR_EQUALS> |
829         t = <OR_EQUALS> |
830         t = <AND_EQUALS> |
831
832         (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
833         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
834         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
835         (t = <DEFINE> { newLine = true; } )
836         )
837         {
838                 if (text.equals("")) {
839                         text = t.image;
840                         newSpace = true;
841                 } else {
842                         text = text + " " + t.image;
843                         /*
844                         if (newSpace && spaceSeparator(t)) {
845                                 text = text + " " + t.image;
846                         } else {
847                                 text = text + t.image;
848                                 if (spaceSeparator(t))
849                                         newSpace = true;
850                         }*/
851                 }
852                 if (newLine) {
853                         content.add(text);
854                         text = "";
855                         newLine = false;
856                         inTemplate = false;
857                 }
858         }
859         )+
860
861         {
862                 if (content.size() == 0) {
863                         content.add(text);
864                 }
865                 return content;
866         }
867 }
868
869
870 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
871 {
872         Construct inst;
873         StringBuilder sb;
874         boolean flushSB;
875 }
876 {
877         {
878                 _file = f;
879                 _content = content;
880                 _constructs = constructs;
881                 sb = new StringBuilder();
882         }
883         (
884         (inst = ParseSpec()
885         {
886                 _constructs.add(inst);
887         }
888         ) |
889         //((code = C_CPP_CODE(headers)) { _content.addAll(code); })
890         (
891         flushSB = OriginalCode(sb)
892         {
893                 if (flushSB) {
894                         sb = new StringBuilder();
895                 }
896         }
897         )
898         )* 
899         // For the last piece of code
900         {
901                 _content.add(sb.toString());
902         }
903         <EOF>
904 }
905
906 // If true, there's a new line and sb should be flushed
907 boolean OriginalCode(StringBuilder sb) :
908 {
909         String str;
910 }
911 {
912         str = <ANY>.image
913         {
914                 if (!str.equals("\n")) {
915                         sb.append(str);
916                         return false;
917                 } else {
918                         _content.add(sb.toString());
919                         return true;
920                 }
921         }
922 }
923
924 Construct ParseSpec() :
925 {
926         Construct res;  
927 }
928 {
929         (
930         LOOKAHEAD(2) res = Global_construct() |
931         LOOKAHEAD(2) res = Interface() |
932         LOOKAHEAD(2) res = Potential_commit_point_define() |
933         LOOKAHEAD(2) res = Commit_point_define() |
934         LOOKAHEAD(2) res = Commit_point_define_check() |
935         LOOKAHEAD(2) res = Potential_additional_ordering_point_define() |
936         LOOKAHEAD(2) res = Additional_ordering_point_define() |
937         LOOKAHEAD(2) res = Additional_ordering_point_define_check() |
938         LOOKAHEAD(2) res = Commit_point_clear() |
939         LOOKAHEAD(2) res = Entry_point() |
940         LOOKAHEAD(2) res = Class_begin() |
941         LOOKAHEAD(2) res = Class_end() |
942         LOOKAHEAD(2) res = Interface_define()
943         )
944         {
945                 //System.out.println(res);
946                 return res;
947         }
948 }
949
950 GlobalConstruct Global_construct() :
951 {
952         GlobalConstruct res;
953         SequentialDefineSubConstruct code;
954         HashMap<String, String> options;
955         String key, value;
956 }
957 {
958         {
959                 res = null;
960                 options = new HashMap<String, String>();
961         }
962                 <BEGIN> 
963                         (<OPTIONS>
964                                 ((key = <IDENTIFIER>.image)
965                                 <EQUALS>
966                                 (value = <IDENTIFIER>.image)
967                                 {
968                                         if (options.containsKey(key)) {
969                                                 throw new ParseException("Duplicate options!");
970                                         }
971                                         options.put(key, value);
972                                 }
973                                 <SEMI_COLON>
974                                 )*
975                         )?
976                         (code = Global_define())
977                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
978                         (Interface_clusters(res))?
979                         (Happens_before(res))?
980                 <END>
981         {
982                 res.unfoldInterfaceCluster();
983                 return res;
984         }
985 }
986
987 SequentialDefineSubConstruct Global_define() :
988 {
989         ArrayList<String> initVar, cleanup, defineFunc, code, declareStruct;
990         ArrayList<ArrayList<String>> defineFuncs;
991         ArrayList<VariableDeclaration> declareVars;
992         ArrayList<ArrayList<String>> declareStructs;
993         VariableDeclaration declareVar;
994
995 }
996 {
997         {
998                 declareVars = new ArrayList<VariableDeclaration>();
999                 initVar = new ArrayList<String>();
1000                 cleanup = new ArrayList<String>();
1001                 defineFuncs = new ArrayList<ArrayList<String>>();
1002                 declareStructs = new ArrayList<ArrayList<String>>();
1003         }
1004         <GLOBAL_DEFINE>
1005         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
1006                 declareStructs.add(declareStruct); }))*
1007                 (<DECLARE_VAR> ((declareVar = TypeParam() <SEMI_COLON> {
1008                         declareVars.add(declareVar); } )*))?
1009         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
1010         (<CLEANUP> (code = C_CPP_CODE(null) { cleanup = code; } ))?
1011         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
1012         {
1013                 SequentialDefineSubConstruct res = new
1014                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, cleanup, defineFuncs);
1015                 //System.out.println(res);
1016                 return res;
1017         }
1018 }
1019
1020 ConditionalInterface Conditional_interface() :
1021 {
1022         String interfaceName, hbConditionLabel;
1023 }
1024 {
1025         {
1026                 hbConditionLabel = "";
1027         }
1028         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
1029         <IDENTIFIER>.image <CLOSE_PAREN>)?
1030         {
1031                 return new ConditionalInterface(interfaceName, hbConditionLabel);
1032         }
1033 }
1034
1035 void Interface_cluster(GlobalConstruct inst) :
1036 {
1037         String clusterName;
1038         ConditionalInterface condInterface;
1039 }
1040 {
1041         (clusterName= <IDENTIFIER>.image)
1042         <EQUALS> <OPEN_BRACE>
1043                 (condInterface = Conditional_interface()
1044                 { inst.addInterface2Cluster(clusterName, condInterface); } 
1045                 )
1046                 (<COMMA> condInterface = Conditional_interface()
1047                 { inst.addInterface2Cluster(clusterName, condInterface); } 
1048                 )*
1049         <CLOSE_BRACE>
1050 }
1051
1052 void Interface_clusters(GlobalConstruct inst) :
1053 {}
1054 {
1055         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
1056 }
1057
1058 void Happens_before(GlobalConstruct inst) :
1059 {
1060         ConditionalInterface left, right;       
1061 }
1062 {
1063         <HAPPENS_BEFORE> 
1064         (
1065         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
1066         { inst.addHBCondition(left, right); }
1067         )+
1068 }
1069
1070 InterfaceConstruct Interface() :
1071 {
1072         InterfaceConstruct res;
1073         String interfaceName, condition, idCode, check,
1074                 postCheck, commitPoint, hbLabel, hbCondition;
1075         ArrayList<String> commitPointSet;
1076         ArrayList<String> action, postAction;
1077         HashMap<String, String> hbConditions;
1078         ArrayList<String> content;
1079 }
1080 {
1081         {
1082                 res = null;
1083                 action = new ArrayList<String>();
1084                 condition = "";
1085                 idCode = "";
1086                 check = "";
1087                 postCheck = "";
1088                 commitPointSet = new ArrayList<String>();
1089                 hbConditions = new HashMap<String, String>();
1090                 postAction = new ArrayList<String>();
1091         }
1092                 <BEGIN>
1093                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1094                         <COMMIT_POINT_SET>
1095                                 (commitPoint = <IDENTIFIER>.image
1096                                 { commitPointSet.add(commitPoint); }
1097                                 )
1098                                 (<OR>
1099                                         (commitPoint = <IDENTIFIER>.image)
1100                                         {
1101                                                 if (commitPointSet.contains(commitPoint)) {
1102                                                         throw new ParseException(interfaceName + " has" +
1103                                                                 "duplicate commit point labels");
1104                                                 }
1105                                                 commitPointSet.add(commitPoint);
1106                                         }
1107                                 )*
1108
1109                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1110                         (
1111                                 <HB_CONDITION>
1112                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1113                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1114                                 {
1115                                         if (hbConditions.containsKey(hbLabel)) {
1116                                                 throw new ParseException(interfaceName + " has" +
1117                                                         "duplicate happens-before condtion labels");
1118                                         }
1119                                         hbConditions.put(hbLabel, hbCondition);
1120                                 }
1121                         )*
1122                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1123                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1124                         (<ACTION> action = C_CPP_CODE(null))?
1125                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1126                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1127                 <END>
1128         {
1129                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1130                         hbConditions, idCode, check, action, postAction, postCheck);
1131                 return res;
1132         }
1133 }
1134
1135
1136 PotentialCPDefineConstruct Potential_commit_point_define() :
1137 {
1138         PotentialCPDefineConstruct res;
1139         String label, condition;
1140         ArrayList<String> content;
1141 }
1142 {
1143
1144         { res = null; }
1145                 <BEGIN>
1146                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1147                         <LABEL> (label = <IDENTIFIER>.image)
1148                 <END>
1149         {
1150                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
1151                 return res;
1152         }
1153 }
1154
1155 PotentialCPDefineConstruct Potential_additional_ordering_point_define() :
1156 {
1157         PotentialCPDefineConstruct res;
1158         String label, condition;
1159         ArrayList<String> content;
1160 }
1161 {
1162
1163         { res = null; }
1164                 <BEGIN>
1165                         <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1166                         <LABEL> (label = <IDENTIFIER>.image)
1167                 <END>
1168         {
1169                 // Set the boolean flag isAdditionalOrderingPoint to be true
1170                 res = new PotentialCPDefineConstruct(_file, _content.size(), true, label, condition); 
1171                 return res;
1172         }
1173 }
1174
1175
1176 CPDefineConstruct Commit_point_define() :
1177 {
1178         CPDefineConstruct res;
1179         String label, potentialCPLabel, condition;
1180         ArrayList<String> content;
1181 }
1182 {
1183
1184         { res = null; }
1185                 <BEGIN>
1186                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1187                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1188                         <LABEL> (label = <IDENTIFIER>.image)
1189                 <END>
1190         {
1191                 res = new CPDefineConstruct(_file, _content.size(), false, label, potentialCPLabel, condition);
1192                 return res;
1193         }
1194 }
1195
1196 CPDefineConstruct Additional_ordering_point_define() :
1197 {
1198         CPDefineConstruct res;
1199         String label, potentialCPLabel, condition;
1200         ArrayList<String> content;
1201 }
1202 {
1203
1204         { res = null; }
1205                 <BEGIN>
1206                         <ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1207                         <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1208                         <LABEL> (label = <IDENTIFIER>.image)
1209                 <END>
1210         {
1211                 // Set the boolean flag isAdditionalOrderingPoint to be true
1212                 res = new CPDefineConstruct(_file, _content.size(), true, label, potentialCPLabel, condition);
1213                 return res;
1214         }
1215 }
1216
1217 CPClearConstruct Commit_point_clear() :
1218 {
1219         CPClearConstruct res;   
1220         String label, condition;
1221         ArrayList<String> content;
1222 }
1223 {
1224
1225         { res = null; }
1226                 <BEGIN> 
1227                         <COMMIT_POINT_CLEAR> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1228                         <LABEL> (label = <IDENTIFIER>.image)
1229                 <END>
1230         {
1231                 res = new CPClearConstruct(_file, _content.size(), label, condition);
1232                 return res;
1233         }
1234 }
1235
1236
1237 CPDefineCheckConstruct Commit_point_define_check() :
1238 {
1239         CPDefineCheckConstruct res;     
1240         String label, condition;
1241         ArrayList<String> content;
1242 }
1243 {
1244
1245         { res = null; }
1246                 <BEGIN> 
1247                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1248                         <LABEL> (label = <IDENTIFIER>.image)
1249                 <END>
1250         {
1251                 res = new CPDefineCheckConstruct(_file, _content.size(), false, label, condition);
1252                 return res;
1253         }
1254 }
1255
1256 CPDefineCheckConstruct Additional_ordering_point_define_check() :
1257 {
1258         CPDefineCheckConstruct res;     
1259         String label, condition;
1260         ArrayList<String> content;
1261 }
1262 {
1263
1264         { res = null; }
1265                 <BEGIN> 
1266                         <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1267                         <LABEL> (label = <IDENTIFIER>.image)
1268                 <END>
1269         {
1270                 // Set the boolean flag isAdditionalOrderingPoint to be true
1271                 res = new CPDefineCheckConstruct(_file, _content.size(), true, label, condition);
1272                 return res;
1273         }
1274 }
1275
1276 EntryPointConstruct Entry_point() :
1277 {}
1278 {
1279
1280                 <BEGIN> 
1281                         <ENTRY_POINT>
1282                 <END>
1283         {
1284                 return new EntryPointConstruct(_file, _content.size());
1285         }
1286 }
1287
1288 ClassBeginConstruct Class_begin() :
1289 {}
1290 {
1291
1292                 <BEGIN> 
1293                         <CLASS_BEGIN>
1294                 <END>
1295         {
1296                 return new ClassBeginConstruct(_file, _content.size());
1297         }
1298 }
1299
1300 ClassEndConstruct Class_end() :
1301 {}
1302 {
1303
1304                 <BEGIN> 
1305                         <CLASS_END>
1306                 <END>
1307         {
1308                 return new ClassEndConstruct(_file, _content.size());
1309         }
1310 }
1311
1312 InterfaceDefineConstruct Interface_define() :
1313 {
1314         String name;    
1315 }
1316 {
1317                 <BEGIN>
1318                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1319                 <END>
1320         {
1321                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1322         }
1323 }