/* * xtc - The eXTensible Compiler * Copyright (C) 2009-2011 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.InputStreamReader; import java.io.BufferedReader; 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.6 $ */ public class ActionGenerator { public static void main(String args[]) throws Exception { BufferedReader inputStream = null; PrintWriter outputStream = null; if (args.length != 1) { System.err.println("Please specify a class name."); System.exit(1); } String className = args[0]; try { String l; HashSet<Integer> list; HashMap<Integer, String> action; HashSet<Integer> layout; HashSet<Integer> passthrough; HashSet<Integer> complete; outputStream = new PrintWriter(System.out); outputStream.print("" + "/*\n" + " * xtc - The eXTensible Compiler\n" + " * Copyright (C) 2009-2011 New York University\n" + " *\n" + " * This library is free software; you can redistribute it and/or\n" + " * modify it under the terms of the GNU Lesser General Public License\n" + " * version 2.1 as published by the Free Software Foundation.\n" + " *\n" + " * This library 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 GNU\n" + " * Lesser General Public License for more details.\n" + " *\n" + " * You should have received a copy of the GNU Lesser General Public\n" + " * License along with this library; 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" + "/**\n" + " * This class is generated from grammar annotations and provides semantic\n" + " * value and action support.\n" + " */\n" ); inputStream = new BufferedReader(new InputStreamReader(System.in)); list = new HashSet<Integer>(); layout = new HashSet<Integer>(); action = new HashMap<Integer, String>(); passthrough = new HashSet<Integer>(); complete = new HashSet<Integer>(); 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 < ForkMergeParserTables.yytname.table.length; i++) { if (ForkMergeParserTables.yytname.table[i].equals(name)) { sym = i; break; } } if (sym >= 0) { if (type.equals("list")) { list.add(sym); } else if (type.equals("layout")) { layout.add(sym); } else if (type.equals("action")) { action.put(sym, name); } else if (type.equals("passthrough")) { passthrough.add(sym); } else if (type.equals("complete")) { complete.add(sym); } else { System.err.println("error: node " + name + " has unknown " + "type " + type); } } else { System.err.println("error: there is no node " + name + " in the " + "grammar"); } } boolean isAbstract = false; if (action.size() > 0) { // Then this class an abstract one that needs to be // overridden. isAbstract = true; } outputStream.print("" + "public" + (isAbstract ? " abstract" : "") + " class " + className + " extends Actions {\n" + "\n" ); outputStream.print("" + " public ValueType getValueType(int id) {\n" + " switch (id) {\n" ); for (int i = 0; i < ForkMergeParserTables.yytname.table.length; i++) { String delim; outputStream.print("" + " case " + i + ": // " + ForkMergeParserTables.yytname.table[i] + "\n" ); if (list.contains(i)) { outputStream.print("" + " return ValueType.LIST;\n\n" ); } else if (layout.contains(i)) { outputStream.print("" + " return ValueType.LAYOUT;\n\n" ); } else if (action.containsKey(i)) { outputStream.print("" + " return ValueType.ACTION;\n\n" ); } else if (passthrough.contains(i)) { outputStream.print("" + " return ValueType.PASS_THROUGH;\n\n" ); } else { outputStream.print("" + " return ValueType.NODE;\n\n" ); } } outputStream.print("" + " default:\n" + " throw new RuntimeException();\n" + " }\n" + " }\n" + "\n"); outputStream.print("" + " public boolean isComplete(int id) {\n" + " switch(id) {\n"); for (Integer i : complete) { outputStream.print("" + " case " + i + ": " + "// " + ForkMergeParserTables.yytname.table[i] + "\n" + " return true;\n\n"); } outputStream.print("" + " default:\n" + " return false;\n" + " }\n" + " }\n" + "\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"); for (Integer i : action.keySet()) { outputStream.print("" + " public abstract void " + action.get(i) + "(Subparser subparser);\n\n"); } } outputStream.print("" + "}\n"); } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }