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