1 /* spec-compiler.jj Grammer definition for the specification */
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.
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
29 b) Interface construct
33 IDENTIFIER | IDENTIFIER ...
34 @Condition: ... (Optional)
36 IDENTIFIER :: <C_CPP_Condition>
38 @ID: ... (Optional, use default ID)
42 # Type here must be a pointer
43 @DefineVar: Type var1 = SomeExpression (Optional)
46 @Post_action: (Optional)
47 @Post_check: (Optional)
50 c) Potential commit construct
52 @Potential_commit_point_define: ...
56 d) Commit point define construct
58 @Commit_point_define_check: ...
65 @Commit_point_define: ...
66 @Potential_commit_point_label: ...
70 e) Entry point construct
75 f) Interface define construct
77 @Interface_define: <Interface_Name>
85 JAVA_UNICODE_ESCAPE = true;
88 PARSER_BEGIN(SpecParser)
89 package edu.uci.eecs.specCompiler.grammerParser;
91 import java.io.FileInputStream;
92 import java.io.FileNotFoundException;
93 import java.io.InputStream;
94 import java.io.ByteArrayInputStream;
95 import java.util.ArrayList;
96 import java.util.HashMap;
97 import java.util.HashSet;
99 import edu.uci.eecs.specCompiler.specExtraction.Construct;
100 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
106 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
107 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
108 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
110 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
112 public class SpecParser {
113 public static void main(String[] argvs)
114 throws ParseException, TokenMgrError {
116 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
117 SpecParser parser = new SpecParser(fis);
119 System.out.println("Parsing finished!");
120 } catch (FileNotFoundException e) {
125 public static Construct parseSpec(String text)
126 throws ParseException, TokenMgrError {
127 InputStream input = new ByteArrayInputStream(text.getBytes());
128 SpecParser parser = new SpecParser(input);
129 return parser.Parse();
134 PARSER_END(SpecParser)
148 // "#" comment for the specification
149 <"#" (~["\n", "\r"])* (["\n", "\r"])>
151 // "//" comment for the specification
152 <"//" (~["\n", "\r"])* (["\n", "\r"])>
157 /* Above are specification-only tokens */
166 <OPTIONS: "@Options:">
168 <GLOBAL_DEFINE: "@Global_define:">
170 <DECLARE_VAR: "@DeclareVar:">
172 <INIT_VAR: "@InitVar:">
174 <DEFINE_FUNC: "@DefineFunc:">
176 <INTERFACE_CLUSTER: "@Interface_cluster:">
178 <HAPPENS_BEFORE: "@Happens_before:">
180 <INTERFACE: "@Interface:">
182 <COMMIT_POINT_SET: "@Commit_point_set:">
184 <ENTRY_POINT: "@Entry_point">
186 <INTERFACE_DEFINE: "@Interface_define:">
188 <CONDITION: "@Condition:">
190 <HB_CONDITION: "@HB_condition:">
198 <DEFINEVAR: "@DefineVar:">
202 <POST_ACTION: "@Post_action:">
204 <POST_CHECK: "@Post_check:">
206 <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
210 <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
212 <COMMIT_POINT_DEFINE: "@Commit_point_define:">
214 <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
217 /* Specification & C/C++ shared tokens */
221 <#LETTER: ["a"-"z", "A"-"Z"]>
223 <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
240 /* C/C++ only token*/
271 <GREATER_EQUALS: ">=">
275 <LOGICAL_EQUALS: "==">
295 ((~["\"","\\","\n","\r"])
297 ( ["n","t","b","r","f","\\","'","\""]
298 | ["0"-"7"] ( ["0"-"7"] )?
299 | ["0"-"3"] ["0"-"7"]
308 ((~["'","\\","\n","\r"])
310 (["n","t","b","r","f","\\","'","\""]
311 | ["0"-"7"] ( ["0"-"7"] )?
312 | ["0"-"3"] ["0"-"7"]
320 <DECIMAL_LITERAL> (["l","L"])?
321 | <HEX_LITERAL> (["l","L"])?
322 | <OCTAL_LITERAL> (["l","L"])?>
324 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
326 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
328 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
330 < FLOATING_POINT_LITERAL:
331 <DECIMAL_FLOATING_POINT_LITERAL>
332 | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
334 < #DECIMAL_FLOATING_POINT_LITERAL:
335 (["0"-"9"])+ "." (["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 | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
340 < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
342 < #HEXADECIMAL_FLOATING_POINT_LITERAL:
343 "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
344 | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
346 < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
355 LOOKAHEAD(3) res = Global_construct() |
356 LOOKAHEAD(3) res = Interface() |
357 LOOKAHEAD(3) res = Potential_commit_point_define() |
358 LOOKAHEAD(3) res = Commit_point_define() |
359 LOOKAHEAD(3) res = Commit_point_define_check() |
360 LOOKAHEAD(3) res = Entry_point() |
361 LOOKAHEAD(3) res = Interface_define()
365 //System.out.println(res);
370 GlobalConstruct Global_construct() :
373 SequentialDefineSubConstruct code;
374 HashMap<String, String> options;
380 options = new HashMap<String, String>();
385 ((key = <IDENTIFIER>.image)
387 (value = <IDENTIFIER>.image)
389 if (options.containsKey(key)) {
390 throw new ParseException("Duplicate options!");
392 options.put(key, value);
397 (code = Global_define())
398 { res = new GlobalConstruct(code, options); }
399 (Interface_clusters(res))?
400 (Happens_before(res))?
404 res.unfoldInterfaceCluster();
409 String C_CPP_CODE() :
416 text = new StringBuilder();
422 t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
423 t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
424 t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
425 t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
426 t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
427 t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
428 t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
429 t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
430 t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
433 text.append(t.image);
434 if (t.image.equals(";") || t.image.equals("\\")
435 || t.image.equals("{") || t.image.equals("}"))
442 //System.out.println(text);
443 return text.toString();
447 SequentialDefineSubConstruct Global_define() :
449 String declareVar, initVar, defineFunc;
458 (<DECLARE_VAR> (declareVar = C_CPP_CODE()))?
459 (<INIT_VAR> (initVar = C_CPP_CODE()))?
460 (<DEFINE_FUNC> (defineFunc = C_CPP_CODE()))?
462 SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
463 //System.out.println(res);
468 ConditionalInterface Conditional_interface() :
470 String interfaceName, hbConditionLabel;
474 hbConditionLabel = "";
476 interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
477 <IDENTIFIER>.image <CLOSE_BRACKET>)?
479 return new ConditionalInterface(interfaceName, hbConditionLabel);
483 void Interface_cluster(GlobalConstruct inst) :
486 ConditionalInterface condInterface;
489 (clusterName= <IDENTIFIER>.image)
490 <EQUALS> <OPEN_PAREN>
491 (condInterface = Conditional_interface()
492 { inst.addInterface2Cluster(clusterName, condInterface); }
494 (<COMMA> condInterface = Conditional_interface()
495 { inst.addInterface2Cluster(clusterName, condInterface); }
500 void Interface_clusters(GlobalConstruct inst) :
503 <INTERFACE_CLUSTER> (Interface_cluster(inst))+
506 void Happens_before(GlobalConstruct inst) :
508 ConditionalInterface left, right;
513 left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
514 { inst.addHBCondition(left, right); }
518 InterfaceConstruct Interface() :
520 InterfaceConstruct res;
521 String interfaceName, condition, idCode, check, postAction,
522 postCheck, commitPoint, hbLabel, hbCondition;
523 ActionSubConstruct action;
524 ArrayList<String> commitPointSet;
525 HashMap<String, String> hbConditions;
536 commitPointSet = new ArrayList<String>();
537 hbConditions = new HashMap<String, String>();
541 <INTERFACE> (interfaceName = <IDENTIFIER>.image)
543 (commitPoint = <IDENTIFIER>.image
544 { commitPointSet.add(commitPoint); }
547 (commitPoint = <IDENTIFIER>.image)
549 if (commitPointSet.contains(commitPoint)) {
550 throw new ParseException(interfaceName + " has" +
551 "duplicate commit point labels");
553 commitPointSet.add(commitPoint);
557 (<CONDITION> (condition = C_CPP_CODE()))?
560 (hbLabel = <IDENTIFIER>.image)
561 (hbCondition = C_CPP_CODE())
563 if (hbConditions.containsKey(hbLabel)) {
564 throw new ParseException(interfaceName + " has" +
565 "duplicate happens-before condtion labels");
567 hbConditions.put(hbLabel, hbCondition);
570 (<ID> (idCode = C_CPP_CODE()))?
571 (<CHECK> (check = C_CPP_CODE()))?
573 (<POST_ACTION> (postAction = C_CPP_CODE()))?
574 (<POST_CHECK> (postCheck = C_CPP_CODE()))?
578 res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
579 hbConditions, idCode, check, action, postAction, postCheck);
584 ActionSubConstruct Action() :
586 String type, name, expr, defineVarStr, code;
587 ArrayList<DefineVar> defineVars;
591 defineVars = new ArrayList<DefineVar>();
597 (<DEFINEVAR> (defineVarStr = C_CPP_CODE())
599 int eqIdx = defineVarStr.indexOf('=');
600 int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
601 type = defineVarStr.substring(0, typeEnd);
602 name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
603 expr = defineVarStr.substring(eqIdx + 2);
604 DefineVar defineVar = new DefineVar(type, name, expr);
605 defineVars.add(defineVar);
606 })* (<CODE> (code = C_CPP_CODE()))? )
610 ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
615 PotentialCPDefineConstruct Potential_commit_point_define() :
617 PotentialCPDefineConstruct res;
618 String label, condition;
625 <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
626 <LABEL> (label = <IDENTIFIER>.image)
630 res = new PotentialCPDefineConstruct(label, condition);
636 CPDefineConstruct Commit_point_define() :
638 CPDefineConstruct res;
639 String label, potentialCPLabel, condition;
646 <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
647 <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
648 <LABEL> (label = <IDENTIFIER>.image)
652 res = new CPDefineConstruct(label, potentialCPLabel, condition);
658 CPDefineCheckConstruct Commit_point_define_check() :
660 CPDefineCheckConstruct res;
661 String label, condition;
668 <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
669 <LABEL> (label = <IDENTIFIER>.image)
673 res = new CPDefineCheckConstruct(label, condition);
678 EntryPointConstruct Entry_point() :
688 return new EntryPointConstruct();
692 InterfaceDefineConstruct Interface_define() :
699 <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
703 return new InterfaceDefineConstruct(name);