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