/* * xtc - The eXTensible Compiler * Copyright (C) 2009-2012 New York University * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package xtc.lang.cpp; import java.lang.*; import java.io.BufferedReader; import java.io.FileReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.HashSet; import java.util.HashMap; /** * This class generates a base class for semantic actions for a * grammar. It takes "name, type" pairs from the standard input. * * @author Paul Gazzillo * @version $Revision: 1.11 $ */ public class GenerateActionsClass { public static void main(String args[]) throws Exception { BufferedReader inputStream = null; PrintWriter outputStream = null; if (args.length < 2) { System.err.println("USAGE: GenerateValuesClass outClassName" + " parseTablesClassName [all]"); System.err.println("\n" + "This will create an abstract java class with methods for each action" + "annotation. Specifying \"all\" will create a java class with empty" + "methods for every production, regardless of annotation."); System.exit(1); } String outClassName = args[0]; String parseTablesClassName = args[1]; String actionSwitchFile = args.length > 2 ? args[2] : null; String prologueFile = args.length > 3 ? args[3] : null; String epilogueFile = args.length > 4 ? args[4] : null; ParseTables parseTables = (ParseTables) Class.forName(parseTablesClassName).newInstance(); try { String l; HashMap<Integer, String> action; outputStream = new PrintWriter(System.out); outputStream.print("" + "/*\n" + " * xtc - The eXTensible Compiler\n" + " * Copyright (C) 2009-2012 New York University\n" + " *\n" + " * This program is free software; you can redistribute it and/or\n" + " * modify it under the terms of the GNU General Public License\n" + " * version 2 as published by the Free Software Foundation.\n" + " *\n" + " * This program is distributed in the hope that it will be useful,\n" + " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + " * GNU General Public License for more details.\n" + " *\n" + " * You should have received a copy of the GNU General Public License\n" + " * along with this program; if not, write to the Free Software\n" + " * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n" + " * USA.\n" + " */\n" + "package xtc.lang.cpp;\n" + "\n" + "import xtc.lang.cpp.ForkMergeParser.Subparser;\n" + "\n"); if (null != prologueFile) { inputStream = new BufferedReader(new FileReader(prologueFile)); outputStream.println("/* from " + prologueFile + " */"); while ((l = inputStream.readLine()) != null) { outputStream.println(l); } } outputStream.print("" + "\n" + "/**\n" + " * This class is generated from grammar annotations and provides semantic\n" + " * action support.\n" + " */\n" ); action = new HashMap<Integer, String>(); inputStream = new BufferedReader(new InputStreamReader(System.in)); while ((l = inputStream.readLine()) != null) { String[] a = l.split(" "); String name = a[0]; String type = a[1]; int sym = -1; for (int i = 0; i < parseTables.yytname.length; i++) { if (parseTables.yytname[i].equals(name)) { sym = i; break; } } if (sym >= 0) { if (type.equals("action")) { action.put(sym, name); } } else { System.err.println("error: there is no node " + name + " in the " + "grammar"); } } outputStream.print("" + "public class " + outClassName + " implements SemanticActions {\n" + "\n" + " /** The instance of this class */\n" + " private static " + outClassName + " ref;\n" + "\n" + " /** Get the instance of this class */\n" + " public static " + outClassName + " getInstance() {\n" + " if (null == ref) {\n" + " ref = new " + outClassName + "();\n" + " }\n" + " return ref;\n" + " }\n" + "\n"); outputStream.print("" + " public Object action(int production, Subparser subparser, Object value) {\n"); if (null != actionSwitchFile) { inputStream = new BufferedReader(new FileReader(actionSwitchFile)); outputStream.print("" + " switch (production) {\n"); while ((l = inputStream.readLine()) != null) { outputStream.println(l); } outputStream.print("" + " }\n" + " return value;\n"); } else { outputStream.print("return null;\n"); } outputStream.print("" + " }\n"); if (action.size() > 0) { outputStream.print("" + " public void dispatch(int id, Subparser subparser) {\n" + " switch(id) {\n"); for (Integer i : action.keySet()) { String name = action.get(i); outputStream.print("" + " case " + i + ":\n" + " " + name + "(subparser);\n" + " break;\n\n"); } outputStream.print("" + " default:\n" + " // Do nothing\n" + " break;\n" + " }\n" + " }\n" + "\n"); } else { outputStream.print("" + " public void dispatch(int id, Subparser subparser) {\n" + " // no action productions\n" + " }\n" ); } if (null != epilogueFile) { inputStream = new BufferedReader(new FileReader(epilogueFile)); outputStream.println(" /* from " + epilogueFile + " */"); while ((l = inputStream.readLine()) != null) { outputStream.println(l); } } outputStream.print("" + "}\n"); } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }