/* Minijava Grammar */ import java_cup.runtime.ComplexSymbolFactory; import java_cup.runtime.ScannerBuffer; import java_cup.runtime.XMLElement; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; import java.io.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; parser code {: public Parser(Lexer lex, ComplexSymbolFactory sf) { super(lex,sf); } public static void main(String[] args) throws Exception { // initialize the symbol factory ComplexSymbolFactory csf = new ComplexSymbolFactory(); // create a buffering scanner wrapper ScannerBuffer lexer = new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csf)); // start parsing Parser p = new Parser(lexer,csf); ParseNode pn = (ParseNode) p.parse().value; } :}; terminal SEMICOLON, COMMA, LPAR, RPAR, LANG, RANG, BEGIN, END, ASSIGN; terminal PUBLIC, INTERFACE, CAPABILITY, DESCRIPTION, METHOD, REQUIRES, WITH, AS; terminal TYPE; terminal IDENT, STRINGCONST; non terminal ParseNode policy; non terminal ParseNode intface, methlist, meth, paramlist, param; non terminal ParseNode capablist, capab, capabcont, cont; non terminal ParseNode reqlist, require, capintlist; /** * A policy file normally consists of: * 1) Interface * - Interface definition * - List of capabilities and their contents * * We also define "requires" statements for users * to declare their required capabilities in the * generated interfaces * 2) List of generated interfaces (requires) */ policy ::= intface:in {: ParseNode pn = new ParseNode("policy"); pn.addChild(in); RESULT = pn; :} | reqlist:rl {: ParseNode pn = new ParseNode("policy"); pn.addChild(rl); RESULT = pn; :} ; //1) Interface class definition // 1) Interface definition // 2) Library list // 3) Driver list // Interface intface ::= PUBLIC INTERFACE IDENT:idint BEGIN methlist:ml capablist:cl END {: ParseNode pn = new ParseNode("interface"); pn.addChild("intface_ident").setLiteral(idint); pn.addChild(ml); pn.addChild(cl); RESULT = pn; :} ; methlist ::= methlist:ml meth:m {: ml.addChild(m); RESULT = ml; :} | /* empty */ {: ParseNode pn = new ParseNode("method_list"); RESULT = pn; :} ; meth ::= PUBLIC TYPE:typemeth IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON {: ParseNode pn = new ParseNode("method"); pn.addChild("method_type").setLiteral(typemeth); pn.addChild("method_ident").setLiteral(idmeth); pn.addChild(pl); RESULT = pn; :} | PUBLIC IDENT:clsmeth IDENT:idmeth LPAR paramlist:pl RPAR SEMICOLON {: ParseNode pn = new ParseNode("method"); pn.addChild("method_class").setLiteral(clsmeth); pn.addChild("method_ident").setLiteral(idmeth); pn.addChild(pl); RESULT = pn; :} ; paramlist ::= paramlist:pl param:p {: pl.addChild(p); RESULT = pl; :} | /* empty */ {: ParseNode pn = new ParseNode("param_list"); RESULT = pn; :} ; param ::= TYPE:typeprm IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_type").setLiteral(typeprm); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | TYPE:typeprm IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_type").setLiteral(typeprm); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral(clsprm); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral(clsprm); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} /* generic/template with one type, e.g. set */ | IDENT:clsprm LANG TYPE:typegen RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} /* generic/template with two types, e.g. map */ | IDENT:clsprm LANG TYPE:typegen1 COMMA TYPE:typegen2 RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen1 + "," + typegen2 + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG TYPE:typegen COMMA IDENT:clsgen RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + "," + clsgen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen COMMA TYPE:typegen RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + "," + typegen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen1 COMMA IDENT:clsgen2 RANG IDENT:idprm {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen1 + "," + clsgen2 + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} /* Add comma at the end... */ /* generic/template with one type, e.g. set */ | IDENT:clsprm LANG TYPE:typegen RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} /* generic/template with two types, e.g. map */ | IDENT:clsprm LANG TYPE:typegen1 COMMA TYPE:typegen2 RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen1 + "," + typegen2 + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG TYPE:typegen COMMA IDENT:clsgen RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + typegen + "," + clsgen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen COMMA TYPE:typegen RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen + "," + typegen + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} | IDENT:clsprm LANG IDENT:clsgen1 COMMA IDENT:clsgen2 RANG IDENT:idprm COMMA {: ParseNode pn = new ParseNode("param"); pn.addChild("param_class").setLiteral((String)clsprm + "<" + clsgen1 + "," + clsgen2 + ">"); pn.addChild("param_ident").setLiteral(idprm); RESULT = pn; :} ; //2) List of capabilities and their respective contents, i.e. description, method, etc. capablist ::= capablist:cl capab:cap {: cl.addChild(cap); RESULT = cl; :} | /* empty */ {: ParseNode pn = new ParseNode("capab_list"); RESULT = pn; :} ; capab ::= CAPABILITY IDENT:idcap BEGIN capabcont:ccont END {: ParseNode pn = new ParseNode("capability"); pn.addChild("capab_ident").setLiteral(idcap); pn.addChild(ccont); RESULT = pn; :} ; capabcont ::= capabcont:ccont cont:cnt {: ccont.addChild(cnt); RESULT = ccont; :} | /* empty */ {: ParseNode pn = new ParseNode("capab_content"); RESULT = pn; :} ; cont ::= DESCRIPTION:dsc ASSIGN STRINGCONST:strdsc SEMICOLON {: ParseNode pn = new ParseNode("capab_content"); pn.addChild("capab_desc").setLiteral(strdsc); RESULT = pn; :} | METHOD:mtd ASSIGN STRINGCONST:strmeth SEMICOLON {: ParseNode pn = new ParseNode("capab_content"); pn.addChild("capab_meth").setLiteral(strmeth); RESULT = pn; :} ; //3) List of interface generation definitions ("requires" statements) reqlist ::= reqlist:rl require:req {: rl.addChild(req); RESULT = rl; :} | /* empty */ {: ParseNode pn = new ParseNode("reqlist"); RESULT = pn; :} ; require ::= REQUIRES IDENT:idint WITH capintlist:cil AS INTERFACE IDENT:idnewint SEMICOLON {: ParseNode pn = new ParseNode("requires"); pn.addChild("intface_ident").setLiteral(idint); pn.addChild(cil); pn.addChild("new_intface_ident").setLiteral(idnewint); RESULT = pn; :} ; capintlist ::= IDENT:idcap {: ParseNode pn = new ParseNode("capab_ident_list"); pn.addChild("capab_ident").setLiteral(idcap); RESULT = pn; :} | capintlist:cil COMMA IDENT:idcap {: cil.addChild("capab_ident").setLiteral(idcap); RESULT = cil; :} | /* empty */ {: ParseNode pn = new ParseNode("capab_ident_list"); RESULT = pn; :} ;