grammar opp; options{ language=Java; } @members{ //Aqui ficar‹o as coisas que fazem parte do estado do sistema (neste caso o compilador) ex: //Erros e notificadores de erros... //Fun¨›es... String errors = ""; boolean has_errors = false; float distancebetween2points(Hashtable env, String id1, String id2){ float dist; Point p1=(Point)env.get(id1); Point p2=(Point)env.get(id2); dist=(float)Math.sqrt(Math.pow(p2.getX()-p1.getX(),2)+ Math.pow(p2.getY()-p1.getY(),2)); return dist; } private static void createFile(String filename, String content){ try{ // Create file FileWriter fstream = new FileWriter(filename); BufferedWriter out = new BufferedWriter(fstream); out.write(content); //Close the output stream out.close(); } catch (Exception e){//Catch exception if any System.err.println("Error: " + e.getMessage()); } } } @header{ import java.util.Hashtable; import java.awt.Point; import java.lang.Math; import java.io.*; } opp returns [Hashtable outEnv, String code] @after{ System.out.println(errors); System.out.println($opp.code); this.createFile("output_opp.dot", $opp.code); } : points[new Hashtable()] routes[$points.outEnv] { $opp.outEnv=$points.outEnv; $opp.code="Digraph G{\n" + $routes.code+ "\n}"; } ; points [Hashtable inEnv] returns [Hashtable outEnv] @after{ System.out.println($points.outEnv); } : a=point [$points.inEnv] (b=point[a] { a = b; } )* { $points.outEnv=b; } ; point [Hashtable inEnv] returns [Hashtable outEnv] : LETTER '(' a1=INT ',' a2=INT')' { $point.outEnv=$point.inEnv; $point.outEnv.put($LETTER.text,new Point(Integer.parseInt($a1.text),Integer.parseInt($a2.text))); } ; routes [Hashtable inEnv] returns [int cont, String code] : a=route[$routes.inEnv, 0, ""] (b=route[a.outEnv, a.outCont, a.outCode] { a=b; } )* { $routes.cont = a.outCont; $routes.code = a.outCode; } ; route [Hashtable inEnv, int inCont, String inCode] returns [Hashtable outEnv, int outCont, String outCode] : name age '(' list [$route.inEnv, $name.text] ')' { $route.outCont = $route.inCont + 1; $route.outCode = $route.inCode + "\n" + $route.outCont + "[style=bold, color=blue, label = \"The "+ $name.text + " with the lenght" + $list.sum + " for people " + $age.text + " years old\"]\n" + $list.code; $route.outEnv = $route.inEnv; } ; age returns [String text] : '(' '>' INT ')' { $age.text = $INT.text; } ; list [Hashtable inEnv, String name] returns [float sum, String code] @init{ float aux = 0; String lastpoint = ""; String aux_code = ""; int aux_sum = 0; } : a1=LETTER { if (!($list.inEnv.containsKey($a1.text))) { errors += "Error in path " + $list.name + " point id unknown " + $a1.text + "\n"; has_errors = true; } lastpoint=$a1.text; } (',' a2=LETTER { if (!($list.inEnv.containsKey($a2.text))) { errors += "Error in path " + $list.name + " point id unknown " + $a2.text + "\n"; has_errors = true; aux_code += ""; lastpoint = ""; aux_sum += 0; } else { aux = distancebetween2points($list.inEnv, lastpoint, $a2.text); aux_code += "\n" + lastpoint + "->" + $a2.text + "[style=bold, color=red, label=\"" + $list.name + ":" + aux + "\"]"; aux_sum += aux; lastpoint = $a2.text; } has_errors = false; } )* { has_errors = false; $list.code = aux_code; $list.sum = aux_sum; } ; name returns [String text] : STRING { $name.text= $STRING.text; } ; LETTER : ('A' .. 'Z') ; INT : ('0'..'9')+ ; COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} ; WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} ; STRING : '\'' (~('\'') )* '\'' ;