header{ package dk.kb.tdiagrams.parser.compiler; import dk.kb.tdiagrams.parser.diagram.*; import dk.kb.tdiagrams.parser.control.*; } class P extends Parser; options { buildAST=true; } tokens { APPDECL; CONVDECL; INTRDECL; MACHDECL; PGM; BODY; PIECE; HEST; DECL; APPID; APP; CONVID; CONV; ANCHORID; ANCHOR; INTR;INTRID; PRES; PROGRAM; COMPLETE; IDENTIFIER; } // Pieces apppiece: ( "App"^ LPAR! ID RPAR! ) ; convpiece: ( "Conv"^ LPAR! ID KOMMA! ID KOMMA! ID RPAR! ) ; intrpiece: ( "Intr"^ LPAR! ID KOMMA! ID RPAR! ); machpiece: ( "Mach"^ LPAR! ID RPAR!); //decl appdecl!: a:apppiece ID { #appdecl = #([APPDECL,"appd"], ID , #a ); } ; convdecl!: c:convpiece ID { #convdecl = #([CONVDECL,"convd"], ID , #c ); } ; intrdecl!: i:intrpiece ID { #intrdecl = #([INTRDECL,"intrd"], ID , #i ); } ; machdecl!: m:machpiece ID { #machdecl = #([MACHDECL,"machd"], ID , #m ); } ; appa:! i:ID { #appa = #( [APPID,"appid"], i ) ; } | app ; app!: "app" DASH "convert" a:appa "with"! c:convc "rooted" "by"! an:anchora "as" i:ID { #app = #([APP,"a-convert"], i,#a,#c,#an) ; } ; convc:! i:ID { #convc = #( [CONVID,"convid"], i) ; } | conv ; conv!: "conv" DASH "convert"^ c1:convc "with"! c2:convc "rooted"! "by"! an:anchora "as" i:ID { #conv = #([CONV,"c-convert"], i, #c1,#c2,#an) ; } ; intrid:! i:ID { #intrid = #([INTRID,"intrid"], i) ; } ; intri: intrid | intr ; intr!: ("combine"^ i1:intrid "with"! in:intri) "as"^ i:ID { #intr = #( [INTR,"combine"], i, #i1,#in) ; } ; anchora:! i:ID { #anchora = #( [ANCHORID,"anchorid"], i ) ; } | anchor; anchor!: ("root"^ in:intri "with"! an:anchora) "as"^ i:ID { #anchor = #([ANCHOR,"anchor"],i, #in, #an) ; } ; pgm!: d:decls // one or more SEP^ // -- p:pres // zero or more pres "run"^ LPAR! b:body RPAR! EOF! { #pgm = #([PROGRAM,"run"], #d, #p, ([BODY,"body"], #b)) ; } ; //decls: (decl SEMI) => decl SEMI^ decls decls: ( decl SEMI! )+ { #decls = #([DECL,"decls"], #decls); } ; // | decl // ; decl: appdecl | convdecl | intrdecl | machdecl ; body: !(appa "with") => a:appa "with"! an:anchora { #body = #([COMPLETE,"complete"], #a, #an) ; } | anchor | intr | conv | app |! i:ID { #body = #([IDENTIFIER,"identifier"], i ) ; } ; pre: | conv | anchor | intr | app ; pres: ( pre SEMI! )* { #pres = #([PRES,"pres"], #pres) ; } ; class L extends Lexer; options { k=3; // needed for newline junk charVocabulary='\u0000'..'\u007F'; // allow ascii testLiterals=false; // don't automatically test for literals } // Identifier ID options {testLiterals=true;} : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$'|'.')* ; // Signs LPAR: '(' ; RPAR: ')' ; KOMMA: ','; SEMI: ';'; SEP: DASH DASH; DASH: '-'; // Single-line comments (stolen from // http://www.antlr.org/grammar/java/java.g (changed // to # ) SL_COMMENT : "#" (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$setType(Token.SKIP); newline();} ; WS : ( ' ' | '\t' | '\r' '\n' { newline(); } | '\n' { newline(); } | '\r' { newline(); } ) {$setType(Token.SKIP);} //ignore this token ; /**************************************************** ************************* TREE ********************* ****************************************************/ class TP extends TreeParser; options { importVocab=P; genHashLines=true; } pgm [ DiagramFactory df, NamespaceI n ] returns [ControlResult r] throws TreeParserException { DiagramI ret; r = new ControlResult(null,null); } : #(PROGRAM decls[df,n] pres[df,n] #(BODY ret=body[df,n])) { r = new ControlResult(ret,n); } ; decls [DiagramFactory df, NamespaceI r] throws TreeParserException : #(DECL (decl[df,r])+) ; // just get the formatdescriptions apppiece returns [ String r ] { r = null; } : #("App" i:ID) { r = i.getText(); } ; intrpiece returns [ String[] r ] { r= new String[2]; } : #("Intr" i1:ID i2:ID) { r[0] = i1.getText(); r[1] = i2.getText(); } ; convpiece returns [ String[] r ] { r= new String[3]; } : #("Conv" i1:ID i2:ID i3:ID) { r[0] = i1.getText(); r[1] = i2.getText(); r[2] = i3.getText(); } ; machpiece returns [ String r ] { r= null; } : #("Mach" i:ID) { r = i.getText(); } ; // Take the given formatdescriptions from the piece and save it in the namespace appdecl [ DiagramFactory df, NamespaceI r ] throws TreeParserException { String a; } : #(APPDECL i:ID a=apppiece) { r.set(new Id(i.getText()), df.createApp(new Id(i.getText()),a)); } ; convdecl [DiagramFactory df, NamespaceI r ] throws TreeParserException { String[] c; } : #(CONVDECL i:ID c=convpiece) { r.set(new Id(i.getText()), df.createConv(new Id(i.getText()),c[0],c[1],c[2])); } ; intrdecl [ DiagramFactory df, NamespaceI r] throws TreeParserException { String[] a; } : #(INTRDECL i:ID a=intrpiece) { r.set(new Id(i.getText()), df.createIntr(new Id(i.getText()),a[0],a[1])); } ; machdecl [ DiagramFactory df, NamespaceI r ] throws TreeParserException { String m; } : #(MACHDECL i:ID m=machpiece) { r.set(new Id(i.getText()), df.createMach(new Id(i.getText()),m)); } ; // Decent with the right ''type'' decl [ DiagramFactory df, NamespaceI r] throws TreeParserException : appdecl[df,r] | convdecl[df,r] | intrdecl[df,r] | machdecl[df,r] ; // parse all the pres pres [ DiagramFactory df, NamespaceI r ] throws TreeParserException { DiagramI ret=null; } : #(PRES (ret=pre[df,r])*) ; pre [ DiagramFactory df, NamespaceI r ] returns [ DiagramI ret ] throws TreeParserException { ret = null;} : ret=anchor[df,r] | ret=app[df,r] | ret=intr[df,r] | ret=conv[df,r] ; anchor [ DiagramFactory df, NamespaceI a] returns [ MachI r ] throws TreeParserException { IntrI it; MachI an; r = null; } // Take the given ID and save the resulting constructed anchor in the namespace : #(ANCHOR i:ID it=intri[df,a] an=anchora[df,a]) { r = df.createMach(new Id(i.getText()), it, // the top used in constructing this piece an); // the bottome used in constructing this piece a.set(new Id(i.getText()),r); } ; // either just decent into the construction constructions else try to fetch the // piece from the namespace to ensure that it's present and the right kind. anchora [ DiagramFactory df, NamespaceI a] returns [ MachI r ] throws TreeParserException { r=null; } : r=anchor[df,a] | #(ANCHORID i:ID) { try { r = (MachI)a.get(new Id(i.getText()), MachI.class ); }catch(NotFoundException n){ throw new TreeParserException(i.getText()+" isnt declared ("+i.getLine()+")"); }catch(ExpectException n){ throw new TreeParserException(i.getText()+" is "+n.found+" but Mach was expected"); } } ; // Create a new App object with construction info from the recursive decent app [ DiagramFactory df, NamespaceI a ] returns [ AppI r ] throws TreeParserException { r = null; AppI ap; ConvI cv; MachI an; } : #(APP i:ID ap=appa[df,a] cv=convc[df,a] an=anchora[df,a]) { r = df.createApp( (new Id(i.getText())), ap, an, cv // the origin ); a.set(new Id(i.getText()),r); } ; appa [ DiagramFactory df, NamespaceI a ] returns [ AppI r ] throws TreeParserException { r=null; } : r=app[df,a] | #(APPID i:ID) { try { r = (AppI)a.get(new Id(i.getText()), AppI.class ); }catch(NotFoundException n){ throw new TreeParserException(i.getText()+" isnt declared ("+i.getLine()+")"); }catch(ExpectException n){ throw new TreeParserException(i.getText()+" is "+n.found+" but App was expected"); } } ; conv [ DiagramFactory df, NamespaceI a ] returns [ ConvI r ] throws TreeParserException { ConvI c1,c2; MachI an; r = null; } : #(CONV i:ID c1=convc[df,a] c2=convc[df,a] an=anchora[df,a]) { r = df.createConv(new Id(i.getText()), c1, an, c2 // origin ); a.set(new Id(i.getText()),r); } ; convc [ DiagramFactory df, NamespaceI a ] returns [ ConvI r ] throws TreeParserException { r= null; } : r=conv[df,a] | #(CONVID i:ID) { try { r = (ConvI)a.get(new Id(i.getText()), ConvI.class ); }catch(NotFoundException n){ throw new TreeParserException(i.getText()+" isnt declared ("+i.getLine()+")"); }catch(ExpectException n){ throw new TreeParserException(i.getText()+" is "+n.found+" but Conv was expected"); } } ; intr [ DiagramFactory df, NamespaceI a ] returns [ IntrI r ] throws TreeParserException { IntrI i1,i2; r = null; } : #(INTR i:ID i1=intrid[df,a] i2=intri[df,a]) { r = df.createIntr(new Id(i.getText()), i1, i2); a.set(new Id(i.getText()),r); } ; intri [ DiagramFactory df, NamespaceI a ] returns [ IntrI r ] throws TreeParserException { r = null; } : r=intr[df,a] | r=intrid[df,a]; intrid [ DiagramFactory df, NamespaceI a ] returns [ IntrI r ] throws TreeParserException { r= null; } : #(INTRID i:ID) { try { r = (IntrI)a.get(new Id(i.getText()), IntrI.class ); }catch(NotFoundException n){ throw new TreeParserException(i.getText()+" isnt declared ("+i.getLine()+")"); }catch(ExpectException n){ throw new TreeParserException(i.getText()+" is "+n.found+" but Intr was expected"); } } ; body[ DiagramFactory df, NamespaceI a] returns [ DiagramI r ] throws TreeParserException { AppI ap; MachI an; DiagramI d; r = null; } : #(COMPLETE ap=appa[df,a] an=anchora[df,a]) { r = df.createComplete(ap,an); a.set(new Id("___COMPLETE___"),r); } | d=anchor[df,a] { r = d;} | d=intr[df,a] { r=d; } | d=conv[df,a] { r=d; } | d=app[df,a] { r=d; } | #(IDENTIFIER i:ID) { try { r = a.get(new Id(i.getText()) ); }catch(NotFoundException n){ throw new TreeParserException(i.getText()+" isnt declared ("+i.getLine()+")"); } } ;