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