more 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                 @DeclareVar:
20                 @InitVar:
21                 @DefineFunc:
22                 ...
23         @Interface_cluster:
24                 ...
25         @Happens-before:
26                 ...
27         @End
28         
29         b) Interface construct
30         @Begin
31         @Interface: ...
32         @Commit_point_set:
33                 IDENTIFIER | IDENTIFIER ...
34         @Condition: ... (Optional)
35         @HB_Condition:
36                 IDENTIFIER :: <C_CPP_Condition>
37         @HB_Condition: ...
38         @ID: ... (Optional, use default ID)
39         @Check: (Optional)
40                 ...
41         @Action: (Optional)
42                 @DefineVar: Type var1 = SomeExpression (Optional)
43                 @Code (Optional)
44                 ...
45         @Post_action: (Optional)
46         @Post_check: (Optional)
47         @End
48
49         c) Potential commit construct
50         @Begin
51         @Potential_commit_point_define: ...
52         @Label: ...
53         @End
54
55         d) Commit point define construct
56         @Begin
57         @Commit_point_define_check: ...
58         @Label: ...
59         @End
60         
61                 OR
62
63         @Begin
64         @Commit_point_define: ...
65         @Potential_commit_point_label: ...
66         @Label: ...
67         @End
68
69         e) Entry point construct
70         @Begin
71         @Entry_point
72         @End
73
74         f) Interface define construct
75         @Begin
76         @Interface_define: <Interface_Name>
77         @End
78 */
79
80
81
82 options {
83         STATIC = false;
84         JAVA_UNICODE_ESCAPE = true;
85 }
86
87 PARSER_BEGIN(SpecParser)
88 package edu.uci.eecs.specCompiler.grammerParser;
89
90 import java.io.FileInputStream;
91 import java.io.FileNotFoundException;
92 import java.io.InputStream;
93 import java.io.ByteArrayInputStream;
94 import java.util.ArrayList;
95 import java.util.HashMap;
96 import java.util.HashSet;
97
98 import edu.uci.eecs.specCompiler.specExtraction.Construct;
99 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
100 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
105 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
106 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
107 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
108 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
110
111         public class SpecParser {
112                 public static void main(String[] argvs)
113                 throws ParseException, TokenMgrError {
114                         try {
115                                 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
116                                 SpecParser parser = new SpecParser(fis);
117                                 parser.Parse();
118                                 System.out.println("Parsing finished!");
119                         } catch (FileNotFoundException e) {
120                                 e.printStackTrace();
121                         }
122                 }
123         
124                 public static Construct parseSpec(String text)
125                 throws ParseException, TokenMgrError {
126                         InputStream input = new ByteArrayInputStream(text.getBytes());
127                         SpecParser parser = new SpecParser(input);
128                         return parser.Parse();
129                 }
130
131
132         }
133 PARSER_END(SpecParser)
134
135 SKIP :
136 {
137         " "
138 |
139         "\n"
140 |
141         "\r"
142 |
143         "\r\n"
144 |
145         "\t"
146 |
147         // "#" comment for the specification
148         <"#" (~["\n", "\r"])* (["\n", "\r"])>
149 |
150         // "//" comment for the specification
151         <"//" (~["\n", "\r"])* (["\n", "\r"])>
152 }
153
154 TOKEN :
155 {
156 /*   Above are specification-only tokens   */
157         <HEAD: "/**">
158 |
159         <TAIL: "*/">
160 |
161         <BEGIN: "@Begin">
162 |
163         <END: "@End">
164 |
165         <OPTIONS: "@Options:">
166 |
167         <GLOBAL_DEFINE: "@Global_define:">
168 |
169         <DECLARE_VAR: "@DeclareVar:">
170 |
171         <INIT_VAR: "@InitVar:">
172 |
173         <DEFINE_FUNC: "@DefineFunc:">
174 |
175         <INTERFACE_CLUSTER: "@Interface_cluster:">
176 |
177         <HAPPENS_BEFORE: "@Happens_before:">
178 |
179         <INTERFACE: "@Interface:">
180 |
181         <COMMIT_POINT_SET: "@Commit_point_set:">
182 |
183         <ENTRY_POINT: "@Entry_point">
184 |
185         <INTERFACE_DEFINE: "@Interface_define:">
186 |
187         <CONDITION: "@Condition:">
188 |
189         <HB_CONDITION: "@HB_condition:">
190 |
191         <ID: "@ID:">
192 |
193         <CHECK: "@Check:">
194 |
195         <ACTION: "@Action:">
196 |
197         <DEFINEVAR: "@DefineVar:">
198 |
199         <CODE: "@Code:">
200 |
201         <POST_ACTION: "@Post_action:">
202 |
203         <POST_CHECK: "@Post_check:">
204 |
205         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
206 |
207         <LABEL: "@Label:">
208 |
209         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
210 |
211         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
212 |
213         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
214
215
216 /*   Specification & C/C++ shared tokens   */
217 |
218         <#DIGIT: ["0"-"9"]>
219 |
220         <#LETTER: ["a"-"z", "A"-"Z"]>
221 |
222         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
223 |
224         <EQUALS: "=">
225 |
226         <OPEN_PAREN: "{">
227 |
228         <CLOSE_PAREN: "}">
229 |
230         <OPEN_BRACKET: "(">
231 |
232         <CLOSE_BRACKET: ")">
233 |
234         <HB_SYMBOL: "->">
235 |
236         <COMMA: ",">
237
238 |
239 /*   C/C++ only token*/
240         <DOT: ".">
241 |
242         <STAR: "*">
243 |
244         <NEGATE: "~">
245 |
246         <EXCLAMATION: "!">
247 |
248         <AND: "&">
249 |
250         <OR: "|">
251 |
252         <MOD: "%">
253 |
254         <PLUS: "+">
255 |
256         <PLUSPLUS: "++">
257 |
258         <MINUS: "-">
259 |
260         <MINUSMINUS: "--">
261 |
262         <DIVIDE: "/">
263 |
264         <BACKSLASH: "\\">
265 |
266         <LESS_THAN: "<">
267 |
268         <GREATER_THAN: ">">
269 |
270         <GREATER_EQUALS: ">=">
271 |
272         <LESS_EQUALS: "<=">
273 |
274         <LOGICAL_EQUALS: "==">
275 |
276         <NOT_EQUALS: "!=">
277 |
278         <LOGICAL_AND: "&&">
279 |
280         <LOGICAL_OR: "||">
281 |
282         <XOR: "^">
283 |
284         <QUESTION_MARK: "?">
285 |
286         <COLON: ":">
287 |
288         <DOUBLECOLON: "::">
289 |
290         <SEMI_COLON: ";">
291 |
292         <STRING_LITERAL:
293         "\""
294         ((~["\"","\\","\n","\r"])
295         | ("\\"
296                 ( ["n","t","b","r","f","\\","'","\""]
297                 | ["0"-"7"] ( ["0"-"7"] )?
298                 | ["0"-"3"] ["0"-"7"]
299                         ["0"-"7"]
300                 )
301                 )
302         )*
303         "\"">
304 |
305         <CHARACTER_LITERAL:
306         "'"
307         ((~["'","\\","\n","\r"])
308         | ("\\"
309                 (["n","t","b","r","f","\\","'","\""]
310                 | ["0"-"7"] ( ["0"-"7"] )?
311                 | ["0"-"3"] ["0"-"7"]
312                 ["0"-"7"]
313                 )
314                 )
315         )
316         "'">
317 |
318         < INTEGER_LITERAL:
319         <DECIMAL_LITERAL> (["l","L"])?
320       | <HEX_LITERAL> (["l","L"])?
321       | <OCTAL_LITERAL> (["l","L"])?>
322 |
323         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
324 |
325         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
326 |
327         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
328 |
329         < FLOATING_POINT_LITERAL:
330         <DECIMAL_FLOATING_POINT_LITERAL>
331       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
332 |
333         < #DECIMAL_FLOATING_POINT_LITERAL:
334         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
335       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
336       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
337       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
338 |
339         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
340 |
341         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
342         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
343       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
344 |
345         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
346 }
347
348 Construct Parse() :
349 {
350         Construct res;  
351 }
352 {
353         (
354         LOOKAHEAD(3) res = Global_construct() |
355         LOOKAHEAD(3) res = Interface() |
356         LOOKAHEAD(3) res = Potential_commit_point_define() |
357         LOOKAHEAD(3) res = Commit_point_define() |
358         LOOKAHEAD(3) res = Commit_point_define_check() |
359         LOOKAHEAD(3) res = Entry_point() |
360         LOOKAHEAD(3) res = Interface_define()
361         )
362         <EOF>
363         {
364                 //System.out.println(res);
365                 return res;
366         }
367 }
368
369 GlobalConstruct Global_construct() :
370 {
371         GlobalConstruct res;
372         SequentialDefineSubConstruct code;
373         HashMap<String, String> options;
374         String key, value;
375 }
376 {
377         {
378                 res = null;
379                 options = new HashMap<String, String>();
380         }
381         <HEAD>
382                 <BEGIN> 
383                         (<OPTIONS>
384                                 ((key = <IDENTIFIER>.image)
385                                 <EQUALS>
386                                 (value = <IDENTIFIER>.image)
387                                 {
388                                         if (options.containsKey(key)) {
389                                                 throw new ParseException("Duplicate options!");
390                                         }
391                                         options.put(key, value);
392                                 }
393                                 <SEMI_COLON>
394                                 )*
395                         )?
396                         (code = Global_define())
397                         { res = new GlobalConstruct(code, options); }
398                         (Interface_clusters(res))?
399                         (Happens_before(res))?
400                 <END>
401         <TAIL>
402         {
403                 res.unfoldInterfaceCluster();
404                 return res;
405         }
406 }
407
408 String C_CPP_CODE() :
409 {
410         StringBuilder text;
411         Token t;
412 }
413 {
414         {
415                 text = new StringBuilder();
416                 t = new Token();
417         }
418         (
419         //LOOKAHEAD(2)
420         (
421         t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
422         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
423         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
424         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
425         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
426         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
427         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
428         t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
429         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
430         )
431         {
432                 text.append(t.image);
433                 if (t.image.equals(";") || t.image.equals("\\")
434                         || t.image.equals("{") || t.image.equals("}"))
435                         text.append("\n");
436                 else
437                         text.append(" ");
438         }
439         )+
440         {
441                 //System.out.println(text);
442                 return text.toString();
443         }
444 }
445
446 SequentialDefineSubConstruct Global_define() :
447 {
448         String declareVar, initVar, defineFunc;
449 }
450 {
451         {
452                 declareVar = "";
453                 initVar = "";
454                 defineFunc = "";
455         }
456         <GLOBAL_DEFINE>
457                 (<DECLARE_VAR> (declareVar = C_CPP_CODE()))?
458         (<INIT_VAR> (initVar = C_CPP_CODE()))?
459         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE()))?
460         {
461                 SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
462                 //System.out.println(res);
463                 return res;
464         }
465 }
466
467 ConditionalInterface Conditional_interface() :
468 {
469         String interfaceName, hbConditionLabel;
470 }
471 {
472         {
473                 hbConditionLabel = "";
474         }
475         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
476         <IDENTIFIER>.image <CLOSE_BRACKET>)?
477         {
478                 return new ConditionalInterface(interfaceName, hbConditionLabel);
479         }
480 }
481
482 void Interface_cluster(GlobalConstruct inst) :
483 {
484         String clusterName;
485         ConditionalInterface condInterface;
486 }
487 {
488         (clusterName= <IDENTIFIER>.image)
489         <EQUALS> <OPEN_PAREN>
490                 (condInterface = Conditional_interface()
491                 { inst.addInterface2Cluster(clusterName, condInterface); } 
492                 )
493                 (<COMMA> condInterface = Conditional_interface()
494                 { inst.addInterface2Cluster(clusterName, condInterface); } 
495                 )*
496         <CLOSE_PAREN>
497 }
498
499 void Interface_clusters(GlobalConstruct inst) :
500 {}
501 {
502         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
503 }
504
505 void Happens_before(GlobalConstruct inst) :
506 {
507         ConditionalInterface left, right;       
508 }
509 {
510         <HAPPENS_BEFORE> 
511         (
512         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
513         { inst.addHBCondition(left, right); }
514         )+
515 }
516
517 InterfaceConstruct Interface() :
518 {
519         InterfaceConstruct res;
520         String interfaceName, condition, idCode, check, postAction,
521                 postCheck, commitPoint, hbLabel, hbCondition;
522         ActionSubConstruct action;
523         ArrayList<String> commitPointSet;
524         HashMap<String, String> hbConditions;
525 }
526 {
527         {
528                 res = null;
529                 action = null;
530                 condition = "";
531                 idCode = "";
532                 check = "";
533                 postAction = "";
534                 postCheck = "";
535                 commitPointSet = new ArrayList<String>();
536                 hbConditions = new HashMap<String, String>();
537         }
538         <HEAD> 
539                 <BEGIN>
540                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
541                         <COMMIT_POINT_SET>
542                                 (commitPoint = <IDENTIFIER>.image
543                                 { commitPointSet.add(commitPoint); }
544                                 )
545                                 (<OR>
546                                         (commitPoint = <IDENTIFIER>.image)
547                                         {
548                                                 if (commitPointSet.contains(commitPoint)) {
549                                                         throw new ParseException(interfaceName + " has" +
550                                                                 "duplicate commit point labels");
551                                                 }
552                                                 commitPointSet.add(commitPoint);
553                                         }
554                                 )*
555
556                         (<CONDITION> (condition = C_CPP_CODE()))?
557                         (
558                                 <HB_CONDITION>
559                                 (hbLabel = <IDENTIFIER>.image)
560                                 (hbCondition = C_CPP_CODE())
561                                 {
562                                         if (hbConditions.containsKey(hbLabel)) {
563                                                 throw new ParseException(interfaceName + " has" +
564                                                         "duplicate happens-before condtion labels");
565                                         }
566                                         hbConditions.put(hbLabel, hbCondition);
567                                 }
568                         )*
569                         (<ID> (idCode = C_CPP_CODE()))?
570                         (<CHECK> (check = C_CPP_CODE()))?
571                         (action = Action())?
572                         (<POST_ACTION> (postAction = C_CPP_CODE()))?
573                         (<POST_CHECK> (postCheck = C_CPP_CODE()))?
574                 <END>
575         <TAIL>
576         {
577                 res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
578                         hbConditions, idCode, check, action, postAction, postCheck);
579                 return res;
580         }
581 }
582
583 ActionSubConstruct Action() :
584 {
585         String type, name, expr, defineVarStr, code;
586         ArrayList<DefineVar> defineVars;
587 }
588 {
589         {
590                 defineVars = new ArrayList<DefineVar>();
591                 code = "";
592         }
593         <ACTION>
594         (
595                 (
596                 (<DEFINEVAR> (defineVarStr = C_CPP_CODE()) 
597                 {
598                         int eqIdx = defineVarStr.indexOf('=');
599                         int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
600                         type = defineVarStr.substring(0, typeEnd);
601                         name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
602                         expr = defineVarStr.substring(eqIdx + 2);
603                         DefineVar defineVar = new DefineVar(type, name, expr);
604                         defineVars.add(defineVar);
605                 })*  (<CODE> (code = C_CPP_CODE()))? ) 
606         )
607         
608         {
609                 ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
610                 return res;
611         }
612 }
613
614 PotentialCPDefineConstruct Potential_commit_point_define() :
615 {
616         PotentialCPDefineConstruct res;
617         String label, condition;
618 }
619 {
620
621         { res = null; }
622         <HEAD> 
623                 <BEGIN>
624                         <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
625                         <LABEL> (label = <IDENTIFIER>.image)
626                 <END>
627         <TAIL>
628         {
629                 res = new PotentialCPDefineConstruct(label, condition); 
630                 return res;
631         }
632 }
633
634
635 CPDefineConstruct Commit_point_define() :
636 {
637         CPDefineConstruct res;
638         String label, potentialCPLabel, condition;
639 }
640 {
641
642         { res = null; }
643         <HEAD> 
644                 <BEGIN>
645                         <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
646                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
647                         <LABEL> (label = <IDENTIFIER>.image)
648                 <END>
649         <TAIL>
650         {
651                 res = new CPDefineConstruct(label, potentialCPLabel, condition);
652                 return res;
653         }
654 }
655
656
657 CPDefineCheckConstruct Commit_point_define_check() :
658 {
659         CPDefineCheckConstruct res;     
660         String label, condition;
661 }
662 {
663
664         { res = null; }
665         <HEAD> 
666                 <BEGIN> 
667                         <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
668                         <LABEL> (label = <IDENTIFIER>.image)
669                 <END>
670         <TAIL>
671         {
672                 res = new CPDefineCheckConstruct(label, condition);
673                 return res;
674         }
675 }
676
677 EntryPointConstruct Entry_point() :
678 {}
679 {
680
681         <HEAD> 
682                 <BEGIN> 
683                         <ENTRY_POINT>
684                 <END>
685         <TAIL>
686         {
687                 return new EntryPointConstruct();
688         }
689 }
690
691 InterfaceDefineConstruct Interface_define() :
692 {
693         String name;    
694 }
695 {
696         <HEAD>
697                 <BEGIN>
698                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
699                 <END>
700         <TAIL>
701         {
702                 return new InterfaceDefineConstruct(name);
703         }
704 }
705
706