public static void generateParser(Grammar g, String target) throws FileNotFoundException { g.prepareToGeneration(); PrintWriter out = new PrintWriter(target + "/Node.java"); // out.println("import Lexer;\n"); // out.println("package nodes;\n"); out.println("class Node {"); out.println("\tNode[] children;"); out.println("\tpublic String text;"); out.println("}"); out.close(); out = new PrintWriter(target + "/TerminalNode.java"); out.println( "public class TerminalNode extends Node {\n\n" + "\tpublic TerminalNode(Lexer lx) {\n" + "\t\ttext = lx.getNext();\n" + "\t\tchildren = new Node[0];\n" + "\t}"); out.println("}"); out.close(); out = new PrintWriter(target + "/EpsNode.java"); out.println( "public class EpsNode extends Node {\n\n" + "\tpublic EpsNode() {\n" + "\t\ttext = \"EPS\";\n" + "\t\tchildren = new Node[0];\n" + "\t}"); out.println("}"); out.close(); for (NonTerminal nt : g.nterms) { out = new PrintWriter(target + "/" + nt.getName() + "Node.java"); out.println("import java.util.*;"); out.println("class " + nt.getName() + "Node extends Node {"); for (Attribute at : nt.atts) { out.println("\tpublic " + at.type + " " + at.name + ";"); } out.println(); out.println("\tpublic " + nt.getName() + "Node(Lexer lx) {"); for (Rule r : nt.rules) { HashSet<String> good = new HashSet<String>(); if (r.getChildCount() == 0) { good = nt.FOLLOW; } else { if (r.children.get(0).isTerminal()) { good.add(r.children.get(0).getName()); } else { good.addAll(((NonTerminal) (r.children.get(0))).FIRST); } } out.print("\t\tif ("); boolean first = true; if (r.getChildCount() == 0) { out.print("lx.nextIsEOF"); first = false; } for (String t : good) { if (!first) out.print(" || "); first = false; out.print("lx.nextIs" + t + ""); } out.println(") {"); if (r.children.size() == 0) { out.println("\t\t\tchildren = new Node[1];"); out.println("\t\t\tchildren[0] = new EpsNode();"); } else { out.println("\t\t\tchildren = new Node[" + r.children.size() + "];"); for (int i = 0; i < r.children.size(); i++) { Node n = r.children.get(i); if (n.isTerminal()) { out.println("\t\t\tchildren[" + i + "] = new TerminalNode(lx);"); } else { out.println("\t\t\tchildren[" + i + "] = new " + n.getName() + "Node(lx);"); } } } if (r.code != null) { String outCode = r.code; // System.err.println("--"); // System.err.println(outCode); // System.err.println("@"); for (int i = 0; i < r.getChildCount(); i++) { if (!r.children.get(i).isTerminal()) outCode = outCode.replaceAll( "_" + i, "((" + r.children.get(i).getName() + "Node)(children[" + i + "]))"); else outCode = outCode.replaceAll("_" + i, "children[" + i + "]"); } // System.err.println(outCode); out.println(outCode); } out.println("\t\t\treturn;"); out.println("\t\t}"); } out.println("\t\tthrow new AssertionError(\"unexpected token :\" + lx.getNext());"); out.println("\t}"); out.println("}"); out.close(); } }