auto import from //branches/cupcake_rel/...@138607
diff --git a/tools/dasm/src/java_cup/Main.java b/tools/dasm/src/java_cup/Main.java
new file mode 100644
index 0000000..c816da1
--- /dev/null
+++ b/tools/dasm/src/java_cup/Main.java
@@ -0,0 +1,856 @@
+
+package java_cup;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Enumeration;
+
+/** This class serves as the main driver for the JavaCup system.
+ *  It accepts user options and coordinates overall control flow.
+ *  The main flow of control includes the following activities:
+ *  <ul>
+ *    <li> Parse user supplied arguments and options.
+ *    <li> Open output files.
+ *    <li> Parse the specification from standard input.
+ *    <li> Check for unused terminals, non-terminals, and productions.
+ *    <li> Build the state machine, tables, etc.
+ *    <li> Output the generated code.
+ *    <li> Close output files.
+ *    <li> Print a summary if requested.
+ *  </ul>
+ *
+ *  Options to the main program include: <dl>
+ *   <dt> -package name
+ *   <dd> specify package generated classes go in [default none]
+ *   <dt> -parser name
+ *   <dd> specify parser class name [default "parser"]
+ *   <dt> -symbols name
+ *   <dd> specify name for symbol constant class [default "sym"]
+ *   <dt> -nonterms
+ *   <dd> put non terminals in symbol constant class
+ *   <dt> -expect #
+ *   <dd> number of conflicts expected/allowed [default 0]
+ *   <dt> -compact_red
+ *   <dd> compact tables by defaulting to most frequent reduce
+ *   <dt> -nowarn
+ *   <dd> don't warn about useless productions, etc.
+ *   <dt> -nosummary
+ *   <dd> don't print the usual summary of parse states, etc.
+ *   <dt> -progress
+ *   <dd> print messages to indicate progress of the system
+ *   <dt> -time
+ *   <dd> print time usage summary
+ *   <dt> -dump_grammar
+ *   <dd> produce a dump of the symbols and grammar
+ *   <dt> -dump_states
+ *   <dd> produce a dump of parse state machine
+ *   <dt> -dump_tables
+ *   <dd> produce a dump of the parse tables
+ *   <dt> -dump
+ *   <dd> produce a dump of all of the above
+ *   <dt> -debug
+ *   <dd> turn on debugging messages within JavaCup
+ *   </dl>
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class Main {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+  /** Only constructor is private, so we do not allocate any instances of this
+      class. */
+  private Main() { }
+
+  /*-------------------------*/
+  /* Options set by the user */
+  /*-------------------------*/
+  /** User option -- do we print progress messages. */
+  protected static boolean print_progress   = false;
+  /** User option -- do we produce a dump of the state machine */
+  protected static boolean opt_dump_states  = false;
+  /** User option -- do we produce a dump of the parse tables */
+  protected static boolean opt_dump_tables  = false;
+  /** User option -- do we produce a dump of the grammar */
+  protected static boolean opt_dump_grammar = false;
+  /** User option -- do we show timing information as a part of the summary */
+  protected static boolean opt_show_timing  = false;
+  /** User option -- do we run produce extra debugging messages */
+  protected static boolean opt_do_debug     = false;
+  /** User option -- do we compact tables by making most common reduce the
+      default action */
+  protected static boolean opt_compact_red  = false;
+  /** User option -- should we include non terminal symbol numbers in the
+      symbol constant class. */
+  protected static boolean include_non_terms = false;
+  /** User option -- do not print a summary. */
+  protected static boolean no_summary = false;
+  /** User option -- number of conflicts to expect */
+  protected static int expect_conflicts = 0;
+
+  /*----------------------------------------------------------------------*/
+  /* Timing data (not all of these time intervals are mutually exclusive) */
+  /*----------------------------------------------------------------------*/
+  /** Timing data -- when did we start */
+  protected static long start_time       = 0;
+  /** Timing data -- when did we end preliminaries */
+  protected static long prelim_end       = 0;
+  /** Timing data -- when did we end parsing */
+  protected static long parse_end        = 0;
+  /** Timing data -- when did we end checking */
+  protected static long check_end        = 0;
+  /** Timing data -- when did we end dumping */
+  protected static long dump_end         = 0;
+  /** Timing data -- when did we end state and table building */
+  protected static long build_end        = 0;
+  /** Timing data -- when did we end nullability calculation */
+  protected static long nullability_end  = 0;
+  /** Timing data -- when did we end first set calculation */
+  protected static long first_end        = 0;
+  /** Timing data -- when did we end state machine construction */
+  protected static long machine_end      = 0;
+  /** Timing data -- when did we end table construction */
+  protected static long table_end        = 0;
+  /** Timing data -- when did we end checking for non-reduced productions */
+  protected static long reduce_check_end = 0;
+  /** Timing data -- when did we finish emitting code */
+  protected static long emit_end         = 0;
+  /** Timing data -- when were we completely done */
+  protected static long final_time       = 0;
+
+  /* Additional timing information is also collected in emit */
+
+  /** Path to create output files */
+  private static String out_path = null;
+
+  /*-----------------------------------------------------------*/
+  /*--- Main Program ------------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The main driver for the system.
+   * @param argv an array of strings containing command line arguments.
+   */
+  public static void main(String argv[])
+    throws internal_error, java.io.IOException, java.lang.Exception
+    {
+      boolean did_output = false;
+
+      start_time = System.currentTimeMillis();
+
+      /* process user options and arguments */
+      parse_args(argv);
+
+      /* open output files */
+      if (print_progress) System.err.println("Opening files...");
+      open_files();
+
+      prelim_end = System.currentTimeMillis();
+
+      /* parse spec into internal data structures */
+      if (print_progress)
+    System.err.println("Parsing specification from standard input...");
+      parse_grammar_spec();
+
+      parse_end = System.currentTimeMillis();
+
+      /* don't proceed unless we are error free */
+      if (lexer.error_count == 0)
+    {
+      /* check for unused bits */
+          if (print_progress) System.err.println("Checking specification...");
+          check_unused();
+
+          check_end = System.currentTimeMillis();
+
+      /* build the state machine and parse tables */
+          if (print_progress) System.err.println("Building parse tables...");
+          build_parser();
+
+          build_end = System.currentTimeMillis();
+
+      /* output the generated code */
+          if (print_progress) System.err.println("Writing parser...");
+          emit_parser();
+      did_output = true;
+
+          emit_end = System.currentTimeMillis();
+    }
+      else
+    {
+      /* fix up the times to make the summary easier */
+      emit_end = parse_end;
+    }
+
+      /* do requested dumps */
+      if (opt_dump_grammar) dump_grammar();
+      if (opt_dump_states)  dump_machine();
+      if (opt_dump_tables)  dump_tables();
+
+      dump_end = System.currentTimeMillis();
+
+      /* close output files */
+      if (print_progress) System.err.println("Closing files...");
+      close_files();
+
+      /* produce a summary if desired */
+      if (!no_summary) emit_summary(did_output);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Print a "usage message" that described possible command line options,
+   *  then exit.
+   * @param message a specific error message to preface the usage message by.
+   */
+  protected static void usage(String message)
+    {
+      System.err.println();
+      System.err.println(message);
+      System.err.println();
+      System.err.println(
+"Usage: " + version.program_name + " [options]\n" +
+"  and expects a specification file on standard input.\n" +
+"  Legal options include:\n" +
+"    -out path      specify the output files path [default current directory]\n" +
+"    -package name  specify package generated classes go in [default none]\n" +
+"    -parser name   specify parser class name [default \"parser\"]\n" +
+"    -symbols name  specify name for symbol constant class [default \"sym\"]\n"+
+"    -nonterms      put non terminals in symbol constant class\n" +
+"    -expect #      number of conflicts expected/allowed [default 0]\n" +
+"    -compact_red   compact tables by defaulting to most frequent reduce\n" +
+"    -nowarn        don't warn about useless productions, etc.\n" +
+"    -nosummary     don't print the usual summary of parse states, etc.\n" +
+"    -progress      print messages to indicate progress of the system\n" +
+"    -time          print time usage summary\n" +
+"    -dump_grammar  produce a human readable dump of the symbols and grammar\n"+
+"    -dump_states   produce a dump of parse state machine\n"+
+"    -dump_tables   produce a dump of the parse tables\n"+
+"    -dump          produce a dump of all of the above\n"
+      );
+      System.exit(1);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Parse command line options and arguments to set various user-option
+   *  flags and variables.
+   * @param argv the command line arguments to be parsed.
+   */
+  protected static void parse_args(String argv[])
+    {
+      int len = argv.length;
+      int i;
+
+      /* parse the options */
+      for (i=0; i<len; i++)
+    {
+      /* try to get the various options */
+      if (argv[i].equals("-package"))
+        {
+          /* must have an arg */
+          if (++i >= len || argv[i].startsWith("-") ||
+                argv[i].endsWith(".cup"))
+        usage("-package must have a name argument");
+
+          /* record the name */
+          emit.package_name = argv[i];
+        }
+      else if (argv[i].equals("-parser"))
+        {
+          /* must have an arg */
+          if (++i >= len || argv[i].startsWith("-") ||
+                argv[i].endsWith(".cup"))
+        usage("-parser must have a name argument");
+
+          /* record the name */
+          emit.parser_class_name = argv[i];
+        }
+      else if (argv[i].equals("-input")) {
+          /* must have an arg */
+          if (++i >= len || argv[i].startsWith("-") ||
+              argv[i].endsWith(".cup"))
+              usage("-input must have a name argument");
+
+          /* record the name */
+          emit.input_file_name = argv[i];
+      }
+      else if (argv[i].equals("-symbols"))
+        {
+          /* must have an arg */
+          if (++i >= len || argv[i].startsWith("-") ||
+                argv[i].endsWith(".cup"))
+        usage("-symbols must have a name argument");
+
+          /* record the name */
+          emit.symbol_const_class_name = argv[i];
+        }
+      else if (argv[i].equals("-nonterms"))
+        {
+          include_non_terms = true;
+        }
+      else if (argv[i].equals("-expect"))
+        {
+          /* must have an arg */
+          if (++i >= len || argv[i].startsWith("-") ||
+                argv[i].endsWith(".cup"))
+        usage("-expect must have a name argument");
+
+          /* record the number */
+          try {
+            expect_conflicts = Integer.parseInt(argv[i]);
+          } catch (NumberFormatException e) {
+        usage("-expect must be followed by a decimal integer");
+          }
+        }
+          else if (argv[i].equals("-out"))
+        {
+          /* must have an arg */
+              if (++i >= len || argv[i].startsWith("-"))
+                usage("-out must have a path argument");
+
+              /* validate path */
+              if (argv[i].length() != 0) {
+                out_path = argv[i] + File.separator;
+                File f = new File(out_path);
+                if (!f.exists() || !f.isDirectory())
+                  out_path = null;
+          }
+              if (out_path == null)
+                usage("-out argument must be a valid existing path");
+        }
+      else if (argv[i].equals("-compact_red"))  opt_compact_red = true;
+      else if (argv[i].equals("-nosummary"))    no_summary = true;
+      else if (argv[i].equals("-nowarn"))       emit.nowarn = true;
+      else if (argv[i].equals("-dump_states"))  opt_dump_states = true;
+      else if (argv[i].equals("-dump_tables"))  opt_dump_tables = true;
+      else if (argv[i].equals("-progress"))     print_progress = true;
+      else if (argv[i].equals("-dump_grammar")) opt_dump_grammar = true;
+      else if (argv[i].equals("-dump"))
+            opt_dump_states = opt_dump_tables = opt_dump_grammar = true;
+      else if (argv[i].equals("-time"))         opt_show_timing = true;
+      else if (argv[i].equals("-debug"))        opt_do_debug = true;
+      else
+        {
+          usage("Unrecognized option \"" + argv[i] + "\"");
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /*-------*/
+  /* Files */
+  /*-------*/
+
+  /** Input file.  This is a buffered version of System.in. */
+  protected static BufferedInputStream input_file;
+
+  /** Output file for the parser class. */
+  protected static PrintStream parser_class_file;
+
+  /** Output file for the symbol constant class. */
+  protected static PrintStream symbol_class_file;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Open various files used by the system. */
+  protected static void open_files()
+    {
+      File fil;
+      String out_name;
+
+      /* use a buffered version of standard input */
+        if (emit.input_file_name != null)
+            try {
+                input_file = new BufferedInputStream(new FileInputStream(emit.input_file_name));
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                System.exit(3);
+            }
+        else
+            input_file = new BufferedInputStream(System.in);
+
+      /* open each of the output files */
+      if (out_path == null)
+        out_path = "";
+
+      /* parser class */
+      out_name = out_path + emit.parser_class_name + ".java";
+      fil = new File(out_name);
+      try {
+        parser_class_file = new PrintStream(
+         new BufferedOutputStream(new FileOutputStream(fil), 4096));
+      } catch(Exception e) {
+    System.err.println("Can't open \"" + out_name + "\" for output");
+    System.exit(3);
+      }
+
+      /* symbol constants class */
+      out_name = out_path + emit.symbol_const_class_name + ".java";
+      fil = new File(out_name);
+      try {
+        symbol_class_file = new PrintStream(
+         new BufferedOutputStream(new FileOutputStream(fil), 4096));
+      } catch(Exception e) {
+    System.err.println("Can't open \"" + out_name + "\" for output");
+    System.exit(4);
+      }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Close various files used by the system. */
+  protected static void close_files() throws java.io.IOException
+    {
+      if (input_file != null) input_file.close();
+      if (parser_class_file != null) parser_class_file.close();
+      if (symbol_class_file != null) symbol_class_file.close();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Parse the grammar specification from standard input.  This produces
+   *  sets of terminal, non-terminals, and productions which can be accessed
+   *  via static variables of the respective classes, as well as the setting
+   *  of various variables (mostly in the emit class) for small user supplied
+   *  items such as the code to scan with.
+   */
+  protected static void parse_grammar_spec() throws java.lang.Exception
+    {
+      parser parser_obj;
+
+      /* create a parser and parse with it */
+      parser_obj = new parser();
+      try {
+    if (opt_do_debug)
+          parser_obj.debug_parse();
+    else
+          parser_obj.parse();
+      } catch (Exception e)
+      {
+    /* something threw an exception.  catch it and emit a message so we
+       have a line number to work with, then re-throw it */
+    lexer.emit_error("Internal error: Unexpected exception");
+    throw e;
+      }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Check for unused symbols.  Unreduced productions get checked when
+   *  tables are created.
+   */
+  protected static void check_unused()
+    {
+      terminal term;
+      non_terminal nt;
+
+      /* check for unused terminals */
+      for (Enumeration t = terminal.all(); t.hasMoreElements(); )
+    {
+      term = (terminal)t.nextElement();
+
+      /* don't issue a message for EOF */
+      if (term == terminal.EOF) continue;
+
+      /* or error */
+      if (term == terminal.error) continue;
+
+      /* is this one unused */
+      if (term.use_count() == 0)
+        {
+          /* count it and warn if we are doing warnings */
+          emit.unused_term++;
+          if (!emit.nowarn)
+        {
+          System.err.println("Warning: Terminal \"" + term.name() +
+                     "\" was declared but never used");
+          lexer.warning_count++;
+        }
+        }
+    }
+
+      /* check for unused non terminals */
+      for (Enumeration n = non_terminal.all(); n.hasMoreElements(); )
+    {
+      nt = (non_terminal)n.nextElement();
+
+      /* is this one unused */
+      if (nt.use_count() == 0)
+        {
+          /* count and warn if we are doing warnings */
+          emit.unused_term++;
+          if (!emit.nowarn)
+        {
+          System.err.println("Warning: Non terminal \"" + nt.name() +
+                     "\" was declared but never used");
+          lexer.warning_count++;
+        }
+        }
+    }
+
+    }
+
+  /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+  /* . . Internal Results of Generating the Parser . .*/
+  /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Start state in the overall state machine. */
+  protected static lalr_state start_state;
+
+  /** Resulting parse action table. */
+  protected static parse_action_table action_table;
+
+  /** Resulting reduce-goto table. */
+  protected static parse_reduce_table reduce_table;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Build the (internal) parser from the previously parsed specification.
+   *  This includes:<ul>
+   *    <li> Computing nullability of non-terminals.
+   *    <li> Computing first sets of non-terminals and productions.
+   *    <li> Building the viable prefix recognizer machine.
+   *    <li> Filling in the (internal) parse tables.
+   *    <li> Checking for unreduced productions.
+   *  </ul>
+   */
+  protected static void build_parser() throws internal_error
+    {
+      /* compute nullability of all non terminals */
+      if (opt_do_debug || print_progress)
+    System.err.println("  Computing non-terminal nullability...");
+      non_terminal.compute_nullability();
+
+      nullability_end = System.currentTimeMillis();
+
+      /* compute first sets of all non terminals */
+      if (opt_do_debug || print_progress)
+    System.err.println("  Computing first sets...");
+      non_terminal.compute_first_sets();
+
+      first_end = System.currentTimeMillis();
+
+      /* build the LR viable prefix recognition machine */
+      if (opt_do_debug || print_progress)
+    System.err.println("  Building state machine...");
+      start_state = lalr_state.build_machine(emit.start_production);
+
+      machine_end = System.currentTimeMillis();
+
+      /* build the LR parser action and reduce-goto tables */
+      if (opt_do_debug || print_progress)
+    System.err.println("  Filling in tables...");
+      action_table = new parse_action_table();
+      reduce_table = new parse_reduce_table();
+      for (Enumeration st = lalr_state.all(); st.hasMoreElements(); )
+    {
+      ((lalr_state)st.nextElement()).build_table_entries(
+                                  action_table, reduce_table);
+    }
+
+      table_end = System.currentTimeMillis();
+
+      /* check and warn for non-reduced productions */
+      if (opt_do_debug || print_progress)
+    System.err.println("  Checking for non-reduced productions...");
+      action_table.check_reductions();
+
+      reduce_check_end = System.currentTimeMillis();
+
+      /* if we have more conflicts than we expected issue a message and die */
+      if (emit.num_conflicts > expect_conflicts)
+    {
+      System.err.println("*** More conflicts encountered than expected " +
+                 "-- parser generation aborted");
+      lexer.error_count++;
+      build_end = System.currentTimeMillis();
+
+      /* do dumps and summary as needed */
+          if (opt_dump_grammar) dump_grammar();
+          if (opt_dump_states)  dump_machine();
+      if (!no_summary) emit_summary(false);
+
+      System.exit(100);
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Call the emit routines necessary to write out the generated parser. */
+  protected static void emit_parser() throws internal_error
+    {
+      emit.symbols(symbol_class_file, include_non_terms);
+      emit.parser(parser_class_file, action_table, reduce_table,
+          start_state.index(), emit.start_production, opt_compact_red);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Helper routine to optionally return a plural or non-plural ending.
+   * @param val the numerical value determining plurality.
+   */
+  protected static String plural(int val)
+    {
+      if (val == 1)
+    return "";
+      else
+    return "s";
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit a long summary message to standard error (System.err) which
+   *  summarizes what was found in the specification, how many states were
+   *  produced, how many conflicts were found, etc.  A detailed timing
+   *  summary is also produced if it was requested by the user.
+   * @param output_produced did the system get far enough to generate code.
+   */
+  protected static void emit_summary(boolean output_produced)
+    {
+      final_time = System.currentTimeMillis();
+
+      if (no_summary) return;
+
+      System.err.println("------- " + version.title_str +
+             " Parser Generation Summary -------");
+
+      /* error and warning count */
+      System.err.println("  " + lexer.error_count + " error" +
+     plural(lexer.error_count) + " and " + lexer.warning_count +
+     " warning" + plural(lexer.warning_count));
+
+      /* basic stats */
+      System.err.print("  " + terminal.number() + " terminal" +
+             plural(terminal.number()) + ", ");
+      System.err.print(non_terminal.number() + " non terminal" +
+             plural(non_terminal.number()) + ", and ");
+      System.err.println(production.number() + " production" +
+             plural(production.number()) + " declared, ");
+      System.err.println("  producing " + lalr_state.number() +
+             " unique parse states.");
+
+      /* unused symbols */
+      System.err.println("  " + emit.unused_term + " terminal" +
+             plural(emit.unused_term) + " declared but not used.");
+      System.err.println("  " + emit.unused_non_term + " non terminal" +
+             plural(emit.unused_term) + " declared but not used.");
+
+      /* productions that didn't reduce */
+      System.err.println("  " + emit.not_reduced + " production" +
+             plural(emit.not_reduced) + " never reduced.");
+
+      /* conflicts */
+      System.err.println("  " + emit.num_conflicts + " conflict" +
+             plural(emit.num_conflicts) + " detected" +
+                     " (" + expect_conflicts + " expected).");
+
+      /* code location */
+      if (output_produced)
+    System.err.println("  Code written to \"" + emit.parser_class_name +
+            ".java\", and \"" + emit.symbol_const_class_name + ".java\".");
+      else
+    System.err.println("  No code produced.");
+
+      if (opt_show_timing) show_times();
+
+      System.err.println(
+    "---------------------------------------------------- (" +
+     version.version_str + ")");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce the optional timing summary as part of an overall summary. */
+  protected static void show_times()
+    {
+      long total_time = final_time - start_time;
+
+      System.err.println(". . . . . . . . . . . . . . . . . . . . . . . . . ");
+      System.err.println("  Timing Summary");
+      System.err.println("    Total time       "
+        + timestr(final_time-start_time, total_time));
+      System.err.println("      Startup        "
+    + timestr(prelim_end-start_time, total_time));
+      System.err.println("      Parse          "
+    + timestr(parse_end-prelim_end, total_time) );
+      if (check_end != 0)
+        System.err.println("      Checking       "
+        + timestr(check_end-parse_end, total_time));
+      if (check_end != 0 && build_end != 0)
+        System.err.println("      Parser Build   "
+        + timestr(build_end-check_end, total_time));
+      if (nullability_end != 0 && check_end != 0)
+        System.err.println("        Nullability  "
+        + timestr(nullability_end-check_end, total_time));
+      if (first_end != 0 && nullability_end != 0)
+        System.err.println("        First sets   "
+            + timestr(first_end-nullability_end, total_time));
+      if (machine_end != 0 && first_end != 0)
+        System.err.println("        State build  "
+        + timestr(machine_end-first_end, total_time));
+      if (table_end != 0 && machine_end != 0)
+        System.err.println("        Table build  "
+        + timestr(table_end-machine_end, total_time));
+      if (reduce_check_end != 0 && table_end != 0)
+        System.err.println("        Checking     "
+        + timestr(reduce_check_end-table_end, total_time));
+      if (emit_end != 0 && build_end != 0)
+        System.err.println("      Code Output    "
+        + timestr(emit_end-build_end, total_time));
+      if (emit.symbols_time != 0)
+    System.err.println("        Symbols      "
+        + timestr(emit.symbols_time, total_time));
+      if (emit.parser_time != 0)
+    System.err.println("        Parser class "
+        + timestr(emit.parser_time, total_time));
+      if (emit.action_code_time != 0)
+    System.err.println("          Actions    "
+        + timestr(emit.action_code_time, total_time));
+      if (emit.production_table_time != 0)
+    System.err.println("          Prod table "
+        + timestr(emit.production_table_time, total_time));
+      if (emit.action_table_time != 0)
+    System.err.println("          Action tab "
+        + timestr(emit.action_table_time, total_time));
+      if (emit.goto_table_time != 0)
+    System.err.println("          Reduce tab "
+        + timestr(emit.goto_table_time, total_time));
+
+      System.err.println("      Dump Output    "
+    + timestr(dump_end-emit_end, total_time));
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Helper routine to format a decimal based display of seconds and
+   *  percentage of total time given counts of milliseconds.   Note: this
+   *  is broken for use with some instances of negative time (since we don't
+   *  use any negative time here, we let if be for now).
+   * @param time_val   the value being formatted (in ms).
+   * @param total_time total time percentages are calculated against (in ms).
+   */
+  protected static String timestr(long time_val, long total_time)
+    {
+      boolean neg;
+      long    ms = 0;
+      long    sec = 0;
+      long    percent10;
+      String  pad;
+
+      /* work with positives only */
+      neg = time_val < 0;
+      if (neg) time_val = -time_val;
+
+      /* pull out seconds and ms */
+      ms = time_val % 1000;
+      sec = time_val / 1000;
+
+      /* construct a pad to blank fill seconds out to 4 places */
+      if (sec < 10)
+    pad = "   ";
+      else if (sec < 100)
+    pad = "  ";
+      else if (sec < 1000)
+    pad = " ";
+      else
+    pad = "";
+
+      /* calculate 10 times the percentage of total */
+      percent10 = (time_val*1000)/total_time;
+
+      /* build and return the output string */
+      return (neg ? "-" : "") + pad + sec + "." +
+         ((ms%1000)/100) + ((ms%100)/10) + (ms%10) + "sec" +
+         " (" + percent10/10 + "." + percent10%10 + "%)";
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a human readable dump of the grammar. */
+  public static void dump_grammar() throws internal_error
+    {
+      int cnt;
+      Enumeration t, n, p;
+      production prod;
+
+      System.err.println("===== Terminals =====");
+      for (t = terminal.all(), cnt=0; t.hasMoreElements(); cnt++)
+    {
+      System.err.print(((terminal)t.nextElement()).name() + " ");
+      if ((cnt+1) % 5 == 0) System.err.println();
+    }
+      System.err.println();
+      System.err.println();
+
+      System.err.println("===== Non terminals =====");
+      for (n=non_terminal.all(), cnt=0; n.hasMoreElements(); cnt++)
+    {
+      System.err.print(((non_terminal)n.nextElement()).name() + " ");
+      if ((cnt+1) % 5 == 0) System.err.println();
+    }
+      System.err.println();
+      System.err.println();
+
+
+      System.err.println("===== Productions =====");
+      for (p=production.all(); p.hasMoreElements(); )
+    {
+      prod = (production)p.nextElement();
+      System.err.print(prod.lhs().the_symbol().name() + " ::= ");
+      for (int i=0; i<prod.rhs_length(); i++)
+        if (prod.rhs(i).is_action())
+          System.err.print("{action} ");
+        else
+          System.err.print(
+             ((symbol_part)prod.rhs(i)).the_symbol().name() + " ");
+      System.err.println();
+    }
+      System.err.println();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a (semi-) human readable dump of the complete viable prefix
+   *  recognition state machine.
+   */
+  public static void dump_machine()
+    {
+      lalr_state ordered[] = new lalr_state[lalr_state.number()];
+
+      /* put the states in sorted order for a nicer display */
+      for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
+    {
+      lalr_state st = (lalr_state)s.nextElement();
+      ordered[st.index()] = st;
+    }
+
+      System.err.println("===== Viable Prefix Recognizer =====");
+      for (int i = 0; i<lalr_state.number(); i++)
+    {
+      if (ordered[i] == start_state) System.err.print("START ");
+          System.err.println(ordered[i]);
+      System.err.println("-------------------");
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a (semi-) human readable dumps of the parse tables */
+  public static void dump_tables()
+    {
+      System.err.println(action_table);
+      System.err.println(reduce_table);
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
diff --git a/tools/dasm/src/java_cup/action_part.java b/tools/dasm/src/java_cup/action_part.java
new file mode 100644
index 0000000..5beb385
--- /dev/null
+++ b/tools/dasm/src/java_cup/action_part.java
@@ -0,0 +1,93 @@
+
+package java_cup;
+
+/** 
+ * This class represents a part of a production which contains an
+ * action.  These are eventually eliminated from productions and converted
+ * to trailing actions by factoring out with a production that derives the
+ * empty string (and ends with this action).
+ *
+ * @see java_cup.production
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class action_part extends production_part {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructors ------------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. 
+   * @param code_str string containing the actual user code.
+   */
+  public action_part(String code_str)
+    {
+      super(/* never have a label on code */null);
+      _code_string = code_str;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** String containing code for the action in question. */
+  protected String _code_string;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** String containing code for the action in question. */
+  public String code_string() {return _code_string;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Set the code string. */
+  public void set_code_string(String new_str) {_code_string = new_str;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Override to report this object as an action. */
+  public boolean is_action() { return true; }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison for properly typed object. */
+  public boolean equals(action_part other)
+    {
+      /* compare the strings */
+      return other != null && super.equals(other) && 
+         other.code_string().equals(code_string());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof action_part)) 
+    return false;
+      else
+    return equals((action_part)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a hash code. */
+  public int hashCode()
+    {
+      return super.hashCode() ^ 
+         (code_string()==null ? 0 : code_string().hashCode());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string.  */
+  public String toString()
+    {
+      return super.toString() + "{" + code_string() + "}";
+    }
+
+  /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/action_production.java b/tools/dasm/src/java_cup/action_production.java
new file mode 100644
index 0000000..112e1eb
--- /dev/null
+++ b/tools/dasm/src/java_cup/action_production.java
@@ -0,0 +1,39 @@
+
+package java_cup;
+
+/** A specialized version of a production used when we split an existing
+ *  production in order to remove an embedded action.  Here we keep a bit 
+ *  of extra bookkeeping so that we know where we came from.
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class action_production extends production {
+
+  /** Constructor.
+   * @param base       the production we are being factored out of.
+   * @param lhs_sym    the LHS symbol for this production.
+   * @param rhs_parts  array of production parts for the RHS.
+   * @param rhs_len    how much of the rhs_parts array is valid.
+   * @param action_str the trailing reduce action for this production.
+   */ 
+  public action_production(
+    production      base,
+    non_terminal    lhs_sym, 
+    production_part rhs_parts[],
+    int             rhs_len,
+    String          action_str)
+    throws internal_error
+    {
+      super(lhs_sym, rhs_parts, rhs_len, action_str);
+      _base_production = base;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The production we were taken out of. */
+  protected production _base_production;
+
+  /** The production we were taken out of. */
+  public production base_production() {return _base_production;}
+};
diff --git a/tools/dasm/src/java_cup/emit.java b/tools/dasm/src/java_cup/emit.java
new file mode 100644
index 0000000..5c2ce69
--- /dev/null
+++ b/tools/dasm/src/java_cup/emit.java
@@ -0,0 +1,755 @@
+
+package java_cup;
+
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Stack;
+
+/**
+ * This class handles emitting generated code for the resulting parser.
+ * The various parse tables must be constructed, etc. before calling any
+ * routines in this class.<p>
+ *
+ * Three classes are produced by this code:
+ *   <dl>
+ *   <dt> symbol constant class
+ *   <dd>   this contains constant declarations for each terminal (and
+ *          optionally each non-terminal).
+ *   <dt> action class
+ *   <dd>   this non-public class contains code to invoke all the user actions
+ *          that were embedded in the parser specification.
+ *   <dt> parser class
+ *   <dd>   the specialized parser class consisting primarily of some user
+ *          supplied general and initialization code, and the parse tables.
+ *   </dl><p>
+ *
+ *  Three parse tables are created as part of the parser class:
+ *    <dl>
+ *    <dt> production table
+ *    <dd>   lists the LHS non terminal number, and the length of the RHS of
+ *           each production.
+ *    <dt> action table
+ *    <dd>   for each state of the parse machine, gives the action to be taken
+ *           (shift, reduce, or error) under each lookahead symbol.<br>
+ *    <dt> reduce-goto table
+ *    <dd>   when a reduce on a given production is taken, the parse stack is
+ *           popped back a number of elements corresponding to the RHS of the
+ *           production.  This reveals a prior state, which we transition out
+ *           of under the LHS non terminal symbol for the production (as if we
+ *           had seen the LHS symbol rather than all the symbols matching the
+ *           RHS).  This table is indexed by non terminal numbers and indicates
+ *           how to make these transitions.
+ *    </dl><p>
+ *
+ * In addition to the method interface, this class maintains a series of
+ * public global variables and flags indicating how misc. parts of the code
+ * and other output is to be produced, and counting things such as number of
+ * conflicts detected (see the source code and public variables below for
+ * more details).<p>
+ *
+ * This class is "static" (contains only static data and methods).<p>
+ *
+ * @see java_cup.main
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+/* Major externally callable routines here include:
+     symbols               - emit the symbol constant class
+     parser                - emit the parser class
+
+   In addition the following major internal routines are provided:
+     emit_package          - emit a package declaration
+     emit_action_code      - emit the class containing the user's actions
+     emit_production_table - emit declaration and init for the production table
+     do_action_table       - emit declaration and init for the action table
+     do_reduce_table       - emit declaration and init for the reduce-goto table
+
+   Finally, this class uses a number of public instance variables to communicate
+   optional parameters and flags used to control how code is generated,
+   as well as to report counts of various things (such as number of conflicts
+   detected).  These include:
+
+   prefix                  - a prefix string used to prefix names that would
+                 otherwise "pollute" someone else's name space.
+   package_name            - name of the package emitted code is placed in
+                 (or null for an unnamed package.
+   symbol_const_class_name - name of the class containing symbol constants.
+   parser_class_name       - name of the class for the resulting parser.
+   action_code             - user supplied declarations and other code to be
+                 placed in action class.
+   parser_code             - user supplied declarations and other code to be
+                 placed in parser class.
+   init_code               - user supplied code to be executed as the parser
+                 is being initialized.
+   scan_code               - user supplied code to get the next token.
+   start_production        - the start production for the grammar.
+   import_list             - list of imports for use with action class.
+   num_conflicts           - number of conflicts detected.
+   nowarn                  - true if we are not to issue warning messages.
+   not_reduced             - count of number of productions that never reduce.
+   unused_term             - count of unused terminal symbols.
+   unused_non_term         - count of unused non terminal symbols.
+   *_time                  - a series of symbols indicating how long various
+                 sub-parts of code generation took (used to produce
+                 optional time reports in main).
+*/
+
+public class emit {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Only constructor is private so no instances can be created. */
+  private emit() { }
+
+  /*-----------------------------------------------------------*/
+  /*--- Static (Class) Variables ------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  public static String input_file_name;
+
+  /** The prefix placed on names that pollute someone else's name space. */
+  public static String prefix = "CUP$";
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Package that the resulting code goes into (null is used for unnamed). */
+  public static String package_name = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Name of the generated class for symbol constants. */
+  public static String symbol_const_class_name = "sym";
+
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Name of the generated parser class. */
+  public static String parser_class_name = "parser";
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User declarations for direct inclusion in user action class. */
+  public static String action_code = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User declarations for direct inclusion in parser class. */
+  public static String parser_code = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User code for user_init() which is called during parser initialization. */
+  public static String init_code = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User code for scan() which is called to get the next token. */
+  public static String scan_code = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The start production of the grammar. */
+  public static production start_production = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** List of imports (Strings containing class names) to go with actions. */
+  public static Stack import_list = new Stack();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Number of conflict found while building tables. */
+  public static int num_conflicts = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do we skip warnings? */
+  public static boolean nowarn = false;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of the number on non-reduced productions found. */
+  public static int not_reduced = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of unused terminals. */
+  public static int unused_term = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of unused non terminals. */
+  public static int unused_non_term = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /* Timing values used to produce timing report in main.*/
+
+  /** Time to produce symbol constant class. */
+  public static long symbols_time          = 0;
+
+  /** Time to produce parser class. */
+  public static long parser_time           = 0;
+
+  /** Time to produce action code class. */
+  public static long action_code_time      = 0;
+
+  /** Time to produce the production table. */
+  public static long production_table_time = 0;
+
+  /** Time to produce the action table. */
+  public static long action_table_time     = 0;
+
+  /** Time to produce the reduce-goto table. */
+  public static long goto_table_time       = 0;
+
+  /** Do we produce calls debug_gammar in generated parser? */
+  public static String debug_grammar = null;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Build a string with the standard prefix.
+   * @param str string to prefix.
+   */
+  protected static String pre(String str) {return prefix + str;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit a package spec if the user wants one.
+   * @param out stream to produce output on.
+   */
+  protected static void emit_package(PrintStream out)
+    {
+      /* generate a package spec if we have a name for one */
+      if (package_name != null)
+    out.println("package " + package_name + ";\n");
+
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit code for the symbol constant class, optionally including non terms,
+   *  if they have been requested.
+   * @param out            stream to produce output on.
+   * @param emit_non_terms do we emit constants for non terminals?
+   */
+  public static void symbols(PrintStream out, boolean emit_non_terms)
+    {
+      terminal term;
+      non_terminal nt;
+
+      long start_time = System.currentTimeMillis();
+
+      /* top of file */
+      out.println();
+      out.println("//----------------------------------------------------");
+      out.println("// The following code was generated by " +
+                               version.title_str);
+      out.println("// " + new Date());
+      out.println("//----------------------------------------------------");
+      out.println();
+      emit_package(out);
+
+      /* class header */
+      out.println(
+        "/** JavaCup generated class containing symbol constants. */");
+      out.println("public class " + symbol_const_class_name + " {");
+
+      out.println("  /* terminals */");
+
+      /* walk over the terminals */              /* later might sort these */
+      for (Enumeration e = terminal.all(); e.hasMoreElements(); )
+    {
+      term = (terminal)e.nextElement();
+
+      /* output a constant decl for the terminal */
+      out.println("  static final int " + term.name() + " = " +
+              term.index() + ";");
+    }
+
+      /* do the non terminals if they want them (parser doesn't need them) */
+      if (emit_non_terms)
+    {
+          out.println("\n  /* non terminals */");
+
+          /* walk over the non terminals */       /* later might sort these */
+          for (Enumeration e = non_terminal.all(); e.hasMoreElements(); )
+        {
+          nt = (non_terminal)e.nextElement();
+
+          /* output a constant decl for the terminal */
+          out.println("  static final int " + nt.name() + " = " +
+                  nt.index() + ";");
+        }
+    }
+
+      /* end of class */
+      out.println("};\n");
+
+      symbols_time = System.currentTimeMillis() - start_time;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit code for the non-public class holding the actual action code.
+   * @param out        stream to produce output on.
+   * @param start_prod the start production of the grammar.
+   */
+  protected static void emit_action_code(PrintStream out, production start_prod)
+    throws internal_error
+    {
+      production prod;
+
+      long start_time = System.currentTimeMillis();
+
+      /* class header */
+      out.println();
+      out.println(
+       "/** JavaCup generated class to encapsulate user supplied action code.*/"
+      );
+      out.println("class " +  pre("actions") + " {");
+
+      /* user supplied code */
+      if (action_code != null)
+    {
+      out.println();
+          out.println(action_code);
+    }
+
+      /* constructor */
+      out.println();
+      out.println("  /** Constructor */");
+      out.println("  " + pre("actions") + "() { }");
+
+      /* action method head */
+      out.println();
+      out.println("  /** Method with the actual generated action code. */");
+      out.println("  public final java_cup.runtime.symbol " +
+             pre("do_action") + "(");
+      out.println("    int                        " + pre("act_num,"));
+      out.println("    java_cup.runtime.lr_parser " + pre("parser,"));
+      out.println("    java.util.Stack            " + pre("stack,"));
+      out.println("    int                        " + pre("top)"));
+      out.println("    throws java.lang.Exception");
+      out.println("    {");
+
+      /* declaration of result symbol */
+      out.println("      /* object for return from actions */");
+      out.println("      java_cup.runtime.symbol " + pre("result") + ";");
+      out.println();
+
+      /* switch top */
+      out.println("      /* select the action based on the action number */");
+      out.println("      switch (" + pre("act_num") + ")");
+      out.println("        {");
+
+      /* emit action code for each production as a separate case */
+      for (Enumeration p = production.all(); p.hasMoreElements(); )
+    {
+      prod = (production)p.nextElement();
+
+      /* case label */
+          out.println("          /*. . . . . . . . . . . . . . . . . . . .*/");
+          out.println("          case " + prod.index() + ": // " +
+                      prod.to_simple_string());
+
+      /* give them their own block to work in */
+      out.println("            {");
+
+          /* user supplied code for debug_grammar() */
+          if (debug_grammar != null)
+            out.println("             " +debug_grammar+ "(\"" +
+                        prod.to_simple_string() + "\");");
+
+      /* create the result symbol */
+      out.println("              " + pre("result") + " = new " +
+        prod.lhs().the_symbol().stack_type() + "(/*" +
+        prod.lhs().the_symbol().name() + "*/" +
+        prod.lhs().the_symbol().index() + ");");
+
+      /* if there is an action string, emit it */
+      if (prod.action() != null && prod.action().code_string() != null &&
+          !prod.action().equals(""))
+        out.println("              " + prod.action().code_string());
+
+      /* end of their block */
+      out.println("            }");
+
+      /* if this was the start production, do action for accept */
+      if (prod == start_prod)
+        {
+          out.println("          /* ACCEPT */");
+          out.println("          " + pre("parser") + ".done_parsing();");
+        }
+
+      /* code to return lhs symbol */
+      out.println("          return " + pre("result") + ";");
+      out.println();
+    }
+
+      /* end of switch */
+      out.println("          /* . . . . . .*/");
+      out.println("          default:");
+      out.println("            throw new Exception(");
+      out.println("               \"Invalid action number found in " +
+                  "internal parse table\");");
+      out.println();
+      out.println("        }");
+
+      /* end of method */
+      out.println("    }");
+
+      /* end of class */
+      out.println("};\n");
+
+      action_code_time = System.currentTimeMillis() - start_time;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit the production table.
+   * @param out stream to produce output on.
+   */
+  protected static void emit_production_table(PrintStream out)
+    {
+      production all_prods[];
+      production prod;
+
+      long start_time = System.currentTimeMillis();
+
+      /* do the top of the table */
+      out.println();
+      out.println("  /** production table */");
+      out.println("  protected static final short _production_table[][] = {");
+
+      /* collect up the productions in order */
+      all_prods = new production[production.number()];
+      for (Enumeration p = production.all(); p.hasMoreElements(); )
+    {
+      prod = (production)p.nextElement();
+      all_prods[prod.index()] = prod;
+    }
+
+      /* do one entry per production */
+      out.print("    ");
+      for (int i = 0; i<production.number(); i++)
+    {
+      prod = all_prods[i];
+
+      /* make the table entry */
+      out.print("    {");
+      out.print(/* lhs symbol # */ prod.lhs().the_symbol().index() + ", ");
+      out.print(/* rhs size */     prod.rhs_length() + "}");
+
+      /* put in a comma if we aren't at the end */
+      if (i < production.number()-1) out.print(", ");
+
+      /* 5 entries per line */
+      if ((i+1) % 5 == 0)
+        {
+          out.println();
+          out.print("    ");
+        }
+    }
+
+      /* finish off the table initializer */
+      out.println("  };");
+
+      /* do the public accessor method */
+      out.println();
+      out.println("  /** access to production table */");
+      out.println("  public short[][] production_table() " +
+                         "{return _production_table;}");
+
+      production_table_time = System.currentTimeMillis() - start_time;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit the action table.
+   * @param out             stream to produce output on.
+   * @param act_tab         the internal representation of the action table.
+   * @param compact_reduces do we use the most frequent reduce as default?
+   */
+  protected static void do_action_table(
+    PrintStream        out,
+    parse_action_table act_tab,
+    boolean            compact_reduces)
+    throws internal_error
+    {
+      parse_action_row row;
+      parse_action     act;
+      int              red;
+
+      long start_time = System.currentTimeMillis();
+
+      out.println();
+      out.println("  /** parse action table */");
+      out.println("  protected static final short[][] _action_table = {");
+
+      /* do each state (row) of the action table */
+      for (int i = 0; i < act_tab.num_states(); i++)
+    {
+      /* get the row */
+      row = act_tab.under_state[i];
+
+      /* determine the default for the row */
+      if (compact_reduces)
+        row.compute_default();
+      else
+        row.default_reduce = -1;
+
+      out.print("    /*" + i + "*/{");
+
+      /* do each column */
+      for (int j = 0; j < row.size(); j++)
+        {
+          /* extract the action from the table */
+          act = row.under_term[j];
+
+          /* skip error entries these are all defaulted out */
+          if (act.kind() != parse_action.ERROR)
+        {
+          /* first put in the symbol index, then the actual entry */
+
+          /* shifts get positive entries of state number + 1 */
+          if (act.kind() == parse_action.SHIFT)
+            {
+            out.print(j + "," +
+                (((shift_action)act).shift_to().index() + 1) + ",");
+            }
+
+          /* reduce actions get negated entries of production# + 1 */
+          else if (act.kind() == parse_action.REDUCE)
+            {
+              /* if its the default entry let it get defaulted out */
+              red = ((reduce_action)act).reduce_with().index();
+              if (red != row.default_reduce)
+                out.print(j + "," + (-(red+1)) + ",");
+            }
+
+          /* shouldn't be anything else */
+          else
+            throw new internal_error("Unrecognized action code " +
+              act.kind() + " found in parse table");
+        }
+        }
+
+      /* finish off the row with a default entry */
+      if (row.default_reduce != -1)
+        out.println("-1," + (-(row.default_reduce+1)) + "},");
+      else
+        out.println("-1,0},");
+    }
+
+      /* finish off the init of the table */
+      out.println("  };");
+
+      /* do the public accessor method */
+      out.println();
+      out.println("  /** access to parse action table */");
+      out.println("  public short[][] action_table() {return _action_table;}");
+
+      action_table_time = System.currentTimeMillis() - start_time;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit the reduce-goto table.
+   * @param out     stream to produce output on.
+   * @param red_tab the internal representation of the reduce-goto table.
+   */
+  protected static void do_reduce_table(
+    PrintStream out,
+    parse_reduce_table red_tab)
+    {
+      lalr_state       goto_st;
+      parse_action     act;
+
+      long start_time = System.currentTimeMillis();
+
+      out.println();
+      out.println("  /** reduce_goto table */");
+      out.println("  protected static final short[][] _reduce_table = {");
+
+      /* do each row of the reduce-goto table */
+      for (int i=0; i<red_tab.num_states(); i++)
+    {
+      out.print("    /*" + i + "*/{");
+
+      /* do each entry in the row */
+      for (int j=0; j<red_tab.under_state[i].size(); j++)
+        {
+          /* get the entry */
+          goto_st = red_tab.under_state[i].under_non_term[j];
+
+          /* if we have none, skip it */
+          if (goto_st != null)
+        {
+          /* make entries for the index and the value */
+          out.print(j + "," + goto_st.index() + ",");
+        }
+        }
+
+      /* end row with default value */
+      out.println("-1,-1},");
+    }
+
+      /* finish off the init of the table */
+      out.println("  };");
+
+      /* do the public accessor method */
+      out.println();
+      out.println("  /** access to reduce_goto table */");
+      out.println("  public short[][] reduce_table() {return _reduce_table;}");
+      out.println();
+
+      goto_table_time = System.currentTimeMillis() - start_time;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit the parser subclass with embedded tables.
+   * @param out             stream to produce output on.
+   * @param action_table    internal representation of the action table.
+   * @param reduce_table    internal representation of the reduce-goto table.
+   * @param start_st        start state of the parse machine.
+   * @param start_prod      start production of the grammar.
+   * @param compact_reduces do we use most frequent reduce as default?
+   */
+  public static void parser(
+    PrintStream        out,
+    parse_action_table action_table,
+    parse_reduce_table reduce_table,
+    int                start_st,
+    production         start_prod,
+    boolean            compact_reduces)
+    throws internal_error
+    {
+      long start_time = System.currentTimeMillis();
+
+      /* top of file */
+      out.println();
+      out.println("//----------------------------------------------------");
+      out.println("// The following code was generated by " +
+                            version.title_str);
+      out.println("// " + new Date());
+      out.println("//----------------------------------------------------");
+      out.println();
+      emit_package(out);
+
+      /* user supplied imports */
+      for (int i = 0; i < import_list.size(); i++)
+    out.println("import " + import_list.elementAt(i) + ";");
+
+      /* class header */
+      out.println();
+      out.println("public class " + parser_class_name +
+          " extends java_cup.runtime.lr_parser {");
+
+      /* constructor */
+      out.println();
+      out.println("  /** constructor */");
+      out.println("  public " + parser_class_name + "() {super();}");
+
+      /* emit the various tables */
+      emit_production_table(out);
+      do_action_table(out, action_table, compact_reduces);
+      do_reduce_table(out, reduce_table);
+
+      /* instance of the action encapsulation class */
+      out.println("  /** instance of action encapsulation class */");
+      out.println("  protected " + pre("actions") + " action_obj;");
+      out.println();
+
+      /* action object initializer */
+      out.println("  /** action encapsulation object initializer */");
+      out.println("  protected void init_actions()");
+      out.println("    {");
+      out.println("      action_obj = new " + pre("actions") + "();");
+      out.println("    }");
+      out.println();
+
+      /* access to action code */
+      out.println("  /** invoke a user supplied parse action */");
+      out.println("  public java_cup.runtime.symbol do_action(");
+      out.println("    int                        act_num,");
+      out.println("    java_cup.runtime.lr_parser parser,");
+      out.println("    java.util.Stack            stack,");
+      out.println("    int                        top)");
+      out.println("    throws java.lang.Exception");
+      out.println("  {");
+      out.println("    /* call code in generated class */");
+      out.println("    return action_obj." + pre("do_action(") +
+                  "act_num, parser, stack, top);");
+      out.println("  }");
+      out.println("");
+
+
+      /* method to tell the parser about the start state */
+      out.println("  /** start state */");
+      out.println("  public int start_state() {return " + start_st + ";}");
+
+      /* method to indicate start production */
+      out.println("  /** start production */");
+      out.println("  public int start_production() {return " +
+             start_production.index() + ";}");
+      out.println();
+
+      /* methods to indicate EOF and error symbol indexes */
+      out.println("  /** EOF symbol index */");
+      out.println("  public int EOF_sym() {return " + terminal.EOF.index() +
+                      ";}");
+      out.println();
+      out.println("  /** error symbol index */");
+      out.println("  public int error_sym() {return " + terminal.error.index() +
+                      ";}");
+      out.println();
+
+      /* user supplied code for user_init() */
+      if (init_code != null)
+    {
+          out.println();
+      out.println("  /** user initialization */");
+      out.println("  public void user_init() throws java.lang.Exception");
+      out.println("    {");
+      out.println(init_code);
+      out.println("    }");
+    }
+
+      /* user supplied code for scan */
+      if (scan_code != null)
+    {
+          out.println();
+      out.println("  /** scan to get the next token */");
+      out.println("  public java_cup.runtime.token scan()");
+      out.println("    throws java.lang.Exception");
+      out.println("    {");
+      out.println(scan_code);
+      out.println("    }");
+    }
+
+      /* user supplied code */
+      if (parser_code != null)
+    {
+      out.println();
+          out.println(parser_code);
+    }
+
+      /* end of class */
+      out.println("};");
+
+      /* put out the action code class */
+      emit_action_code(out, start_prod);
+
+      parser_time = System.currentTimeMillis() - start_time;
+    }
+
+    /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/internal_error.java b/tools/dasm/src/java_cup/internal_error.java
new file mode 100644
index 0000000..2a05b26
--- /dev/null
+++ b/tools/dasm/src/java_cup/internal_error.java
@@ -0,0 +1,22 @@
+
+package java_cup;
+
+/** Exception subclass for reporting internal errors in JavaCup. */
+public class internal_error extends Exception
+  {
+    /** Constructor with a message */
+    public internal_error(String msg)
+      {
+    super(msg);
+      }
+
+    /** Method called to do a forced error exit on an internal error
+    for cases when we can't actually throw the exception.  */
+    public void crash()
+      {
+    System.err.println("JavaCUP Fatal Internal Error Detected");
+    System.err.println(getMessage());
+    printStackTrace();
+    System.exit(-1);
+      }
+  };
diff --git a/tools/dasm/src/java_cup/lalr_item.java b/tools/dasm/src/java_cup/lalr_item.java
new file mode 100644
index 0000000..dfa09e1
--- /dev/null
+++ b/tools/dasm/src/java_cup/lalr_item.java
@@ -0,0 +1,329 @@
+package java_cup;
+
+import java.util.Stack;
+
+/** This class represents an LALR item. Each LALR item consists of 
+ *  a production, a "dot" at a position within that production, and
+ *  a set of lookahead symbols (terminal).  (The first two of these parts
+ *  are provide by the super class).  An item is designed to represent a 
+ *  configuration that the parser may be in.  For example, an item of the 
+ *  form: <pre>
+ *    [A ::= B * C d E  , {a,b,c}]
+ *  </pre>
+ *  indicates that the parser is in the middle of parsing the production <pre>
+ *    A ::= B C d E
+ *  </pre>
+ *  that B has already been parsed, and that we will expect to see a lookahead 
+ *  of either a, b, or c once the complete RHS of this production has been 
+ *  found.<p>
+ *
+ *  Items may initially be missing some items from their lookahead sets.  
+ *  Links are maintained from each item to the set of items that would need 
+ *  to be updated if symbols are added to its lookahead set.  During 
+ *  "lookahead propagation", we add symbols to various lookahead sets and 
+ *  propagate these changes across these dependency links as needed. 
+ *  
+ * @see     java_cup.lalr_item_set
+ * @see     java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class lalr_item extends lr_item_core {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor. 
+   * @param prod the production for the item.
+   * @param pos  the position of the "dot" within the production.
+   * @param look the set of lookahead symbols.
+   */
+  public lalr_item(production prod, int pos, terminal_set look) 
+    throws internal_error
+    {
+      super(prod, pos);
+      _lookahead = look;
+      _propagate_items = new Stack();
+      needs_propagation = true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with default position (dot at start). 
+   * @param prod the production for the item.
+   * @param look the set of lookahead symbols.
+   */
+  public lalr_item(production prod, terminal_set look) throws internal_error
+    {
+      this(prod,0,look);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with default position and empty lookahead set. 
+   * @param prod the production for the item.
+   */
+  public lalr_item(production prod) throws internal_error
+    {
+      this(prod,0,new terminal_set());
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The lookahead symbols of the item. */
+  protected terminal_set _lookahead;
+
+  /** The lookahead symbols of the item. */
+  public terminal_set lookahead() {return _lookahead;};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Links to items that the lookahead needs to be propagated to. */
+  protected Stack _propagate_items; 
+
+  /** Links to items that the lookahead needs to be propagated to */
+  public Stack propagate_items() {return _propagate_items;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Flag to indicate that this item needs to propagate its lookahead 
+   *  (whether it has changed or not). 
+   */
+  protected boolean needs_propagation;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a new item to the set of items we propagate to. */
+  public void add_propagate(lalr_item prop_to)
+    {
+      _propagate_items.push(prop_to);
+      needs_propagation = true;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Propagate incoming lookaheads through this item to others need to 
+   *  be changed.
+   * @params incoming symbols to potentially be added to lookahead of this item.
+   */
+  public void propagate_lookaheads(terminal_set incoming) throws internal_error
+    {
+      boolean change = false;
+
+      /* if we don't need to propagate, then bail out now */
+      if (!needs_propagation && (incoming == null || incoming.empty()))
+    return;
+
+      /* if we have null incoming, treat as an empty set */
+      if (incoming != null)
+    {
+      /* add the incoming to the lookahead of this item */
+      change = lookahead().add(incoming);
+    }
+
+      /* if we changed or need it anyway, propagate across our links */
+      if (change || needs_propagation)
+    {
+          /* don't need to propagate again */
+          needs_propagation = false;
+
+      /* propagate our lookahead into each item we are linked to */
+      for (int i = 0; i < propagate_items().size(); i++)
+        ((lalr_item)propagate_items().elementAt(i))
+                      .propagate_lookaheads(lookahead());
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce the new lalr_item that results from shifting the dot one position
+   *  to the right. 
+   */
+  public lalr_item shift() throws internal_error
+    {
+      lalr_item result;
+
+      /* can't shift if we have dot already at the end */
+      if (dot_at_end())
+    throw new internal_error("Attempt to shift past end of an lalr_item");
+
+      /* create the new item w/ the dot shifted by one */
+      result = new lalr_item(the_production(), dot_pos()+1, 
+                        new terminal_set(lookahead()));
+
+      /* change in our lookahead needs to be propagated to this item */
+      add_propagate(result);
+
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Calculate lookahead representing symbols that could appear after the
+   *   symbol that the dot is currently in front of.  Note: this routine must
+   *   not be invoked before first sets and nullability has been calculated
+   *   for all non terminals. 
+   */ 
+  public terminal_set calc_lookahead(terminal_set lookahead_after) 
+    throws internal_error
+    {
+      terminal_set    result;
+      int             pos;
+      production_part part;
+      symbol          sym;
+
+      /* sanity check */
+      if (dot_at_end())
+    throw new internal_error(
+      "Attempt to calculate a lookahead set with a completed item");
+
+      /* start with an empty result */
+      result = new terminal_set();
+
+      /* consider all nullable symbols after the one to the right of the dot */
+      for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++) 
+    {
+       part = the_production().rhs(pos);
+
+       /* consider what kind of production part it is -- skip actions */ 
+       if (!part.is_action())
+         {
+           sym = ((symbol_part)part).the_symbol();
+
+           /* if its a terminal add it in and we are done */
+           if (!sym.is_non_term())
+         {
+           result.add((terminal)sym);
+           return result;
+         }
+           else
+         {
+           /* otherwise add in first set of the non terminal */
+           result.add(((non_terminal)sym).first_set());
+
+           /* if its nullable we continue adding, if not, we are done */
+           if (!((non_terminal)sym).nullable())
+             return result;
+         }
+         }
+    }
+
+      /* if we get here everything past the dot was nullable 
+         we add in the lookahead for after the production and we are done */
+      result.add(lookahead_after);
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if everything from the symbol one beyond the dot all the 
+   *  way to the  end of the right hand side is nullable.  This would indicate
+   *  that the lookahead of this item must be included in the lookaheads of
+   *  all items produced as a closure of this item.  Note: this routine should 
+   *  not be invoked until after first sets and nullability have been 
+   *  calculated for all non terminals. 
+   */
+  public boolean lookahead_visible() throws internal_error
+    {
+      production_part part;
+      symbol          sym;
+
+      /* if the dot is at the end, we have a problem, but the cleanest thing
+     to do is just return true. */
+      if (dot_at_end()) return true;
+
+      /* walk down the rhs and bail if we get a non-nullable symbol */
+      for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++)
+    {
+      part = the_production().rhs(pos);
+
+      /* skip actions */
+      if (!part.is_action())
+        {
+          sym = ((symbol_part)part).the_symbol();
+
+          /* if its a terminal we fail */
+          if (!sym.is_non_term()) return false;
+
+          /* if its not nullable we fail */
+          if (!((non_terminal)sym).nullable()) return false;
+        }
+    }
+
+      /* if we get here its all nullable */
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison -- here we only require the cores to be equal since
+   *   we need to do sets of items based only on core equality (ignoring 
+   *   lookahead sets). 
+   */
+  public boolean equals(lalr_item other)
+    {
+      if (other == null) return false;
+      return super.equals(other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof lalr_item)) 
+    return false;
+      else
+    return equals((lalr_item)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return a hash code -- here we only hash the core since we only test core
+   *  matching in LALR items. 
+   */
+  public int hashCode()
+    {
+      return super.hashCode();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to string. */
+  public String toString()
+    {
+      String result = "";
+
+      // additional output for debugging:
+      // result += "(" + hashCode() + ")"; 
+      result += "[";
+      result += super.toString();
+      result += ", ";
+      if (lookahead() != null)
+    {
+      result += "{";
+      for (int t = 0; t < terminal.number(); t++)
+        if (lookahead().contains(t))
+          result += terminal.find(t).name() + " ";
+      result += "}";
+    }
+      else
+    result += "NULL LOOKAHEAD!!";
+      result += "]";
+
+      // additional output for debugging:
+      // result += " -> ";
+      // for (int i = 0; i<propagate_items().size(); i++)
+      //   result += propagate_items().elementAt(i).hashCode() + " ";
+      //
+      // if (needs_propagation) result += " NP";
+
+      return result;
+    }
+    /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/lalr_item_set.java b/tools/dasm/src/java_cup/lalr_item_set.java
new file mode 100644
index 0000000..9abc8db
--- /dev/null
+++ b/tools/dasm/src/java_cup/lalr_item_set.java
@@ -0,0 +1,366 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** This class represents a set of LALR items.  For purposes of building
+ *  these sets, items are considered unique only if they have unique cores
+ *  (i.e., ignoring differences in their lookahead sets).<p>
+ *
+ *  This class provides fairly conventional set oriented operations (union,
+ *  sub/super-set tests, etc.), as well as an LALR "closure" operation (see 
+ *  compute_closure()).
+ *
+ * @see     java_cup.lalr_item
+ * @see     java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class lalr_item_set {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constructor for an empty set. */
+  public lalr_item_set() { }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor for cloning from another set. 
+   * @param other indicates set we should copy from.
+   */
+  public lalr_item_set(lalr_item_set other) 
+    throws internal_error
+    {
+      not_null(other);
+      _all = (Hashtable)other._all.clone();
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** A hash table to implement the set.  We store the items using themselves
+   *  as keys. 
+   */
+  protected Hashtable _all = new Hashtable(11);
+
+  /** Access to all elements of the set. */
+  public Enumeration all() {return _all.elements();}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Cached hashcode for this set. */
+  protected Integer hashcode_cache = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Size of the set */
+  public int size() {return _all.size();}
+
+  /*-----------------------------------------------------------*/
+  /*--- Set Operation Methods ---------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Does the set contain a particular item? 
+   * @param itm the item in question.
+   */
+  public boolean contains(lalr_item itm) {return _all.containsKey(itm);}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return the item in the set matching a particular item (or null if not 
+   *  found) 
+   *  @param itm the item we are looking for.
+   */
+  public lalr_item find(lalr_item itm) {return (lalr_item)_all.get(itm);}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Is this set an (improper) subset of another? 
+   * @param other the other set in question.
+   */
+  public boolean is_subset_of(lalr_item_set other) throws internal_error
+    {
+      not_null(other);
+
+      /* walk down our set and make sure every element is in the other */
+      for (Enumeration e = all(); e.hasMoreElements(); )
+    if (!other.contains((lalr_item)e.nextElement()))
+      return false;
+
+      /* they were all there */
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Is this set an (improper) superset of another? 
+   * @param other the other set in question.
+   */
+  public boolean is_superset_of(lalr_item_set other) throws internal_error
+    {
+      not_null(other);
+      return other.is_subset_of(this);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a singleton item, merging lookahead sets if the item is already 
+   *  part of the set.  returns the element of the set that was added or 
+   *  merged into.
+   * @param itm the item being added.
+   */
+  public lalr_item add(lalr_item itm) throws internal_error
+    {
+      lalr_item other;
+
+      not_null(itm); 
+
+      /* see if an item with a matching core is already there */
+      other = (lalr_item)_all.get(itm);
+
+      /* if so, merge this lookahead into the original and leave it */
+      if (other != null)
+    {
+      other.lookahead().add(itm.lookahead());
+      return other;
+    }
+      /* otherwise we just go in the set */
+      else
+    {
+          /* invalidate cached hashcode */
+          hashcode_cache = null;
+
+          _all.put(itm,itm);
+      return itm;
+    }
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove a single item if it is in the set. 
+   * @param itm the item to remove.
+   */
+  public void remove(lalr_item itm) throws internal_error
+    {
+      not_null(itm); 
+
+      /* invalidate cached hashcode */
+      hashcode_cache = null;
+
+      /* remove it from hash table implementing set */
+      _all.remove(itm);
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a complete set, merging lookaheads where items are already in 
+   *  the set 
+   * @param other the set to be added.
+   */
+  public void add(lalr_item_set other) throws internal_error
+    {
+      not_null(other);
+
+      /* walk down the other set and do the adds individually */
+      for (Enumeration e = other.all(); e.hasMoreElements(); )
+    add((lalr_item)e.nextElement());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove (set subtract) a complete set. 
+   * @param other the set to remove.
+   */
+  public void remove(lalr_item_set other) throws internal_error
+    {
+      not_null(other);
+
+      /* walk down the other set and do the removes individually */
+      for (Enumeration e = other.all(); e.hasMoreElements(); )
+    remove((lalr_item)e.nextElement());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove and return one item from the set (done in hash order). */
+  public lalr_item get_one() throws internal_error
+    {
+      Enumeration the_set;
+      lalr_item result;
+
+      the_set = all();
+      if (the_set.hasMoreElements())
+    {
+          result = (lalr_item)the_set.nextElement();
+          remove(result);
+      return result;
+    }
+      else
+    return null;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Helper function for null test.  Throws an interal_error exception if its
+   *  parameter is null.
+   *  @param obj the object we are testing.
+   */
+  protected void not_null(Object obj) throws internal_error
+    {
+      if (obj == null) 
+    throw new internal_error("Null object used in set operation");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute the closure of the set using the LALR closure rules.  Basically
+   *  for every item of the form: <pre>
+   *    [L ::= a *N alpha, l] 
+   *  </pre>
+   *  (where N is a a non terminal and alpha is a string of symbols) make 
+   *  sure there are also items of the form:  <pre>
+   *    [N ::= *beta, first(alpha l)] 
+   *  </pre>
+   *  corresponding to each production of N.  Items with identical cores but 
+   *  differing lookahead sets are merged by creating a new item with the same 
+   *  core and the union of the lookahead sets (the LA in LALR stands for 
+   *  "lookahead merged" and this is where the merger is).  This routine 
+   *  assumes that nullability and first sets have been computed for all 
+   *  productions before it is called.
+   */
+  public void compute_closure()
+    throws internal_error
+    {
+      lalr_item_set consider;
+      lalr_item     itm, new_itm, add_itm;
+      non_terminal  nt;
+      terminal_set  new_lookaheads;
+      Enumeration   p;
+      production    prod;
+      boolean       need_prop;
+
+      /* invalidate cached hashcode */
+      hashcode_cache = null;
+
+      /* each current element needs to be considered */
+      consider = new lalr_item_set(this);
+
+      /* repeat this until there is nothing else to consider */
+      while (consider.size() > 0)
+    {
+      /* get one item to consider */
+      itm = consider.get_one(); 
+
+      /* do we have a dot before a non terminal */
+      nt = itm.dot_before_nt();
+      if (nt != null)
+        {
+          /* create the lookahead set based on first after dot */
+          new_lookaheads = itm.calc_lookahead(itm.lookahead());
+
+          /* are we going to need to propagate our lookahead to new item */
+          need_prop = itm.lookahead_visible();
+
+          /* create items for each production of that non term */
+          for (p = nt.productions(); p.hasMoreElements(); )
+        {
+          prod = (production)p.nextElement();
+
+          /* create new item with dot at start and that lookahead */
+          new_itm = new lalr_item(prod,new_lookaheads);
+
+          /* add/merge item into the set */
+          add_itm = add(new_itm);
+
+          /* if propagation is needed link to that item */
+          if (need_prop)
+            itm.add_propagate(add_itm);
+
+          /* was this was a new item*/
+          if (add_itm == new_itm)
+            {
+              /* that may need further closure, consider it also */ 
+              consider.add(new_itm);
+            } 
+        } 
+        } 
+    } 
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(lalr_item_set other)
+    {
+      if (other == null || other.size() != size()) return false;
+
+      /* once we know they are the same size, then improper subset does test */
+      try {
+        return is_subset_of(other);
+      } catch (internal_error e) {
+    /* can't throw error from here (because superclass doesn't) so crash */
+    e.crash();
+    return false;
+      }
+
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof lalr_item_set))
+    return false;
+      else
+    return equals((lalr_item_set)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return hash code. */
+  public int hashCode()
+    {
+      int result = 0;
+      Enumeration e;
+      int cnt;
+
+      /* only compute a new one if we don't have it cached */
+      if (hashcode_cache == null)
+    {
+          /* hash together codes from at most first 5 elements */
+          for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
+        result ^= ((lalr_item)e.nextElement()).hashCode();
+
+      hashcode_cache = new Integer(result);
+    }
+
+      return hashcode_cache.intValue();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to string. */
+  public String toString()
+    {
+      StringBuffer result = new StringBuffer();
+
+      result.append("{\n");
+      for (Enumeration e=all(); e.hasMoreElements(); ) 
+     {
+       result.append("  " + (lalr_item)e.nextElement() + "\n");
+     }
+       result.append("}");
+
+       return result.toString();
+    }
+    /*-----------------------------------------------------------*/
+};
+
diff --git a/tools/dasm/src/java_cup/lalr_state.java b/tools/dasm/src/java_cup/lalr_state.java
new file mode 100644
index 0000000..9782ceb
--- /dev/null
+++ b/tools/dasm/src/java_cup/lalr_state.java
@@ -0,0 +1,749 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Stack;
+
+/** This class represents a state in the LALR viable prefix recognition machine.
+ *  A state consists of an LALR item set and a set of transitions to other 
+ *  states under terminal and non-terminal symbols.  Each state represents
+ *  a potential configuration of the parser.  If the item set of a state 
+ *  includes an item such as: <pre>
+ *    [A ::= B * C d E , {a,b,c}]
+ *  </pre> 
+ *  this indicates that when the parser is in this state it is currently 
+ *  looking for an A of the given form, has already seen the B, and would
+ *  expect to see an a, b, or c after this sequence is complete.  Note that
+ *  the parser is normally looking for several things at once (represented
+ *  by several items).  In our example above, the state would also include
+ *  items such as: <pre>
+ *    [C ::= * X e Z, {d}]
+ *    [X ::= * f, {e}]
+ *  </pre> 
+ *  to indicate that it was currently looking for a C followed by a d (which
+ *  would be reduced into a C, matching the first symbol in our production 
+ *  above), and the terminal f followed by e.<p>
+ *
+ *  At runtime, the parser uses a viable prefix recognition machine made up
+ *  of these states to parse.  The parser has two operations, shift and reduce.
+ *  In a shift, it consumes one token and makes a transition to a new state.
+ *  This corresponds to "moving the dot past" a terminal in one or more items
+ *  in the state (these new shifted items will then be found in the state at
+ *  the end of the transition).  For a reduce operation, the parser is 
+ *  signifying that it is recognizing the RHS of some production.  To do this
+ *  it first "backs up" by popping a stack of previously saved states.  It 
+ *  pops off the same number of states as are found in the RHS of the 
+ *  production.  This leaves the machine in the same state is was in when the
+ *  parser first attempted to find the RHS.  From this state it makes a 
+ *  transition based on the non-terminal on the LHS of the production.  This
+ *  corresponds to placing the parse in a configuration equivalent to having 
+ *  replaced all the symbols from the the input corresponding to the RHS with 
+ *  the symbol on the LHS.
+ *
+ * @see     java_cup.lalr_item
+ * @see     java_cup.lalr_item_set
+ * @see     java_cup.lalr_transition
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ *  
+ */
+
+public class lalr_state {
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** Constructor for building a state from a set of items.
+   * @param itms the set of items that makes up this state.
+   */
+  public lalr_state(lalr_item_set itms) throws internal_error
+   {
+     /* don't allow null or duplicate item sets */
+     if (itms == null)
+       throw new internal_error(
+     "Attempt to construct an LALR state from a null item set");
+
+     if (find_state(itms) != null)
+       throw new internal_error(
+     "Attempt to construct a duplicate LALR state");
+
+     /* assign a unique index */
+     _index = next_index++;
+
+     /* store the items */
+     _items = itms;
+
+     /* add to the global collection, keyed with its item set */
+     _all.put(_items,this);
+   }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Collection of all states. */
+  protected static Hashtable _all = new Hashtable();
+
+  /** Collection of all states. */
+  public static Enumeration all() {return _all.elements();}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indicate total number of states there are. */
+  public static int number() {return _all.size();}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Hash table to find states by their kernels (i.e, the original, 
+   *  unclosed, set of items -- which uniquely define the state).  This table 
+   *  stores state objects using (a copy of) their kernel item sets as keys. 
+   */
+  protected static Hashtable _all_kernels = new Hashtable();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Find and return state with a given a kernel item set (or null if not 
+   *  found).  The kernel item set is the subset of items that were used to
+   *  originally create the state.  These items are formed by "shifting the
+   *  dot" within items of other states that have a transition to this one.
+   *  The remaining elements of this state's item set are added during closure.
+   * @param itms the kernel set of the state we are looking for. 
+   */
+  public static lalr_state find_state(lalr_item_set itms)
+    {
+      if (itms == null) 
+      return null;
+      else
+      return (lalr_state)_all.get(itms);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Static counter for assigning unique state indexes. */
+  protected static int next_index = 0;
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The item set for this state. */
+  protected lalr_item_set _items;
+
+  /** The item set for this state. */
+  public lalr_item_set items() {return _items;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** List of transitions out of this state. */
+  protected lalr_transition _transitions = null;
+
+  /** List of transitions out of this state. */
+  public lalr_transition transitions() {return _transitions;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Index of this state in the parse tables */
+  protected int _index;
+
+  /** Index of this state in the parse tables */
+  public int index() {return _index;}
+
+  /*-----------------------------------------------------------*/
+  /*--- Static Methods ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Helper routine for debugging -- produces a dump of the given state
+    * onto System.out.
+    */
+  protected static void dump_state(lalr_state st) throws internal_error
+    {
+      lalr_item_set itms;
+      lalr_item itm;
+      production_part part;
+
+      if (st == null) 
+    {
+      System.out.println("NULL lalr_state");
+      return;
+    }
+
+      System.out.println("lalr_state [" + st.index() + "] {");
+      itms = st.items();
+      for (Enumeration e = itms.all(); e.hasMoreElements(); )
+    {
+      itm = (lalr_item)e.nextElement();
+      System.out.print("  [");
+      System.out.print(itm.the_production().lhs().the_symbol().name());
+      System.out.print(" ::= ");
+      for (int i = 0; i<itm.the_production().rhs_length(); i++)
+        {
+          if (i == itm.dot_pos()) System.out.print("(*) ");
+          part = itm.the_production().rhs(i);
+          if (part.is_action()) 
+        System.out.print("{action} ");
+          else
+        System.out.print(((symbol_part)part).the_symbol().name() + " ");
+        }
+      if (itm.dot_at_end()) System.out.print("(*) ");
+      System.out.println("]");
+    }
+      System.out.println("}");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Propagate lookahead sets through the constructed viable prefix 
+   *  recognizer.  When the machine is constructed, each item that results
+      in the creation of another such that its lookahead is included in the
+      other's will have a propagate link set up for it.  This allows additions
+      to the lookahead of one item to be included in other items that it 
+      was used to directly or indirectly create.
+   */
+  protected static void propagate_all_lookaheads() throws internal_error
+    {
+      /* iterate across all states */
+      for (Enumeration st = all(); st.hasMoreElements(); )
+    {
+      /* propagate lookaheads out of that state */
+      ((lalr_state)st.nextElement()).propagate_lookaheads();
+    }
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Add a transition out of this state to another.
+   * @param on_sym the symbol the transition is under.
+   * @param to_st  the state the transition goes to.
+   */
+  public void add_transition(symbol on_sym, lalr_state to_st) 
+    throws internal_error
+    {
+      lalr_transition trans;
+
+      /* create a new transition object and put it in our list */
+      trans = new lalr_transition(on_sym, to_st, _transitions);
+      _transitions = trans;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Build an LALR viable prefix recognition machine given a start 
+   *  production.  This method operates by first building a start state
+   *  from the start production (based on a single item with the dot at
+   *  the beginning and EOF as expected lookahead).  Then for each state
+   *  it attempts to extend the machine by creating transitions out of
+   *  the state to new or existing states.  When considering extension
+   *  from a state we make a transition on each symbol that appears before
+   *  the dot in some item.  For example, if we have the items: <pre>
+   *    [A ::= a b * X c, {d,e}]
+   *    [B ::= a b * X d, {a,b}]
+   *  </pre>
+   *  in some state, then we would be making a transition under X to a new
+   *  state.  This new state would be formed by a "kernel" of items 
+   *  corresponding to moving the dot past the X.  In this case: <pre>
+   *    [A ::= a b X * c, {d,e}]
+   *    [B ::= a b X * Y, {a,b}]
+   *  </pre>
+   *  The full state would then be formed by "closing" this kernel set of 
+   *  items so that it included items that represented productions of things
+   *  the parser was now looking for.  In this case we would items 
+   *  corresponding to productions of Y, since various forms of Y are expected
+   *  next when in this state (see lalr_item_set.compute_closure() for details 
+   *  on closure). <p>
+   *
+   *  The process of building the viable prefix recognizer terminates when no
+   *  new states can be added.  However, in order to build a smaller number of
+   *  states (i.e., corresponding to LALR rather than canonical LR) the state 
+   *  building process does not maintain full loookaheads in all items.  
+   *  Consequently, after the machine is built, we go back and propagate 
+   *  lookaheads through the constructed machine using a call to 
+   *  propagate_all_lookaheads().  This makes use of propagation links 
+   *  constructed during the closure and transition process.
+   *
+   * @param start_prod the start production of the grammar
+   * @see   java_cup.lalr_item_set#compute_closure
+   * @see   java_cup.lalr_state#propagate_all_lookaheads
+   */
+
+  public static lalr_state build_machine(production start_prod) 
+    throws internal_error
+    {
+      lalr_state    start_state;
+      lalr_item_set start_items;
+      lalr_item_set new_items;
+      lalr_item_set linked_items;
+      lalr_item_set kernel;
+      Stack         work_stack = new Stack();
+      lalr_state    st, new_st;
+      symbol_set    outgoing;
+      lalr_item     itm, new_itm, existing, fix_itm;
+      symbol        sym, sym2;
+      Enumeration   i, s, fix;
+
+      /* sanity check */
+      if (start_prod == null)
+    throw new internal_error(
+       "Attempt to build viable prefix recognizer using a null production");
+
+      /* build item with dot at front of start production and EOF lookahead */
+      start_items = new lalr_item_set();
+      itm = new lalr_item(start_prod);
+      itm.lookahead().add(terminal.EOF);
+      start_items.add(itm);
+
+      /* create copy the item set to form the kernel */
+      kernel = new lalr_item_set(start_items);
+
+      /* create the closure from that item set */
+      start_items.compute_closure();
+
+      /* build a state out of that item set and put it in our work set */
+      start_state = new lalr_state(start_items);
+      work_stack.push(start_state);
+
+      /* enter the state using the kernel as the key */
+      _all_kernels.put(kernel, start_state);
+
+      /* continue looking at new states until we have no more work to do */
+      while (!work_stack.empty())
+    {
+      /* remove a state from the work set */
+      st = (lalr_state)work_stack.pop();
+
+      /* gather up all the symbols that appear before dots */
+      outgoing = new symbol_set();
+      for (i = st.items().all(); i.hasMoreElements(); )
+        {
+          itm = (lalr_item)i.nextElement();
+
+          /* add the symbol before the dot (if any) to our collection */
+          sym = itm.symbol_after_dot();
+          if (sym != null) outgoing.add(sym);
+        }
+
+      /* now create a transition out for each individual symbol */
+      for (s = outgoing.all(); s.hasMoreElements(); )
+        {
+          sym = (symbol)s.nextElement();
+
+          /* will be keeping the set of items with propagate links */
+          linked_items = new lalr_item_set();
+
+          /* gather up shifted versions of all the items that have this
+         symbol before the dot */
+          new_items = new lalr_item_set();
+          for (i = st.items().all(); i.hasMoreElements();)
+        {
+          itm = (lalr_item)i.nextElement();
+
+          /* if this is the symbol we are working on now, add to set */
+          sym2 = itm.symbol_after_dot();
+          if (sym.equals(sym2))
+            {
+              /* add to the kernel of the new state */
+              new_items.add(itm.shift());
+
+              /* remember that itm has propagate link to it */
+              linked_items.add(itm);
+            }
+        }
+
+          /* use new items as state kernel */
+          kernel = new lalr_item_set(new_items);
+
+          /* have we seen this one already? */
+          new_st = (lalr_state)_all_kernels.get(kernel);
+
+          /* if we haven't, build a new state out of the item set */
+          if (new_st == null)
+        {
+              /* compute closure of the kernel for the full item set */
+              new_items.compute_closure();
+
+          /* build the new state */
+          new_st = new lalr_state(new_items);
+
+          /* add the new state to our work set */
+          work_stack.push(new_st);
+
+          /* put it in our kernel table */
+          _all_kernels.put(kernel, new_st);
+        }
+          /* otherwise relink propagation to items in existing state */
+          else 
+        {
+          /* walk through the items that have links to the new state */
+          for (fix = linked_items.all(); fix.hasMoreElements(); )
+            {
+              fix_itm = (lalr_item)fix.nextElement();
+
+              /* look at each propagate link out of that item */
+              for (int l =0; l < fix_itm.propagate_items().size(); l++)
+            {
+              /* pull out item linked to in the new state */
+              new_itm = 
+                (lalr_item)fix_itm.propagate_items().elementAt(l);
+
+              /* find corresponding item in the existing state */
+              existing = new_st.items().find(new_itm);
+
+              /* fix up the item so it points to the existing set */
+              if (existing != null)
+                fix_itm.propagate_items().setElementAt(existing ,l);
+            }
+            }
+        }
+
+          /* add a transition from current state to that state */
+          st.add_transition(sym, new_st);
+        }
+    }
+
+      /* all done building states */
+
+      /* propagate complete lookahead sets throughout the states */
+      propagate_all_lookaheads();
+
+      return start_state;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Propagate lookahead sets out of this state. This recursively 
+   *  propagates to all items that have propagation links from some item 
+   *  in this state. 
+   */
+  protected void propagate_lookaheads() throws internal_error
+    {
+      /* recursively propagate out from each item in the state */
+      for (Enumeration itm = items().all(); itm.hasMoreElements(); )
+    ((lalr_item)itm.nextElement()).propagate_lookaheads(null);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Fill in the parse table entries for this state.  There are two 
+   *  parse tables that encode the viable prefix recognition machine, an 
+   *  action table and a reduce-goto table.  The rows in each table 
+   *  correspond to states of the machine.  The columns of the action table
+   *  are indexed by terminal symbols and correspond to either transitions 
+   *  out of the state (shift entries) or reductions from the state to some
+   *  previous state saved on the stack (reduce entries).  All entries in the
+   *  action table that are not shifts or reduces, represent errors.    The
+   *  reduce-goto table is indexed by non terminals and represents transitions 
+   *  out of a state on that non-terminal.<p>
+   *  Conflicts occur if more than one action needs to go in one entry of the
+   *  action table (this cannot happen with the reduce-goto table).  Conflicts
+   *  are resolved by always shifting for shift/reduce conflicts and choosing
+   *  the lowest numbered production (hence the one that appeared first in
+   *  the specification) in reduce/reduce conflicts.  All conflicts are 
+   *  reported and if more conflicts are detected than were declared by the
+   *  user, code generation is aborted.
+   *
+   * @param act_table    the action table to put entries in.
+   * @param reduce_table the reduce-goto table to put entries in.
+   */
+  public void build_table_entries(
+    parse_action_table act_table, 
+    parse_reduce_table reduce_table)
+    throws internal_error
+    {
+      parse_action_row our_act_row;
+      parse_reduce_row our_red_row;
+      lalr_item        itm;
+      parse_action     act, other_act;
+      symbol           sym;
+      boolean          conflicted = false;
+
+      /* pull out our rows from the tables */
+      our_act_row = act_table.under_state[index()];
+      our_red_row = reduce_table.under_state[index()];
+
+      /* consider each item in our state */
+      for (Enumeration i = items().all(); i.hasMoreElements(); )
+    {
+      itm = (lalr_item)i.nextElement();
+
+      /* if its completed (dot at end) then reduce under the lookahead */
+      if (itm.dot_at_end())
+        {
+          act = new reduce_action(itm.the_production());
+
+          /* consider each lookahead symbol */
+          for (int t = 0; t < terminal.number(); t++)
+        {
+          /* skip over the ones not in the lookahead */
+          if (!itm.lookahead().contains(t)) continue;
+
+              /* if we don't already have an action put this one in */
+              if (our_act_row.under_term[t].kind() == 
+              parse_action.ERROR)
+            {
+                  our_act_row.under_term[t] = act;
+            }
+              else
+            {
+              /* we now have at least one conflict */
+              conflicted = true;
+
+              other_act = our_act_row.under_term[t];
+
+              /* if the other act was not a shift */
+              if (other_act.kind() != parse_action.SHIFT)
+                {
+                  /* if we have lower index hence priority, replace it*/
+                  if (itm.the_production().index() < 
+                  ((reduce_action)other_act).reduce_with().index())
+                {
+                  /* replace the action */
+                  our_act_row.under_term[t] = act;
+                }
+                }
+            }
+        }
+        }
+    }
+
+      /* consider each outgoing transition */
+      for (lalr_transition trans=transitions(); trans!=null; trans=trans.next())
+    {
+      /* if its on an terminal add a shift entry */
+      sym = trans.on_symbol();
+      if (!sym.is_non_term())
+        {
+          act = new shift_action(trans.to_state());
+
+          /* if we don't already have an action put this one in */
+          if ( our_act_row.under_term[sym.index()].kind() == 
+           parse_action.ERROR)
+        {
+              our_act_row.under_term[sym.index()] = act;
+        }
+          else
+        {
+          /* we now have at least one conflict */
+          conflicted = true;
+
+          /* shift always wins */
+          our_act_row.under_term[sym.index()] = act;
+        }
+        }
+      else
+        {
+          /* for non terminals add an entry to the reduce-goto table */
+          our_red_row.under_non_term[sym.index()] = trans.to_state();
+        }
+    }
+
+      /* if we end up with conflict(s), report them */
+      if (conflicted)
+        report_conflicts();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce warning messages for all conflicts found in this state.  */
+  protected void report_conflicts()
+    throws internal_error
+    {
+      lalr_item    itm, compare;
+      symbol       shift_sym;
+      terminal_set conflict_set;
+      boolean      after_itm;
+
+      /* consider each element */
+      for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+    {
+      itm = (lalr_item)itms.nextElement();
+
+      /* clear the S/R conflict set for this item */
+      conflict_set = new terminal_set();
+
+      /* if it results in a reduce, it could be a conflict */
+      if (itm.dot_at_end())
+        {
+          /* not yet after itm */
+          after_itm = false;
+
+          /* compare this item against all others looking for conflicts */
+          for (Enumeration comps = items().all(); comps.hasMoreElements(); )
+        {
+          compare = (lalr_item)comps.nextElement();
+
+          /* if this is the item, next one is after it */
+          if (itm == compare) after_itm = true;
+
+          /* only look at it if its not the same item */
+          if (itm != compare)
+            {
+              /* is it a reduce */
+              if (compare.dot_at_end())
+            {
+              /* only look at reduces after itm */
+              if (after_itm)
+                            /* does the comparison item conflict? */
+                            if (compare.lookahead().intersects(itm.lookahead()))
+                              /* report a reduce/reduce conflict */
+                              report_reduce_reduce(itm, compare);
+            }
+              /* must be a shift on a terminal or non-terminal */
+              else 
+            {
+                  /* is it a shift on a terminal */
+              shift_sym = compare.symbol_after_dot();
+              if (!shift_sym.is_non_term()) 
+                {
+                  /* does the terminal conflict with our item */
+                  if (itm.lookahead().contains((terminal)shift_sym))
+                    /* remember the terminal symbol in conflict */
+                    conflict_set.add((terminal)shift_sym);
+                }
+            }
+            }
+        }
+          /* report S/R conflicts under all the symbols we conflict under */
+          for (int t = 0; t < terminal.number(); t++)
+        if (conflict_set.contains(t))
+          report_shift_reduce(itm,t);
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a warning message for one reduce/reduce conflict. 
+   *
+   * @param itm1 first item in conflict.
+   * @param itm2 second item in conflict.
+   */
+  protected void report_reduce_reduce(lalr_item itm1, lalr_item itm2)
+    throws internal_error
+    {
+      boolean comma_flag = false;
+
+      System.err.println("*** Reduce/Reduce conflict found in state #"+index());
+      System.err.print  ("  between ");
+      System.err.println(itm1.to_simple_string());
+      System.err.print  ("  and     ");
+      System.err.println(itm2.to_simple_string());
+      System.err.print("  under symbols: {" );
+      for (int t = 0; t < terminal.number(); t++)
+    {
+      if (itm1.lookahead().contains(t) && itm2.lookahead().contains(t))
+        {
+          if (comma_flag) System.err.print(", "); else comma_flag = true;
+          System.err.print(terminal.find(t).name());
+        }
+    }
+      System.err.println("}");
+      System.err.print("  Resolved in favor of ");
+      if (itm1.the_production().index() < itm2.the_production().index())
+    System.err.println("the first production.\n");
+      else
+    System.err.println("the second production.\n");
+
+      /* count the conflict */
+      emit.num_conflicts++;
+      lexer.warning_count++;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a warning message for one shift/reduce conflict.
+   *
+   * @param red_itm      the item with the reduce.
+   * @param conflict_sym the index of the symbol conflict occurs under.
+   */
+  protected void report_shift_reduce(
+    lalr_item red_itm, 
+    int       conflict_sym)
+    throws internal_error
+    {
+      lalr_item    itm;
+      symbol       shift_sym;
+
+      /* emit top part of message including the reduce item */
+      System.err.println("*** Shift/Reduce conflict found in state #"+index());
+      System.err.print  ("  between ");
+      System.err.println(red_itm.to_simple_string());
+
+      /* find and report on all items that shift under our conflict symbol */
+      for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+    {
+      itm = (lalr_item)itms.nextElement();
+
+      /* only look if its not the same item and not a reduce */
+      if (itm != red_itm && !itm.dot_at_end())
+        {
+          /* is it a shift on our conflicting terminal */
+          shift_sym = itm.symbol_after_dot();
+          if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym)
+            {
+          /* yes, report on it */
+                  System.err.println("  and     " + itm.to_simple_string());
+        }
+        }
+    }
+      System.err.println("  under symbol "+ terminal.find(conflict_sym).name());
+      System.err.println("  Resolved in favor of shifting.\n");
+
+      /* count the conflict */
+      emit.num_conflicts++;
+      lexer.warning_count++;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(lalr_state other)
+    {
+      /* we are equal if our item sets are equal */
+      return other != null && items().equals(other.items());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof lalr_state))
+    return false;
+      else
+    return equals((lalr_state)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a hash code. */
+  public int hashCode()
+    {
+      /* just use the item set hash code */
+      return items().hashCode();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      String result;
+      lalr_transition tr;
+
+      /* dump the item set */
+      result = "lalr_state [" + index() + "]: " + _items + "\n";
+
+      /* do the transitions */
+      for (tr = transitions(); tr != null; tr = tr.next())
+    {
+      result += tr;
+      result += "\n";
+    }
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/lalr_transition.java b/tools/dasm/src/java_cup/lalr_transition.java
new file mode 100644
index 0000000..5e5075c
--- /dev/null
+++ b/tools/dasm/src/java_cup/lalr_transition.java
@@ -0,0 +1,93 @@
+package java_cup;
+
+/** This class represents a transition in an LALR viable prefix recognition 
+ *  machine.  Transitions can be under terminals for non-terminals.  They are
+ *  internally linked together into singly linked lists containing all the 
+ *  transitions out of a single state via the _next field.
+ *
+ * @see     java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ *
+ */
+public class lalr_transition {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor.
+   * @param on_sym  symbol we are transitioning on.
+   * @param to_st   state we transition to.
+   * @param nxt     next transition in linked list.
+   */
+  public lalr_transition(symbol on_sym, lalr_state to_st, lalr_transition nxt)
+    throws internal_error
+    {
+      /* sanity checks */
+      if (on_sym == null)
+    throw new internal_error("Attempt to create transition on null symbol");
+      if (to_st == null)
+    throw new internal_error("Attempt to create transition to null state");
+
+      /* initialize */
+      _on_symbol = on_sym;
+      _to_state  = to_st;
+      _next      = nxt;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with null next. 
+   * @param on_sym  symbol we are transitioning on.
+   * @param to_st   state we transition to.
+   */
+  public lalr_transition(symbol on_sym, lalr_state to_st) throws internal_error
+    {
+      this(on_sym, to_st, null);
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The symbol we make the transition on. */
+  protected symbol _on_symbol;
+
+  /** The symbol we make the transition on. */
+  public symbol on_symbol() {return _on_symbol;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The state we transition to. */
+  protected lalr_state _to_state;
+
+  /** The state we transition to. */
+  public lalr_state to_state() {return _to_state;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Next transition in linked list of transitions out of a state */
+  protected lalr_transition _next;
+
+  /** Next transition in linked list of transitions out of a state */
+  public lalr_transition next() {return _next;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      String result;
+
+      result = "transition on " + on_symbol().name() + " to state [";
+      result += _to_state.index();
+      result += "]";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/lexer.java b/tools/dasm/src/java_cup/lexer.java
new file mode 100644
index 0000000..2b0a056
--- /dev/null
+++ b/tools/dasm/src/java_cup/lexer.java
@@ -0,0 +1,475 @@
+package java_cup;
+
+import java.util.Hashtable;
+
+import java_cup.runtime.str_token;
+import java_cup.runtime.token;
+
+/** This class implements a small scanner (aka lexical analyzer or lexer) for
+ *  the JavaCup specification.  This scanner reads characters from standard 
+ *  input (System.in) and returns integers corresponding to the terminal 
+ *  number of the next token.  Once end of input is reached the EOF token is 
+ *  returned on every subsequent call.<p>
+ *  Tokens currently returned include: <pre>
+ *    Symbol        Constant Returned     Symbol        Constant Returned
+ *    ------        -----------------     ------        -----------------
+ *    "package"     PACKAGE               "import"      IMPORT 
+ *    "code"        CODE                  "action"      ACTION 
+ *    "parser"      PARSER                "terminal"    TERMINAL
+ *    "non"         NON                   "init"        INIT 
+ *    "scan"        SCAN                  "with"        WITH
+ *    "start"       START                   ;           SEMI 
+ *      ,           COMMA                   *           STAR 
+ *      .           DOT                     :           COLON
+ *      ::=         COLON_COLON_EQUALS      |           BAR
+ *    identifier    ID                    {:...:}       CODE_STRING
+ *    "debug"       DEBUG
+ *  </pre>
+ *  All symbol constants are defined in sym.java which is generated by 
+ *  JavaCup from parser.cup.<p>
+ * 
+ *  In addition to the scanner proper (called first via init() then with
+ *  next_token() to get each token) this class provides simple error and 
+ *  warning routines and keeps a count of errors and warnings that is 
+ *  publicly accessible.<p>
+ *  
+ *  This class is "static" (i.e., it has only static members and methods).
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class lexer {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The only constructor is private, so no instances can be created. */
+  private lexer() { }
+
+  /*-----------------------------------------------------------*/
+  /*--- Static (Class) Variables ------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** First character of lookahead. */
+  protected static int next_char; 
+
+  /** Second character of lookahead. */
+  protected static int next_char2;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** EOF constant. */
+  protected static final int EOF_CHAR = -1;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Table of keywords.  Keywords are initially treated as identifiers.
+   *  Just before they are returned we look them up in this table to see if
+   *  they match one of the keywords.  The string of the name is the key here,
+   *  which indexes Integer objects holding the symbol number. 
+   */
+  protected static Hashtable keywords = new Hashtable(23);
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Table of single character symbols.  For ease of implementation, we 
+   *  store all unambiguous single character tokens in this table of Integer
+   *  objects keyed by Integer objects with the numerical value of the 
+   *  appropriate char (currently Character objects have a bug which precludes
+   *  their use in tables).
+   */
+  protected static Hashtable char_symbols = new Hashtable(11);
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Current line number for use in error messages. */
+  protected static int current_line = 1;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Character position in current line. */
+  protected static int current_position = 1;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of total errors detected so far. */
+  public static int error_count = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of warnings issued so far */
+  public static int warning_count = 0;
+
+  /*-----------------------------------------------------------*/
+  /*--- Static Methods ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Initialize the scanner.  This sets up the keywords and char_symbols
+    * tables and reads the first two characters of lookahead.  
+    */
+  public static void init() throws java.io.IOException
+    {
+      /* set up the keyword table */
+      keywords.put("package",  new Integer(sym.PACKAGE));
+      keywords.put("import",   new Integer(sym.IMPORT));
+      keywords.put("code",     new Integer(sym.CODE));
+      keywords.put("action",   new Integer(sym.ACTION));
+      keywords.put("parser",   new Integer(sym.PARSER));
+      keywords.put("terminal", new Integer(sym.TERMINAL));
+      keywords.put("non",      new Integer(sym.NON));
+      keywords.put("init",     new Integer(sym.INIT));
+      keywords.put("scan",     new Integer(sym.SCAN));
+      keywords.put("with",     new Integer(sym.WITH));
+      keywords.put("start",    new Integer(sym.START));
+      keywords.put("debug",    new Integer(sym.DEBUG));
+
+      /* set up the table of single character symbols */
+      char_symbols.put(new Integer(';'), new Integer(sym.SEMI));
+      char_symbols.put(new Integer(','), new Integer(sym.COMMA));
+      char_symbols.put(new Integer('*'), new Integer(sym.STAR));
+      char_symbols.put(new Integer('.'), new Integer(sym.DOT));
+      char_symbols.put(new Integer('|'), new Integer(sym.BAR));
+
+      /* read two characters of lookahead */
+      next_char = System.in.read();
+      if (next_char == EOF_CHAR) 
+    next_char2 = EOF_CHAR;
+      else
+    next_char2 = System.in.read();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Advance the scanner one character in the input stream.  This moves
+   * next_char2 to next_char and then reads a new next_char2.  
+   */
+  protected static void advance() throws java.io.IOException
+    {
+      int old_char;
+
+      old_char = next_char;
+      next_char = next_char2;
+      if (next_char == EOF_CHAR)
+    next_char2 = EOF_CHAR;
+      else
+    next_char2 = System.in.read();
+
+      /* count this */
+      current_position++;
+      if (old_char == '\n')
+    {
+      current_line++;
+      current_position = 1;
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit an error message.  The message will be marked with both the 
+   *  current line number and the position in the line.  Error messages
+   *  are printed on standard error (System.err).
+   * @param message the message to print.
+   */
+  public static void emit_error(String message)
+    {
+      System.err.println("Error at " + current_line + "(" + current_position +
+             "): " + message);
+      error_count++;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Emit a warning message.  The message will be marked with both the 
+   *  current line number and the position in the line.  Messages are 
+   *  printed on standard error (System.err).
+   * @param message the message to print.
+   */
+  public static void emit_warn(String message)
+    {
+      System.err.println("Warning at " + current_line + "(" + current_position +
+             "): " + message);
+      warning_count++;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if a character is ok to start an id. 
+   * @param ch the character in question.
+   */
+  protected static boolean id_start_char(int ch)
+    {
+      return (ch >= 'a' &&  ch <= 'z') || (ch >= 'A' && ch <= 'Z') || 
+         (ch == '_');
+
+      // later need to deal with non-8-bit chars here
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if a character is ok for the middle of an id.
+   * @param ch the character in question. 
+   */
+  protected static boolean id_char(int ch)
+    {
+      return id_start_char(ch) || (ch >= '0' && ch <= '9');
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Try to look up a single character symbol, returns -1 for not found. 
+   * @param ch the character in question.
+   */
+  protected static int find_single_char(int ch)
+    {
+      Integer result;
+
+      result = (Integer)char_symbols.get(new Integer((char)ch));
+      if (result == null) 
+    return -1;
+      else
+    return result.intValue();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Handle swallowing up a comment.  Both old style C and new style C++
+   *  comments are handled.
+   */
+  protected static void swallow_comment() throws java.io.IOException
+    {
+      /* next_char == '/' at this point */
+
+      /* is it a traditional comment */
+      if (next_char2 == '*')
+    {
+      /* swallow the opener */
+      advance(); advance();
+
+      /* swallow the comment until end of comment or EOF */
+      for (;;)
+        {
+          /* if its EOF we have an error */
+          if (next_char == EOF_CHAR)
+        {
+          emit_error("Specification file ends inside a comment");
+          return;
+        }
+
+          /* if we can see the closer we are done */
+          if (next_char == '*' && next_char2 == '/')
+        {
+          advance();
+          advance();
+          return;
+        }
+
+          /* otherwise swallow char and move on */
+          advance();
+        }
+    }
+
+      /* is its a new style comment */
+      if (next_char2 == '/')
+    {
+      /* swallow the opener */
+      advance(); advance();
+
+      /* swallow to '\n', '\f', or EOF */ 
+      while (next_char != '\n' && next_char != '\f' && next_char!=EOF_CHAR)
+        advance();
+
+      return;
+
+    }
+
+      /* shouldn't get here, but... if we get here we have an error */
+      emit_error("Malformed comment in specification -- ignored");
+      advance();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Swallow up a code string.  Code strings begin with "{:" and include
+      all characters up to the first occurrence of ":}" (there is no way to 
+      include ":}" inside a code string).  The routine returns an str_token
+      object suitable for return by the scanner.
+   */
+  protected static token do_code_string() throws java.io.IOException
+    {
+      StringBuffer result = new StringBuffer();
+
+      /* at this point we have lookahead of "{:" -- swallow that */
+      advance(); advance();
+
+      /* save chars until we see ":}" */
+      while (!(next_char == ':' && next_char2 == '}'))
+    {
+      /* if we have run off the end issue a message and break out of loop */
+      if (next_char == EOF_CHAR)
+        {
+          emit_error("Specification file ends inside a code string");
+          break;
+        }
+
+      /* otherwise record the char and move on */
+      result.append(new Character((char)next_char));
+      advance();
+    }
+
+      /* advance past the closer and build a return token */
+      advance(); advance();
+      return new str_token(sym.CODE_STRING, result.toString());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Process an identifier.  Identifiers begin with a letter, underscore,
+   *  or dollar sign, which is followed by zero or more letters, numbers,
+   *  underscores or dollar signs.  This routine returns an str_token suitable
+   *  for return by the scanner.
+   */
+  protected static token do_id() throws java.io.IOException
+    {
+      StringBuffer result = new StringBuffer();
+      String       result_str;
+      Integer      keyword_num;
+      char         buffer[] = new char[1];
+
+      /* next_char holds first character of id */
+      buffer[0] = (char)next_char;
+      result.append(buffer,0,1);
+      advance();
+
+      /* collect up characters while they fit in id */ 
+      while(id_char(next_char))
+    {
+          buffer[0] = (char)next_char;
+      result.append(buffer,0,1);
+      advance();
+    }
+
+      /* extract a string and try to look it up as a keyword */
+      result_str = result.toString();
+      keyword_num = (Integer)keywords.get(result_str);
+
+      /* if we found something, return that keyword */
+      if (keyword_num != null)
+    return new token(keyword_num.intValue());
+
+      /* otherwise build and return an id token with an attached string */
+      return new str_token(sym.ID, result_str);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return one token.  This is the main external interface to the scanner.
+   *  It consumes sufficient characters to determine the next input token
+   *  and returns it.  To help with debugging, this routine actually calls
+   *  real_next_token() which does the work.  If you need to debug the 
+   *  parser, this can be changed to call debug_next_token() which prints
+   *  a debugging message before returning the token.
+   */
+  public static token next_token() throws java.io.IOException
+    {
+      return real_next_token();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Debugging version of next_token().  This routine calls the real scanning
+   *  routine, prints a message on System.out indicating what the token is,
+   *  then returns it.
+   */
+  public static token debug_next_token() throws java.io.IOException
+    {
+      token result = real_next_token();
+      System.out.println("# next_token() => " + result.sym);
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The actual routine to return one token.  This is normally called from
+   *  next_token(), but for debugging purposes can be called indirectly from
+   *  debug_next_token(). 
+   */
+  protected static token real_next_token() throws java.io.IOException
+    {
+      int sym_num;
+
+      for (;;)
+    {
+      /* look for white space */
+      if (next_char == ' ' || next_char == '\t' || next_char == '\n' ||
+          next_char == '\f' ||  next_char == '\r')
+        {
+          /* advance past it and try the next character */
+          advance();
+          continue;
+        }
+
+      /* look for a single character symbol */
+      sym_num = find_single_char(next_char);
+      if (sym_num != -1)
+        {
+          /* found one -- advance past it and return a token for it */
+          advance();
+          return new token(sym_num);
+        }
+
+      /* look for : or ::= */
+      if (next_char == ':')
+        {
+          /* if we don't have a second ':' return COLON */
+          if (next_char2 != ':') 
+        {
+          advance();
+          return new token(sym.COLON);
+        }
+
+          /* move forward and look for the '=' */
+          advance();
+          if (next_char2 == '=') 
+        {
+          advance(); advance();
+          return new token(sym.COLON_COLON_EQUALS);
+        }
+          else
+        {
+          /* return just the colon (already consumed) */
+          return new token(sym.COLON);
+        }
+        }
+
+      /* look for a comment */
+      if (next_char == '/' && (next_char2 == '*' || next_char2 == '/'))
+        {
+          /* swallow then continue the scan */
+          swallow_comment();
+          continue;
+        }
+
+      /* look for start of code string */
+      if (next_char == '{' && next_char2 == ':')
+        return do_code_string();
+
+      /* look for an id or keyword */
+      if (id_start_char(next_char)) return do_id();
+
+      /* look for EOF */
+      if (next_char == EOF_CHAR) return new token(sym.EOF);
+
+      /* if we get here, we have an unrecognized character */
+      emit_warn("Unrecognized character '" + 
+        new Character((char)next_char) + "'(" + next_char + 
+        ") -- ignored");
+
+      /* advance past it */
+      advance();
+    }
+    }
+
+  /*-----------------------------------------------------------*/
+};
+
diff --git a/tools/dasm/src/java_cup/lr_item_core.java b/tools/dasm/src/java_cup/lr_item_core.java
new file mode 100644
index 0000000..164bf4e
--- /dev/null
+++ b/tools/dasm/src/java_cup/lr_item_core.java
@@ -0,0 +1,270 @@
+
+package java_cup;
+
+/** The "core" of an LR item.  This includes a production and the position
+ *  of a marker (the "dot") within the production.  Typically item cores 
+ *  are written using a production with an embedded "dot" to indicate their 
+ *  position.  For example: <pre>
+ *     A ::= B * C d E
+ *  </pre>
+ *  This represents a point in a parse where the parser is trying to match
+ *  the given production, and has succeeded in matching everything before the 
+ *  "dot" (and hence is expecting to see the symbols after the dot next).  See 
+ *  lalr_item, lalr_item_set, and lalr_start for full details on the meaning 
+ *  and use of items.
+ *
+ * @see     java_cup.lalr_item
+ * @see     java_cup.lalr_item_set
+ * @see     java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+*/
+
+public class lr_item_core {
+   
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor.
+   * @param prod production this item uses.
+   * @param pos  position of the "dot" within the item.
+   */
+  public lr_item_core(production prod, int pos) throws internal_error
+    {
+      symbol          after_dot = null;
+      production_part part;
+
+      if (prod == null)
+    throw new internal_error(
+      "Attempt to create an lr_item_core with a null production");
+
+      _the_production = prod;
+
+      if (pos < 0 || pos > _the_production.rhs_length())
+    throw new internal_error(
+      "Attempt to create an lr_item_core with a bad dot position");
+
+      _dot_pos = pos;
+
+      /* compute and cache hash code now */
+      _core_hash_cache = 13*_the_production.hashCode() + pos;
+
+      /* cache the symbol after the dot */
+      if (_dot_pos < _the_production.rhs_length())
+    {
+      part = _the_production.rhs(_dot_pos);
+      if (!part.is_action())
+        _symbol_after_dot = ((symbol_part)part).the_symbol();
+    }
+    } 
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor for dot at start of right hand side. 
+   * @param prod production this item uses.
+   */
+  public lr_item_core(production prod) throws internal_error
+    {
+      this(prod,0);
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The production for the item. */
+  protected production _the_production;
+
+  /** The production for the item. */
+  public production the_production() {return _the_production;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The position of the "dot" -- this indicates the part of the production 
+   *  that the marker is before, so 0 indicates a dot at the beginning of 
+   *  the RHS.
+   */
+  protected int _dot_pos;
+
+  /** The position of the "dot" -- this indicates the part of the production 
+   *  that the marker is before, so 0 indicates a dot at the beginning of 
+   *  the RHS.
+   */
+  public int dot_pos() {return _dot_pos;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Cache of the hash code. */
+  protected int _core_hash_cache;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Cache of symbol after the dot. */
+  protected symbol _symbol_after_dot = null;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Is the dot at the end of the production? */
+  public boolean dot_at_end() 
+    {
+       return _dot_pos >= _the_production.rhs_length();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return the symbol after the dot.  If there is no symbol after the dot
+   *  we return null. */
+  public symbol symbol_after_dot()
+    {
+      /* use the cached symbol */
+      return _symbol_after_dot;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if we have a dot before a non terminal, and if so which one 
+   *  (return null or the non terminal). 
+   */
+  public non_terminal dot_before_nt()
+    {
+      symbol sym;
+
+      /* get the symbol after the dot */
+      sym = symbol_after_dot();
+
+      /* if it exists and is a non terminal, return it */
+      if (sym != null && sym.is_non_term())
+    return (non_terminal)sym;
+      else
+    return null;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a new lr_item_core that results from shifting the dot one 
+   *  position to the right. 
+   */
+  public lr_item_core shift_core() throws internal_error
+    {
+      if (dot_at_end()) 
+    throw new internal_error(
+      "Attempt to shift past end of an lr_item_core");
+
+      return new lr_item_core(_the_production, _dot_pos+1);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison for the core only.  This is separate out because we 
+   *  need separate access in a super class. 
+   */
+  public boolean core_equals(lr_item_core other)
+    {
+      return other != null && 
+         _the_production.equals(other._the_production) && 
+         _dot_pos == other._dot_pos;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(lr_item_core other) {return core_equals(other);}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof lr_item_core))
+    return false;
+      else
+    return equals((lr_item_core)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Hash code for the core (separated so we keep non overridden version). */
+  public int core_hashCode()
+    {
+      return _core_hash_cache;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Hash code for the item. */
+  public int hashCode() 
+    {
+      return _core_hash_cache;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string (separated out from toString() so we can call it
+   *  from subclass that overrides toString()).
+   */
+  public String to_simple_string() throws internal_error
+    {
+      String result;
+      production_part part;
+
+      if (_the_production.lhs() != null && 
+      _the_production.lhs().the_symbol() != null &&
+      _the_production.lhs().the_symbol().name() != null)
+    result = _the_production.lhs().the_symbol().name();
+      else
+    result = "$$NULL$$";
+
+      result += " ::= ";
+
+      for (int i = 0; i<_the_production.rhs_length(); i++)
+    {
+      /* do we need the dot before this one? */
+      if (i == _dot_pos)
+        result += "(*) ";
+      
+      /* print the name of the part */
+      if (_the_production.rhs(i) == null)
+        {
+          result += "$$NULL$$ ";
+        }
+      else
+        {
+          part = _the_production.rhs(i);
+          if (part == null)
+        result += "$$NULL$$ ";
+          else if (part.is_action())
+        result += "{ACTION} ";
+          else if (((symbol_part)part).the_symbol() != null &&
+                       ((symbol_part)part).the_symbol().name() != null)
+        result += ((symbol_part)part).the_symbol().name() + " ";
+          else
+        result += "$$NULL$$ ";
+        }
+    }
+
+      /* put the dot after if needed */
+      if (_dot_pos == _the_production.rhs_length())
+    result += "(*) ";
+
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string */
+  public String toString() 
+    {
+      /* can't throw here since super class doesn't, so we crash instead */
+      try {
+        return to_simple_string();
+      } catch(internal_error e) {
+    e.crash();
+    return null;
+      }
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+   
diff --git a/tools/dasm/src/java_cup/non_terminal.java b/tools/dasm/src/java_cup/non_terminal.java
new file mode 100644
index 0000000..db7fff0
--- /dev/null
+++ b/tools/dasm/src/java_cup/non_terminal.java
@@ -0,0 +1,280 @@
+package java_cup;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** This class represents a non-terminal symbol in the grammar.  Each
+ *  non terminal has a textual name, an index, and a string which indicates
+ *  the type of object it will be implemented with at runtime (i.e. the class
+ *  of object that will be pushed on the parse stack to represent it). 
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class non_terminal extends symbol {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor.
+   * @param nm  the name of the non terminal.
+   * @param tp  the type string for the non terminal.
+   */
+  public non_terminal(String nm, String tp) 
+    {
+      /* super class does most of the work */
+      super(nm, tp);
+
+      /* add to set of all non terminals and check for duplicates */
+      Object conflict = _all.put(nm,this);
+      if (conflict != null)
+    // can't throw an exception here because these are used in static
+    // initializers, so we crash instead
+    // was: 
+    // throw new internal_error("Duplicate non-terminal ("+nm+") created");
+    (new internal_error("Duplicate non-terminal ("+nm+") created")).crash();
+
+      /* assign a unique index */
+      _index = next_index++;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with default type. 
+   * @param nm  the name of the non terminal.
+   */
+  public non_terminal(String nm) 
+    {
+      this(nm, null);
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Table of all non-terminals -- elements are stored using name strings 
+   *  as the key 
+   */
+  protected static Hashtable _all = new Hashtable();
+
+  /** Access to all non-terminals. */
+  public static Enumeration all() {return _all.elements();};
+
+  /** lookup a non terminal by name string */ 
+  public static non_terminal find(String with_name)
+    {
+      if (with_name == null)
+        return null;
+      else 
+        return (non_terminal)_all.get(with_name);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Total number of non-terminals. */
+  public static int number() {return _all.size();};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Static counter to assign unique indexes. */
+  protected static int next_index = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Static counter for creating unique non-terminal names */
+  static protected int next_nt = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** special non-terminal for start symbol */
+  public static final non_terminal START_nt = new non_terminal("$START");
+
+  /*-----------------------------------------------------------*/
+  /*--- Static Methods ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+     
+  /** Method for creating a new uniquely named hidden non-terminal using 
+   *  the given string as a base for the name (or "NT$" if null is passed).
+   * @param prefix base name to construct unique name from. 
+   */
+  static non_terminal create_new(String prefix) throws internal_error
+    {
+      if (prefix == null) prefix = "NT$";
+      return new non_terminal(prefix + next_nt++);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** static routine for creating a new uniquely named hidden non-terminal */
+  static non_terminal create_new() throws internal_error
+    { 
+      return create_new(null); 
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute nullability of all non-terminals. */
+  public static void compute_nullability() throws internal_error
+    {
+      boolean      change = true;
+      non_terminal nt;
+      Enumeration  e;
+      production   prod;
+
+      /* repeat this process until there is no change */
+      while (change)
+    {
+      /* look for a new change */
+      change = false;
+
+      /* consider each non-terminal */
+      for (e=all(); e.hasMoreElements(); )
+        {
+          nt = (non_terminal)e.nextElement();
+
+          /* only look at things that aren't already marked nullable */
+          if (!nt.nullable())
+        {
+          if (nt.looks_nullable())
+            {
+              nt._nullable = true;
+              change = true;
+            }
+        }
+        }
+    }
+      
+      /* do one last pass over the productions to finalize all of them */
+      for (e=production.all(); e.hasMoreElements(); )
+    {
+      prod = (production)e.nextElement();
+      prod.set_nullable(prod.check_nullable());
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute first sets for all non-terminals.  This assumes nullability has
+   *  already computed.
+   */
+  public static void compute_first_sets() throws internal_error
+    {
+      boolean      change = true;
+      Enumeration  n;
+      Enumeration  p;
+      non_terminal nt;
+      production   prod;
+      terminal_set prod_first;
+
+      /* repeat this process until we have no change */
+      while (change)
+    {
+      /* look for a new change */
+      change = false;
+
+      /* consider each non-terminal */
+      for (n = all(); n.hasMoreElements(); )
+        {
+          nt = (non_terminal)n.nextElement();
+
+          /* consider every production of that non terminal */
+          for (p = nt.productions(); p.hasMoreElements(); )
+        {
+          prod = (production)p.nextElement();
+
+          /* get the updated first of that production */
+          prod_first = prod.check_first_set();
+
+          /* if this going to add anything, add it */
+          if (!prod_first.is_subset_of(nt._first_set))
+            {
+              change = true;
+              nt._first_set.add(prod_first);
+            }
+        }
+        }
+    }
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Table of all productions with this non terminal on the LHS. */
+  protected Hashtable _productions = new Hashtable(11);
+
+  /** Access to productions with this non terminal on the LHS. */
+  public Enumeration productions() {return _productions.elements();};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Total number of productions with this non terminal on the LHS. */
+  public int num_productions() {return _productions.size();};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a production to our set of productions. */
+  public void add_production(production prod) throws internal_error
+    {
+      /* catch improper productions */
+      if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
+    throw new internal_error(
+      "Attempt to add invalid production to non terminal production table");
+
+      /* add it to the table, keyed with itself */
+      _productions.put(prod,prod);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Nullability of this non terminal. */
+  protected boolean _nullable;
+
+  /** Nullability of this non terminal. */
+  public boolean nullable() {return _nullable;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** First set for this non-terminal. */
+  protected terminal_set _first_set = new terminal_set();
+
+  /** First set for this non-terminal. */
+  public terminal_set first_set() {return _first_set;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Indicate that this symbol is a non-terminal. */
+  public boolean is_non_term() 
+    {
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Test to see if this non terminal currently looks nullable. */
+  protected boolean looks_nullable() throws internal_error
+    {
+      /* look and see if any of the productions now look nullable */
+      for (Enumeration e = productions(); e.hasMoreElements(); )
+    /* if the production can go to empty, we are nullable */
+    if (((production)e.nextElement()).check_nullable())
+      return true;
+
+      /* none of the productions can go to empty, so we are not nullable */
+      return false;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** convert to string */
+  public String toString()
+    {
+      return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");
+    }
+
+  /*-----------------------------------------------------------*/
+};
diff --git a/tools/dasm/src/java_cup/parse_action.java b/tools/dasm/src/java_cup/parse_action.java
new file mode 100644
index 0000000..1adc92b
--- /dev/null
+++ b/tools/dasm/src/java_cup/parse_action.java
@@ -0,0 +1,87 @@
+
+package java_cup;
+
+/** This class serves as the base class for entries in a parse action table.  
+ *  Full entries will either be SHIFT(state_num), REDUCE(production), or ERROR.
+ *  Objects of this base class will default to ERROR, while the other two 
+ *  types will be  represented by subclasses.
+ * 
+ * @see     java_cup.reduce_action
+ * @see     java_cup.shift_action
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class parse_action {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. */
+  public parse_action()
+    {
+      /* nothing to do in the base class */
+    }
+
+ 
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constant for action type -- error action. */
+  public static final int ERROR = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constant for action type -- shift action. */
+  public static final int SHIFT = 1;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constants for action type -- reduce action. */
+  public static final int REDUCE = 2;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+     
+  /** Quick access to the type -- base class defaults to error. */
+  public int kind() {return ERROR;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality test. */
+  public boolean equals(parse_action other)
+    {
+      /* we match all error actions */
+      return other != null && other.kind() == ERROR;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality test. */
+  public boolean equals(Object other)
+    {
+      if (other instanceof parse_action)
+    return equals((parse_action)other);
+      else
+    return false;
+    }
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute a hash code. */
+  public int hashCode()
+    {
+      /* all objects of this class hash together */
+      return 0xCafe123;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to string. */
+  public String toString() {return "ERROR";}
+
+  /*-----------------------------------------------------------*/
+};
+    
diff --git a/tools/dasm/src/java_cup/parse_action_row.java b/tools/dasm/src/java_cup/parse_action_row.java
new file mode 100644
index 0000000..d12b0af
--- /dev/null
+++ b/tools/dasm/src/java_cup/parse_action_row.java
@@ -0,0 +1,106 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the 
+ *  parse action table.
+ */
+public class parse_action_row {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+           
+  /** Simple constructor.  Note: this should not be used until the number of
+   *  terminals in the grammar has been established.
+   */
+  public parse_action_row()
+    {
+      /* make sure the size is set */
+      if (_size <= 0 )  _size = terminal.number();
+
+      /* allocate the array */
+      under_term = new parse_action[size()];
+
+      /* set each element to an error action */
+      for (int i=0; i<_size; i++)
+    under_term[i] = new parse_action();
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Number of columns (terminals) in every row. */
+  protected static int _size = 0;
+
+  /** Number of columns (terminals) in every row. */
+  public static int size() {return _size;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Table of reduction counts (reused by compute_default()). */
+  protected static int reduction_count[] = null;
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Actual action entries for the row. */
+  public parse_action under_term[];
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Default (reduce) action for this row.  -1 will represent default 
+   *  of error. 
+   */
+  public int default_reduce;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+    
+  /** Compute the default (reduce) action for this row and store it in 
+   *  default_reduce.  In the case of non-zero default we will have the 
+   *  effect of replacing all errors by that reduction.  This may cause 
+   *  us to do erroneous reduces, but will never cause us to shift past 
+   *  the point of the error and never cause an incorrect parse.  -1 will 
+   *  be used to encode the fact that no reduction can be used as a 
+   *  default (in which case error will be used).
+   */
+  public void compute_default()
+    {
+      int i, prod, max_prod, max_red;
+
+      /* if we haven't allocated the count table, do so now */
+      if (reduction_count == null) 
+    reduction_count = new int[production.number()];
+
+      /* clear the reduction count table and maximums */
+      for (i = 0; i < production.number(); i++)
+    reduction_count[i] = 0;
+      max_prod = -1;
+      max_red = 0;
+     
+      /* walk down the row and look at the reduces */
+      for (i = 0; i < size(); i++)
+    if (under_term[i].kind() == parse_action.REDUCE)
+      {
+        /* count the reduce in the proper production slot and keep the 
+           max up to date */
+        prod = ((reduce_action)under_term[i]).reduce_with().index();
+        reduction_count[prod]++;
+        if (reduction_count[prod] > max_red)
+          {
+        max_red = reduction_count[prod];
+        max_prod = prod;
+          }
+      }
+
+       /* record the max as the default (or -1 for not found) */
+       default_reduce = max_prod;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
diff --git a/tools/dasm/src/java_cup/parse_action_table.java b/tools/dasm/src/java_cup/parse_action_table.java
new file mode 100644
index 0000000..002b1d8
--- /dev/null
+++ b/tools/dasm/src/java_cup/parse_action_table.java
@@ -0,0 +1,143 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+
+/** This class represents the complete "action" table of the parser. 
+ *  It has one row for each state in the parse machine, and a column for
+ *  each terminal symbol.  Each entry in the table represents a shift,
+ *  reduce, or an error.  
+ *
+ * @see     java_cup.parse_action
+ * @see     java_cup.parse_action_row
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class parse_action_table {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor.  All terminals, non-terminals, and productions must 
+   *  already have been entered, and the viable prefix recognizer should
+   *  have been constructed before this is called.
+   */
+  public parse_action_table()
+    {
+      /* determine how many states we are working with */
+      _num_states = lalr_state.number();
+
+      /* allocate the array and fill it in with empty rows */
+      under_state = new parse_action_row[_num_states];
+      for (int i=0; i<_num_states; i++)
+    under_state[i] = new parse_action_row();
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** How many rows/states are in the machine/table. */
+  protected int _num_states;
+
+  /** How many rows/states are in the machine/table. */
+  public int num_states() {return _num_states;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Actual array of rows, one per state. */
+  public  parse_action_row[] under_state;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Check the table to ensure that all productions have been reduced. 
+   *  Issue a warning message (to System.err) for each production that
+   *  is never reduced.
+   */
+  public void check_reductions()
+    throws internal_error
+    {
+      parse_action act;
+      production   prod;
+
+      /* tabulate reductions -- look at every table entry */
+      for (int row = 0; row < num_states(); row++)
+    {
+      for (int col = 0; col < under_state[row].size(); col++)
+        {
+          /* look at the action entry to see if its a reduce */
+          act = under_state[row].under_term[col];
+          if (act != null && act.kind() == parse_action.REDUCE)
+        {
+          /* tell production that we used it */
+          ((reduce_action)act).reduce_with().note_reduction_use();
+        }
+        }
+    }
+
+      /* now go across every production and make sure we hit it */
+      for (Enumeration p = production.all(); p.hasMoreElements(); )
+    {
+      prod = (production)p.nextElement();
+
+      /* if we didn't hit it give a warning */
+      if (prod.num_reductions() == 0)
+        {
+          /* count it *
+          emit.not_reduced++;
+
+          /* give a warning if they haven't been turned off */
+          if (!emit.nowarn)
+        {
+          System.err.println("*** Production \"" + 
+                  prod.to_simple_string() + "\" never reduced");
+          lexer.warning_count++;
+        }
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      String result;
+      int cnt;
+
+      result = "-------- ACTION_TABLE --------\n";
+      for (int row = 0; row < num_states(); row++)
+    {
+      result += "From state #" + row + "\n";
+      cnt = 0;
+      for (int col = 0; col < under_state[row].size(); col++)
+        {
+          /* if the action is not an error print it */ 
+          if (under_state[row].under_term[col].kind() != parse_action.ERROR)
+        {
+          result += col + ":" + under_state[row].under_term[col] + " ";
+
+          /* end the line after the 3rd one */
+          cnt++;
+          if (cnt == 3)
+            {
+              result += "\n";
+              cnt = 0;
+            }
+        }
+        }
+          /* finish the line if we haven't just done that */
+      if (cnt != 0) result += "\n";
+    }
+      result += "------------------------------";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
diff --git a/tools/dasm/src/java_cup/parse_reduce_row.java b/tools/dasm/src/java_cup/parse_reduce_row.java
new file mode 100644
index 0000000..d9adf68
--- /dev/null
+++ b/tools/dasm/src/java_cup/parse_reduce_row.java
@@ -0,0 +1,41 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the 
+ *  reduce-goto parse table. 
+ */
+public class parse_reduce_row {
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. Note: this should not be used until the number
+   *  of terminals in the grammar has been established.
+   */
+  public parse_reduce_row()
+    {
+      /* make sure the size is set */
+      if (_size <= 0 )  _size = non_terminal.number();
+
+      /* allocate the array */
+      under_non_term = new lalr_state[size()];
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Number of columns (non terminals) in every row. */
+  protected static int _size = 0;
+
+  /** Number of columns (non terminals) in every row. */
+  public static int size() {return _size;}
+   
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Actual entries for the row. */
+  public lalr_state under_non_term[];
+};
+
diff --git a/tools/dasm/src/java_cup/parse_reduce_table.java b/tools/dasm/src/java_cup/parse_reduce_table.java
new file mode 100644
index 0000000..4f27eb5
--- /dev/null
+++ b/tools/dasm/src/java_cup/parse_reduce_table.java
@@ -0,0 +1,98 @@
+
+package java_cup;
+
+
+/** This class represents the complete "reduce-goto" table of the parser.
+ *  It has one row for each state in the parse machines, and a column for
+ *  each terminal symbol.  Each entry contains a state number to shift to
+ *  as the last step of a reduce. 
+ *
+ * @see     java_cup.parse_reduce_row
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class parse_reduce_table {
+ 
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor.  Note: all terminals, non-terminals, and productions 
+   *  must already have been entered, and the viable prefix recognizer should
+   *  have been constructed before this is called.
+   */
+  public parse_reduce_table()
+    {
+      /* determine how many states we are working with */
+      _num_states = lalr_state.number();
+
+      /* allocate the array and fill it in with empty rows */
+      under_state = new parse_reduce_row[_num_states];
+      for (int i=0; i<_num_states; i++)
+    under_state[i] = new parse_reduce_row();
+    }
+
+   
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** How many rows/states in the machine/table. */
+  protected int _num_states;
+
+  /** How many rows/states in the machine/table. */
+  public int num_states() {return _num_states;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Actual array of rows, one per state */
+  public  parse_reduce_row[] under_state;
+ 
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      String result;
+      lalr_state goto_st;
+      int cnt;
+
+      result = "-------- REDUCE_TABLE --------\n";
+      for (int row = 0; row < num_states(); row++)
+    {
+      result += "From state #" + row + "\n";
+      cnt = 0;
+      for (int col = 0; col < under_state[row].size(); col++)
+        {
+          /* pull out the table entry */
+          goto_st = under_state[row].under_non_term[col];
+
+          /* if it has action in it, print it */
+          if (goto_st != null)
+        {
+          result += col + ":"; 
+          result += goto_st.index();
+
+          /* end the line after the 3rd one */
+          cnt++;
+          if (cnt == 3)
+            {
+              result += "\n";
+              cnt = 0;
+            }
+        }
+        }
+          /* finish the line if we haven't just done that */
+      if (cnt != 0) result += "\n";
+    }
+      result += "-----------------------------";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
diff --git a/tools/dasm/src/java_cup/parser.cup b/tools/dasm/src/java_cup/parser.cup
new file mode 100644
index 0000000..a64584e
--- /dev/null
+++ b/tools/dasm/src/java_cup/parser.cup
@@ -0,0 +1,620 @@
+
+/*================================================================*/
+/*
+  JavaCup Specification for the JavaCup Specification Language
+  by Scott Hudson, GVU Center, Georgia Tech, August 1995
+
+  This JavaCup specification is used to implement JavaCup itself.
+  It specifies the parser for the JavaCup specification language.
+  (It also serves as a reasonable example of what a typical JavaCup
+  spec looks like).
+
+  The specification has the following parts:
+    Package and import declarations
+      These serve the same purpose as in a normal Java source file
+      (and will appear in the generated code for the parser). In this
+      case we are part of the java_cup package and we import both the
+      java_cup runtime system and Hashtable from the standard Java
+      utilities package.
+
+    Action code
+      This section provides code that is included with the class encapsulating
+      the various pieces of user code embedded in the grammar (i.e., the
+      semantic actions).  This provides a series of helper routines and
+      data structures that the semantic actions use.
+
+    Parser code
+      This section provides code included in the parser class itself.  In
+      this case we override the default error reporting routines.
+
+    Init with and scan with
+      These sections provide small bits of code that initialize, then
+      indicate how to invoke the scanner.
+
+    Symbols and grammar
+      These sections declare all the terminal and non terminal symbols
+      and the types of objects that they will be represented by at runtime,
+      then indicate the start symbol of the grammar (), and finally provide
+      the grammar itself (with embedded actions).
+
+    Operation of the parser
+      The parser acts primarily by accumulating data structures representing
+      various parts of the specification.  Various small parts (e.g., single
+      code strings) are stored as static variables of the emit class and
+      in a few cases as variables declared in the action code section.
+      Terminals, non terminals, and productions, are maintained as collection
+      accessible via static methods of those classes.  In addition, two
+      symbol tables are kept:
+    symbols   maintains the name to object mapping for all symbols
+    non_terms maintains a separate mapping containing only the non terms
+
+      Several intermediate working structures are also declared in the action
+      code section.  These include: rhs_parts, rhs_pos, and lhs_nt which
+      build up parts of the current production while it is being parsed.
+
+  Author(s)
+    Scott Hudson, GVU Center, Georgia Tech.
+
+  Revisions
+    v0.9a   First released version                     [SEH] 8/29/95
+    v0.9b   Updated for beta language (throws clauses) [SEH] 11/25/95
+*/
+/*================================================================*/
+
+package java_cup;
+import java_cup.runtime.*;
+import java.util.Hashtable;
+
+/*----------------------------------------------------------------*/
+
+action code {:
+  /** helper routine to clone a new production part adding a given label */
+  protected production_part add_lab(production_part part, String lab)
+    throws internal_error
+    {
+      /* if there is no label, or this is an action, just return the original */
+      if (lab == null || part.is_action()) return part;
+
+      /* otherwise build a new one with the given label attached */
+      return new symbol_part(((symbol_part)part).the_symbol(),lab);
+    }
+
+  /** max size of right hand side we will support */
+  protected final int MAX_RHS = 200;
+
+  /** array for accumulating right hand side parts */
+  protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+  /** where we are currently in building a right hand side */
+  protected int rhs_pos = 0;
+
+  /** start a new right hand side */
+  protected void new_rhs() {rhs_pos = 0; }
+
+  /** add a new right hand side part */
+  protected void add_rhs_part(production_part part) throws java.lang.Exception
+    {
+      if (rhs_pos >= MAX_RHS)
+    throw new Exception("Internal Error: Productions limited to " +
+                 MAX_RHS + " symbols and actions");
+
+      rhs_parts[rhs_pos] = part;
+      rhs_pos++;
+    }
+
+  /** string to build up multiple part names */
+  protected String multipart_name = new String();
+
+  /** append a new name segment to the accumulated multipart name */
+  protected void append_multipart(String name)
+    {
+      String dot = "";
+
+      /* if we aren't just starting out, put on a dot */
+      if (multipart_name.length() != 0)  dot = ".";
+
+      multipart_name = multipart_name.concat(dot + name);
+    }
+
+  /** table of declared symbols -- contains production parts indexed by name */
+  protected Hashtable symbols = new Hashtable();
+
+  /** table of just non terminals -- contains non_terminals indexed by name */
+  protected Hashtable non_terms = new Hashtable();
+
+  /** declared start non_terminal */
+  protected non_terminal start_nt = null;
+
+  /** left hand side non terminal of the current production */
+  protected non_terminal lhs_nt;
+
+:};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser code {:
+
+  /* override error routines */
+
+  public void report_fatal_error(
+    String   message,
+    Object   info)
+    {
+      done_parsing();
+      lexer.emit_error(message);
+      System.err.println("Can't recover from previous error(s), giving up.");
+      System.exit(1);
+    }
+
+    public void report_error(String message, Object info)
+    {
+      lexer.emit_error(message);
+    }
+:};
+
+/*----------------------------------------------------------------*/
+
+init with {: lexer.init(); :};
+scan with {: return lexer.next_token(); :};
+
+/*----------------------------------------------------------------*/
+
+terminal java_cup.runtime.token
+  PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, INIT, SCAN, WITH,
+  START, SEMI, COMMA, STAR, DOT, COLON, COLON_COLON_EQUALS, BAR,
+  DEBUG;
+
+terminal java_cup.runtime.str_token  ID, CODE_STRING;
+
+non terminal java_cup.runtime.symbol
+  spec, package_spec, import_list, code_part, action_code_part,
+  parser_code_part, symbol_list, start_spec, production_list,
+  multipart_id, import_spec, import_id, init_code, scan_code, symbol,
+  debug_grammar,
+  type_id, term_name_list, non_term_name_list, production, prod_part_list,
+  prod_part, new_term_id, new_non_term_id, rhs_list, rhs, empty;
+
+non terminal java_cup.runtime.str_token  nt_id, symbol_id, label_id, opt_label;
+
+/*----------------------------------------------------------------*/
+
+start with spec;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+spec ::=
+    {:
+          /* declare "error" as a terminal */
+          symbols.put("error", new symbol_part(terminal.error));
+
+          /* declare start non terminal */
+          non_terms.put("$START", non_terminal.START_nt);
+    :}
+    package_spec
+    import_list
+    code_part
+        debug_grammar
+        init_code
+    scan_code
+    symbol_list
+    start_spec
+    production_list
+    |
+    /* error recovery assuming something went wrong before symbols
+       and we have TERMINAL or NON TERMINAL to sync on.  if we get
+       an error after that, we recover inside symbol_list or
+       production_list
+    */
+    error
+    symbol_list
+    start_spec
+    production_list
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+package_spec ::=
+    PACKAGE
+    multipart_id
+    {:
+      /* save the package name */
+      emit.package_name = multipart_name;
+
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_list ::=
+    import_list
+    import_spec
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_spec ::=
+    IMPORT
+    import_id
+    {:
+      /* save this import on the imports list */
+      emit.import_list.push(multipart_name);
+
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+code_part ::= action_code_part parser_code_part ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+action_code_part ::=
+    ACTION CODE CODE_STRING:user_code SEMI
+    {:
+      /* save the user included code string */
+      emit.action_code = user_code.str_val;
+    :}
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser_code_part ::=
+    PARSER CODE CODE_STRING:user_code SEMI
+    {:
+      /* save the user included code string */
+      emit.parser_code = user_code.str_val;
+    :}
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+init_code ::=
+    INIT WITH CODE_STRING:user_code SEMI
+    {:
+      /* save the user code */
+      emit.init_code = user_code.str_val;
+    :}
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+scan_code ::=
+    SCAN WITH CODE_STRING:user_code SEMI
+    {:
+      /* save the user code */
+      emit.scan_code = user_code.str_val;
+    :}
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+debug_grammar ::=
+        DEBUG WITH multipart_id SEMI
+    {:
+      /* save the procedure name */
+          emit.debug_grammar = multipart_name;
+          /* reset the accumulated multipart name */
+          multipart_name = new String();
+    :}
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_list ::= symbol_list symbol | symbol;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol ::=
+    TERMINAL
+    type_id
+    term_name_list
+    {:
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    |
+    NON
+    TERMINAL
+    type_id
+    non_term_name_list
+    {:
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    |
+
+    /* error recovery productions -- sync on semicolon */
+
+    TERMINAL
+    error
+    {:
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    |
+    NON
+    TERMINAL
+    error
+    {:
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    :}
+    SEMI
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+term_name_list ::= term_name_list COMMA new_term_id | new_term_id;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+non_term_name_list ::=
+    non_term_name_list
+    COMMA
+    new_non_term_id
+    |
+    new_non_term_id
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+start_spec ::=
+    START WITH nt_id:start_name
+    {:
+      /* verify that the name has been declared as a non terminal */
+      non_terminal nt = (non_terminal)non_terms.get(start_name.str_val);
+      if (nt == null)
+        {
+          lexer.emit_error( "Start non terminal \"" + start_name.str_val +
+                       "\" has not been declared");
+        }
+          else
+        {
+          /* remember the non-terminal for later */
+          start_nt = nt;
+
+          /* build a special start production */
+          new_rhs();
+          add_rhs_part(new symbol_part(start_nt));
+          add_rhs_part(new symbol_part(terminal.EOF));
+          emit.start_production =
+             new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+          new_rhs();
+        }
+    :}
+    SEMI
+    |
+    empty
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production_list ::= production_list production | production;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production ::=
+    nt_id:lhs_id
+    {:
+      /* lookup the lhs nt */
+      lhs_nt = (non_terminal)non_terms.get(lhs_id.str_val);
+
+          /* if it wasn't declared, emit a message */
+      if (lhs_nt == null)
+        {
+          if (lexer.error_count == 0)
+            lexer.emit_error("LHS non terminal \"" + lhs_id.str_val +
+                   "\" has not been declared");
+        }
+
+      /* reset the rhs accumulation */
+      new_rhs();
+    :}
+    COLON_COLON_EQUALS
+    rhs_list
+    SEMI
+    |
+    error
+    {: lexer.emit_error("Syntax Error"); :}
+    SEMI
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs_list ::= rhs_list BAR rhs | rhs;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs ::=
+    prod_part_list
+    {:
+      if (lhs_nt != null)
+        {
+          /* build the production */
+          production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+          /* if we have no start non-terminal declared and this is
+         the first production, make its lhs nt the start_nt
+         and build a special start production for it. */
+              if (start_nt == null)
+        {
+          start_nt = lhs_nt;
+
+              /* build a special start production */
+              new_rhs();
+              add_rhs_part(new symbol_part(start_nt));
+              add_rhs_part(new symbol_part(terminal.EOF));
+              emit.start_production =
+             new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+              new_rhs();
+        }
+        }
+
+      /* reset the rhs accumulation in any case */
+      new_rhs();
+    :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part_list ::= prod_part_list prod_part | empty;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part ::=
+    symbol_id:symid opt_label:labid
+    {:
+      /* try to look up the id */
+      production_part symb = (production_part)symbols.get(symid.str_val);
+
+      /* if that fails, symbol is undeclared */
+      if (symb == null)
+        {
+          if (lexer.error_count == 0)
+            lexer.emit_error("Symbol \"" + symid.str_val +
+                   "\" has not been declared");
+        }
+      else
+        {
+          /* add a labeled production part */
+          add_rhs_part(add_lab(symb, labid.str_val));
+        }
+    :}
+    |
+    CODE_STRING:code_str
+    {:
+      /* add a new production part */
+      add_rhs_part(new action_part(code_str.str_val));
+    :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+opt_label ::=
+    COLON label_id:labid
+    {: RESULT.str_val = labid.str_val; :}
+    |
+    empty
+    {: RESULT.str_val = null; :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+multipart_id ::=
+    multipart_id DOT ID:another_id
+    {: append_multipart(another_id.str_val); :}
+    |
+    ID:an_id
+    {: append_multipart(an_id.str_val); :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_id ::=
+    multipart_id DOT STAR
+    {: append_multipart("*"); :}
+    |
+    multipart_id
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+type_id ::= multipart_id;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_term_id ::=
+    ID:term_id
+    {:
+      /* see if this terminal has been declared before */
+      if (symbols.get(term_id.str_val) != null)
+        {
+          /* issue a message */
+          lexer.emit_error("Symbol \"" + term_id.str_val +
+               "\" has already been declared");
+        }
+      else
+        {
+          /* build a production_part and put it in the table */
+          symbols.put(term_id.str_val,
+            new symbol_part(new terminal(term_id.str_val, multipart_name)));
+        }
+    :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_non_term_id ::=
+    ID:non_term_id
+    {:
+      /* see if this non terminal has been declared before */
+      if (symbols.get(non_term_id.str_val) != null)
+        {
+          /* issue a message */
+          lexer.emit_error( "Symbol \"" + non_term_id.str_val +
+                                  "\" has already been declared");
+        }
+      else
+        {
+          /* build the non terminal object */
+              non_terminal this_nt =
+        new non_terminal(non_term_id.str_val, multipart_name);
+
+          /* put it in the non_terms table */
+          non_terms.put(non_term_id.str_val, this_nt);
+
+          /* build a production_part and put it in the symbols table */
+          symbols.put(non_term_id.str_val, new symbol_part(this_nt));
+        }
+    :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+nt_id ::=
+    ID:the_id
+    {: RESULT.str_val = the_id.str_val; :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_id ::=
+    ID:the_id
+    {: RESULT.str_val = the_id.str_val; :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+label_id ::=
+    ID:the_id
+    {: RESULT.str_val = the_id.str_val; :}
+    ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+empty ::= /* nothing */;
+
+/*----------------------------------------------------------------*/
diff --git a/tools/dasm/src/java_cup/parser.java b/tools/dasm/src/java_cup/parser.java
new file mode 100644
index 0000000..3230281
--- /dev/null
+++ b/tools/dasm/src/java_cup/parser.java
@@ -0,0 +1,1130 @@
+
+//----------------------------------------------------
+// The following code was generated by Java(tm) CUP v0.9d
+// Thu Aug 10 03:51:39 MSD 2006
+//----------------------------------------------------
+
+package java_cup;
+
+import java.util.Hashtable;
+
+public class parser extends java_cup.runtime.lr_parser {
+
+  /** constructor */
+  public parser() {super();}
+
+  /** production table */
+  protected static final short _production_table[][] = {
+        {0, 2},     {32, 0},     {1, 10},     {1, 4},     {33, 0}, 
+        {2, 4},     {2, 1},     {3, 2},     {3, 1},     {34, 0}, 
+        {11, 4},     {4, 2},     {5, 4},     {5, 1},     {6, 4}, 
+        {6, 1},     {13, 4},     {13, 1},     {14, 4},     {14, 1}, 
+        {16, 4},     {16, 1},     {7, 2},     {7, 1},     {35, 0}, 
+        {15, 5},     {36, 0},     {15, 6},     {37, 0},     {15, 4}, 
+        {38, 0},     {15, 5},     {18, 3},     {18, 1},     {19, 3}, 
+        {19, 1},     {39, 0},     {8, 5},     {8, 1},     {9, 2}, 
+        {9, 1},     {40, 0},     {20, 5},     {41, 0},     {20, 3}, 
+        {25, 3},     {25, 1},     {26, 1},     {21, 2},     {21, 1}, 
+        {22, 2},     {22, 1},     {31, 2},     {31, 1},     {10, 3}, 
+        {10, 1},     {12, 3},     {12, 1},     {17, 1},     {23, 1}, 
+        {24, 1},     {28, 1},     {29, 1},     {30, 1},     {27, 0}
+      };
+
+  /** access to production table */
+  public short[][] production_table() {return _production_table;}
+
+  /** parse action table */
+  protected static final short[][] _action_table = {
+    /*0*/{1,3,2,-2,3,-2,5,-2,6,-2,7,-2,8,-2,9,-2,10,-2,20,-2,-1,0},
+    /*1*/{0,120,-1,0},
+    /*2*/{7,34,8,36,-1,0},
+    /*3*/{2,7,3,-65,5,-65,6,-65,7,-65,8,-65,9,-65,10,-65,20,-65,-1,0},
+    /*4*/{3,-65,5,-65,6,-65,7,-65,8,-65,9,-65,10,-65,20,-65,-1,0},
+    /*5*/{3,-7,5,-7,6,-7,7,-7,8,-7,9,-7,10,-7,20,-7,-1,0},
+    /*6*/{21,8,-1,0},
+    /*7*/{13,-56,16,-56,21,-56,-1,0},
+    /*8*/{13,-5,16,11,-1,0},
+    /*9*/{13,13,-1,0},
+    /*10*/{21,12,-1,0},
+    /*11*/{13,-55,16,-55,21,-55,-1,0},
+    /*12*/{3,-6,5,-6,6,-6,7,-6,8,-6,9,-6,10,-6,20,-6,-1,0},
+    /*13*/{3,17,5,18,6,-65,7,-65,8,-65,9,-65,10,-65,20,-65,-1,0},
+    /*14*/{3,-9,5,-9,6,-9,7,-9,8,-9,9,-9,10,-9,20,-9,-1,0},
+    /*15*/{3,-8,5,-8,6,-8,7,-8,8,-8,9,-8,10,-8,20,-8,-1,0},
+    /*16*/{21,8,-1,0},
+    /*17*/{4,108,-1,0},
+    /*18*/{6,103,7,-65,8,-65,9,-65,10,-65,20,-65,-1,0},
+    /*19*/{6,-14,7,-14,8,-14,9,-14,10,-14,20,-14,-1,0},
+    /*20*/{7,-65,8,-65,9,-65,10,-65,20,22,-1,0},
+    /*21*/{11,99,-1,0},
+    /*22*/{7,-22,8,-22,9,-22,10,-22,-1,0},
+    /*23*/{7,-65,8,-65,9,25,10,-65,-1,0},
+    /*24*/{11,96,-1,0},
+    /*25*/{7,-65,8,-65,10,29,-1,0},
+    /*26*/{7,-18,8,-18,10,-18,-1,0},
+    /*27*/{7,34,8,36,-1,0},
+    /*28*/{11,31,-1,0},
+    /*29*/{7,-20,8,-20,-1,0},
+    /*30*/{22,32,-1,0},
+    /*31*/{13,33,-1,0},
+    /*32*/{7,-19,8,-19,-1,0},
+    /*33*/{1,85,21,8,-1,0},
+    /*34*/{1,-24,7,-24,8,-24,12,-24,21,-24,-1,0},
+    /*35*/{7,72,-1,0},
+    /*36*/{1,-65,7,34,8,36,12,41,21,-65,-1,0},
+    /*37*/{1,47,21,43,-1,0},
+    /*38*/{1,-39,21,-39,-1,0},
+    /*39*/{1,-23,7,-23,8,-23,12,-23,21,-23,-1,0},
+    /*40*/{11,42,-1,0},
+    /*41*/{21,43,-1,0},
+    /*42*/{13,-62,18,-62,-1,0},
+    /*43*/{13,-37,-1,0},
+    /*44*/{13,46,-1,0},
+    /*45*/{1,-38,21,-38,-1,0},
+    /*46*/{13,-44,-1,0},
+    /*47*/{18,-42,-1,0},
+    /*48*/{0,-3,1,47,21,43,-1,0},
+    /*49*/{0,-41,1,-41,21,-41,-1,0},
+    /*50*/{0,-40,1,-40,21,-40,-1,0},
+    /*51*/{18,53,-1,0},
+    /*52*/{13,-65,19,-65,21,-65,22,-65,-1,0},
+    /*53*/{13,68,19,67,-1,0},
+    /*54*/{13,-50,19,-50,21,-50,22,-50,-1,0},
+    /*55*/{13,-48,19,-48,21,59,22,58,-1,0},
+    /*56*/{13,-47,19,-47,-1,0},
+    /*57*/{13,-52,19,-52,21,-52,22,-52,-1,0},
+    /*58*/{13,-63,17,-63,19,-63,21,-63,22,-63,-1,0},
+    /*59*/{13,-65,17,62,19,-65,21,-65,22,-65,-1,0},
+    /*60*/{13,-49,19,-49,21,-49,22,-49,-1,0},
+    /*61*/{21,65,-1,0},
+    /*62*/{13,-54,19,-54,21,-54,22,-54,-1,0},
+    /*63*/{13,-51,19,-51,21,-51,22,-51,-1,0},
+    /*64*/{13,-64,21,-64,22,-64,-1,0},
+    /*65*/{13,-53,21,-53,22,-53,-1,0},
+    /*66*/{13,-65,19,-65,21,-65,22,-65,-1,0},
+    /*67*/{0,-43,1,-43,21,-43,-1,0},
+    /*68*/{13,-46,19,-46,-1,0},
+    /*69*/{13,71,-1,0},
+    /*70*/{0,-45,1,-45,21,-45,-1,0},
+    /*71*/{1,73,21,8,-1,0},
+    /*72*/{13,-31,-1,0},
+    /*73*/{16,11,21,-59,-1,0},
+    /*74*/{21,76,-1,0},
+    /*75*/{13,-61,14,-61,-1,0},
+    /*76*/{13,-27,14,79,-1,0},
+    /*77*/{13,-36,14,-36,-1,0},
+    /*78*/{21,76,-1,0},
+    /*79*/{13,81,-1,0},
+    /*80*/{1,-28,7,-28,8,-28,12,-28,21,-28,-1,0},
+    /*81*/{13,-35,14,-35,-1,0},
+    /*82*/{13,84,-1,0},
+    /*83*/{1,-32,7,-32,8,-32,12,-32,21,-32,-1,0},
+    /*84*/{13,-29,-1,0},
+    /*85*/{21,87,-1,0},
+    /*86*/{13,-60,14,-60,-1,0},
+    /*87*/{13,-34,14,-34,-1,0},
+    /*88*/{13,-25,14,91,-1,0},
+    /*89*/{13,93,-1,0},
+    /*90*/{21,87,-1,0},
+    /*91*/{13,-33,14,-33,-1,0},
+    /*92*/{1,-26,7,-26,8,-26,12,-26,21,-26,-1,0},
+    /*93*/{13,95,-1,0},
+    /*94*/{1,-30,7,-30,8,-30,12,-30,21,-30,-1,0},
+    /*95*/{22,97,-1,0},
+    /*96*/{13,98,-1,0},
+    /*97*/{7,-17,8,-17,10,-17,-1,0},
+    /*98*/{21,8,-1,0},
+    /*99*/{13,101,16,11,-1,0},
+    /*100*/{7,-21,8,-21,9,-21,10,-21,-1,0},
+    /*101*/{7,-16,8,-16,9,-16,10,-16,20,-16,-1,0},
+    /*102*/{4,105,-1,0},
+    /*103*/{7,-12,8,-12,9,-12,10,-12,20,-12,-1,0},
+    /*104*/{22,106,-1,0},
+    /*105*/{13,107,-1,0},
+    /*106*/{7,-15,8,-15,9,-15,10,-15,20,-15,-1,0},
+    /*107*/{22,109,-1,0},
+    /*108*/{13,110,-1,0},
+    /*109*/{6,-13,7,-13,8,-13,9,-13,10,-13,20,-13,-1,0},
+    /*110*/{13,-58,16,115,-1,0},
+    /*111*/{13,-10,-1,0},
+    /*112*/{13,114,-1,0},
+    /*113*/{3,-11,5,-11,6,-11,7,-11,8,-11,9,-11,10,-11,20,-11,-1,0},
+    /*114*/{15,116,21,12,-1,0},
+    /*115*/{13,-57,-1,0},
+    /*116*/{1,-65,7,34,8,36,12,41,21,-65,-1,0},
+    /*117*/{1,47,21,43,-1,0},
+    /*118*/{0,-4,1,47,21,43,-1,0},
+    /*119*/{0,-1,-1,0},
+  };
+
+  /** access to parse action table */
+  public short[][] action_table() {return _action_table;}
+
+  /** reduce_goto table */
+  protected static final short[][] _reduce_table = {
+    /*0*/{1,1,32,3,-1,-1},
+    /*1*/{-1,-1},
+    /*2*/{7,116,15,34,-1,-1},
+    /*3*/{2,4,27,5,-1,-1},
+    /*4*/{3,13,27,14,-1,-1},
+    /*5*/{-1,-1},
+    /*6*/{10,8,-1,-1},
+    /*7*/{-1,-1},
+    /*8*/{33,9,-1,-1},
+    /*9*/{-1,-1},
+    /*10*/{-1,-1},
+    /*11*/{-1,-1},
+    /*12*/{-1,-1},
+    /*13*/{4,20,5,18,11,15,27,19,-1,-1},
+    /*14*/{-1,-1},
+    /*15*/{-1,-1},
+    /*16*/{10,110,12,111,-1,-1},
+    /*17*/{-1,-1},
+    /*18*/{6,103,27,101,-1,-1},
+    /*19*/{-1,-1},
+    /*20*/{16,23,27,22,-1,-1},
+    /*21*/{-1,-1},
+    /*22*/{-1,-1},
+    /*23*/{13,25,27,26,-1,-1},
+    /*24*/{-1,-1},
+    /*25*/{14,27,27,29,-1,-1},
+    /*26*/{-1,-1},
+    /*27*/{7,36,15,34,-1,-1},
+    /*28*/{-1,-1},
+    /*29*/{-1,-1},
+    /*30*/{-1,-1},
+    /*31*/{-1,-1},
+    /*32*/{-1,-1},
+    /*33*/{10,73,17,85,-1,-1},
+    /*34*/{-1,-1},
+    /*35*/{-1,-1},
+    /*36*/{8,37,15,39,27,38,-1,-1},
+    /*37*/{9,48,20,49,28,47,-1,-1},
+    /*38*/{-1,-1},
+    /*39*/{-1,-1},
+    /*40*/{-1,-1},
+    /*41*/{28,43,-1,-1},
+    /*42*/{-1,-1},
+    /*43*/{39,44,-1,-1},
+    /*44*/{-1,-1},
+    /*45*/{-1,-1},
+    /*46*/{41,69,-1,-1},
+    /*47*/{40,51,-1,-1},
+    /*48*/{20,50,28,47,-1,-1},
+    /*49*/{-1,-1},
+    /*50*/{-1,-1},
+    /*51*/{-1,-1},
+    /*52*/{21,55,25,53,26,56,27,54,-1,-1},
+    /*53*/{-1,-1},
+    /*54*/{-1,-1},
+    /*55*/{22,60,29,59,-1,-1},
+    /*56*/{-1,-1},
+    /*57*/{-1,-1},
+    /*58*/{-1,-1},
+    /*59*/{27,62,31,63,-1,-1},
+    /*60*/{-1,-1},
+    /*61*/{30,65,-1,-1},
+    /*62*/{-1,-1},
+    /*63*/{-1,-1},
+    /*64*/{-1,-1},
+    /*65*/{-1,-1},
+    /*66*/{21,55,26,68,27,54,-1,-1},
+    /*67*/{-1,-1},
+    /*68*/{-1,-1},
+    /*69*/{-1,-1},
+    /*70*/{-1,-1},
+    /*71*/{10,73,17,74,-1,-1},
+    /*72*/{38,82,-1,-1},
+    /*73*/{-1,-1},
+    /*74*/{19,76,24,77,-1,-1},
+    /*75*/{-1,-1},
+    /*76*/{36,79,-1,-1},
+    /*77*/{-1,-1},
+    /*78*/{24,81,-1,-1},
+    /*79*/{-1,-1},
+    /*80*/{-1,-1},
+    /*81*/{-1,-1},
+    /*82*/{-1,-1},
+    /*83*/{-1,-1},
+    /*84*/{37,93,-1,-1},
+    /*85*/{18,88,23,87,-1,-1},
+    /*86*/{-1,-1},
+    /*87*/{-1,-1},
+    /*88*/{35,89,-1,-1},
+    /*89*/{-1,-1},
+    /*90*/{23,91,-1,-1},
+    /*91*/{-1,-1},
+    /*92*/{-1,-1},
+    /*93*/{-1,-1},
+    /*94*/{-1,-1},
+    /*95*/{-1,-1},
+    /*96*/{-1,-1},
+    /*97*/{-1,-1},
+    /*98*/{10,99,-1,-1},
+    /*99*/{-1,-1},
+    /*100*/{-1,-1},
+    /*101*/{-1,-1},
+    /*102*/{-1,-1},
+    /*103*/{-1,-1},
+    /*104*/{-1,-1},
+    /*105*/{-1,-1},
+    /*106*/{-1,-1},
+    /*107*/{-1,-1},
+    /*108*/{-1,-1},
+    /*109*/{-1,-1},
+    /*110*/{-1,-1},
+    /*111*/{34,112,-1,-1},
+    /*112*/{-1,-1},
+    /*113*/{-1,-1},
+    /*114*/{-1,-1},
+    /*115*/{-1,-1},
+    /*116*/{8,117,15,39,27,38,-1,-1},
+    /*117*/{9,118,20,49,28,47,-1,-1},
+    /*118*/{20,50,28,47,-1,-1},
+    /*119*/{-1,-1},
+  };
+
+  /** access to reduce_goto table */
+  public short[][] reduce_table() {return _reduce_table;}
+
+  /** instance of action encapsulation class */
+  protected CUP$actions action_obj;
+
+  /** action encapsulation object initializer */
+  protected void init_actions()
+    {
+      action_obj = new CUP$actions();
+    }
+
+  /** invoke a user supplied parse action */
+  public java_cup.runtime.symbol do_action(
+    int                        act_num,
+    java_cup.runtime.lr_parser parser,
+    java.util.Stack            stack,
+    int                        top)
+    throws java.lang.Exception
+  {
+    /* call code in generated class */
+    return action_obj.CUP$do_action(act_num, parser, stack, top);
+  }
+
+  /** start state */
+  public int start_state() {return 0;}
+  /** start production */
+  public int start_production() {return 0;}
+
+  /** EOF symbol index */
+  public int EOF_sym() {return 0;}
+
+  /** error symbol index */
+  public int error_sym() {return 1;}
+
+
+  /** user initialization */
+  public void user_init() throws java.lang.Exception
+    {
+ lexer.init(); 
+    }
+
+  /** scan to get the next token */
+  public java_cup.runtime.token scan()
+    throws java.lang.Exception
+    {
+ return lexer.next_token(); 
+    }
+
+
+
+  /* override error routines */
+
+  public void report_fatal_error(
+    String   message,
+    Object   info)
+    {
+      done_parsing();
+      lexer.emit_error(message);
+      System.err.println("Can't recover from previous error(s), giving up.");
+      System.exit(1);
+    }
+
+    public void report_error(String message, Object info)
+    {
+      lexer.emit_error(message);
+    }
+
+};
+
+/** JavaCup generated class to encapsulate user supplied action code.*/
+class CUP$actions {
+
+
+  /** helper routine to clone a new production part adding a given label */
+  protected production_part add_lab(production_part part, String lab)
+    throws internal_error
+    {
+      /* if there is no label, or this is an action, just return the original */
+      if (lab == null || part.is_action()) return part;
+
+      /* otherwise build a new one with the given label attached */
+      return new symbol_part(((symbol_part)part).the_symbol(),lab);
+    }
+
+  /** max size of right hand side we will support */
+  protected final int MAX_RHS = 200;
+
+  /** array for accumulating right hand side parts */
+  protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+  /** where we are currently in building a right hand side */
+  protected int rhs_pos = 0;
+
+  /** start a new right hand side */
+  protected void new_rhs() {rhs_pos = 0; }
+
+  /** add a new right hand side part */
+  protected void add_rhs_part(production_part part) throws java.lang.Exception
+    {
+      if (rhs_pos >= MAX_RHS)
+    throw new Exception("Internal Error: Productions limited to " +
+                 MAX_RHS + " symbols and actions");
+
+      rhs_parts[rhs_pos] = part;
+      rhs_pos++;
+    }
+
+  /** string to build up multiple part names */
+  protected String multipart_name = new String();
+
+  /** append a new name segment to the accumulated multipart name */
+  protected void append_multipart(String name)
+    {
+      String dot = "";
+
+      /* if we aren't just starting out, put on a dot */
+      if (multipart_name.length() != 0)  dot = ".";
+
+      multipart_name = multipart_name.concat(dot + name);
+    }
+
+  /** table of declared symbols -- contains production parts indexed by name */
+  protected Hashtable symbols = new Hashtable();
+
+  /** table of just non terminals -- contains non_terminals indexed by name */
+  protected Hashtable non_terms = new Hashtable();
+
+  /** declared start non_terminal */
+  protected non_terminal start_nt = null;
+
+  /** left hand side non terminal of the current production */
+  protected non_terminal lhs_nt;
+
+
+
+  /** Constructor */
+  CUP$actions() { }
+
+  /** Method with the actual generated action code. */
+  public final java_cup.runtime.symbol CUP$do_action(
+    int                        CUP$act_num,
+    java_cup.runtime.lr_parser CUP$parser,
+    java.util.Stack            CUP$stack,
+    int                        CUP$top)
+    throws java.lang.Exception
+    {
+      /* object for return from actions */
+      java_cup.runtime.symbol CUP$result;
+
+      /* select the action based on the action number */
+      switch (CUP$act_num)
+        {
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 64: // empty ::= 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*empty*/27);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 63: // label_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.str_token(/*label_id*/30);
+               ((java_cup.runtime.str_token)CUP$result).str_val = (/*the_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val; 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 62: // symbol_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.str_token(/*symbol_id*/29);
+               ((java_cup.runtime.str_token)CUP$result).str_val = (/*the_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val; 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 61: // nt_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.str_token(/*nt_id*/28);
+               ((java_cup.runtime.str_token)CUP$result).str_val = (/*the_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val; 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 60: // new_non_term_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*new_non_term_id*/24);
+              
+      /* see if this non terminal has been declared before */
+      if (symbols.get((/*non_term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val) != null)
+        {
+          /* issue a message */
+          lexer.emit_error( "Symbol \"" + (/*non_term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val +
+                                  "\" has already been declared");
+        }
+      else
+        {
+          /* build the non terminal object */
+              non_terminal this_nt =
+        new non_terminal((/*non_term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val, multipart_name);
+
+          /* put it in the non_terms table */
+          non_terms.put((/*non_term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val, this_nt);
+
+          /* build a production_part and put it in the symbols table */
+          symbols.put((/*non_term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val, new symbol_part(this_nt));
+        }
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 59: // new_term_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*new_term_id*/23);
+              
+      /* see if this terminal has been declared before */
+      if (symbols.get((/*term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val) != null)
+        {
+          /* issue a message */
+          lexer.emit_error("Symbol \"" + (/*term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val +
+               "\" has already been declared");
+        }
+      else
+        {
+          /* build a production_part and put it in the table */
+          symbols.put((/*term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val,
+            new symbol_part(new terminal((/*term_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val, multipart_name)));
+        }
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 58: // type_id ::= multipart_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*type_id*/17);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 57: // import_id ::= multipart_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*import_id*/12);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 56: // import_id ::= multipart_id DOT STAR 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*import_id*/12);
+               append_multipart("*"); 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 55: // multipart_id ::= ID 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*multipart_id*/10);
+               append_multipart((/*an_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val); 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 54: // multipart_id ::= multipart_id DOT ID 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*multipart_id*/10);
+               append_multipart((/*another_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val); 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 53: // opt_label ::= empty 
+            {
+              CUP$result = new java_cup.runtime.str_token(/*opt_label*/31);
+               ((java_cup.runtime.str_token)CUP$result).str_val = null; 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 52: // opt_label ::= COLON label_id 
+            {
+              CUP$result = new java_cup.runtime.str_token(/*opt_label*/31);
+               ((java_cup.runtime.str_token)CUP$result).str_val = (/*labid*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val; 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 51: // prod_part ::= CODE_STRING 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*prod_part*/22);
+              
+      /* add a new production part */
+      add_rhs_part(new action_part((/*code_str*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val));
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 50: // prod_part ::= symbol_id opt_label 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*prod_part*/22);
+              
+      /* try to look up the id */
+      production_part symb = (production_part)symbols.get((/*symid*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val);
+
+      /* if that fails, symbol is undeclared */
+      if (symb == null)
+        {
+          if (lexer.error_count == 0)
+            lexer.emit_error("Symbol \"" + (/*symid*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val +
+                   "\" has not been declared");
+        }
+      else
+        {
+          /* add a labeled production part */
+          add_rhs_part(add_lab(symb, (/*labid*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val));
+        }
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 49: // prod_part_list ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*prod_part_list*/21);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 48: // prod_part_list ::= prod_part_list prod_part 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*prod_part_list*/21);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 47: // rhs ::= prod_part_list 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*rhs*/26);
+              
+      if (lhs_nt != null)
+        {
+          /* build the production */
+          production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+          /* if we have no start non-terminal declared and this is
+         the first production, make its lhs nt the start_nt
+         and build a special start production for it. */
+              if (start_nt == null)
+        {
+          start_nt = lhs_nt;
+
+              /* build a special start production */
+              new_rhs();
+              add_rhs_part(new symbol_part(start_nt));
+              add_rhs_part(new symbol_part(terminal.EOF));
+              emit.start_production =
+             new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+              new_rhs();
+        }
+        }
+
+      /* reset the rhs accumulation in any case */
+      new_rhs();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 46: // rhs_list ::= rhs 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*rhs_list*/25);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 45: // rhs_list ::= rhs_list BAR rhs 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*rhs_list*/25);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 44: // production ::= error NT$9 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*production*/20);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 43: // NT$9 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$9*/41);
+               lexer.emit_error("Syntax Error"); 
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 42: // production ::= nt_id NT$8 COLON_COLON_EQUALS rhs_list SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*production*/20);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 41: // NT$8 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$8*/40);
+              
+      /* lookup the lhs nt */
+      lhs_nt = (non_terminal)non_terms.get((/*lhs_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val);
+
+          /* if it wasn't declared, emit a message */
+      if (lhs_nt == null)
+        {
+          if (lexer.error_count == 0)
+            lexer.emit_error("LHS non terminal \"" + (/*lhs_id*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val +
+                   "\" has not been declared");
+        }
+
+      /* reset the rhs accumulation */
+      new_rhs();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 40: // production_list ::= production 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*production_list*/9);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 39: // production_list ::= production_list production 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*production_list*/9);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 38: // start_spec ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*start_spec*/8);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 37: // start_spec ::= START WITH nt_id NT$7 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*start_spec*/8);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 36: // NT$7 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$7*/39);
+              
+      /* verify that the name has been declared as a non terminal */
+      non_terminal nt = (non_terminal)non_terms.get((/*start_name*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val);
+      if (nt == null)
+        {
+          lexer.emit_error( "Start non terminal \"" + (/*start_name*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-0)).str_val +
+                       "\" has not been declared");
+        }
+          else
+        {
+          /* remember the non-terminal for later */
+          start_nt = nt;
+
+          /* build a special start production */
+          new_rhs();
+          add_rhs_part(new symbol_part(start_nt));
+          add_rhs_part(new symbol_part(terminal.EOF));
+          emit.start_production =
+             new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+          new_rhs();
+        }
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 35: // non_term_name_list ::= new_non_term_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*non_term_name_list*/19);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 34: // non_term_name_list ::= non_term_name_list COMMA new_non_term_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*non_term_name_list*/19);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 33: // term_name_list ::= new_term_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*term_name_list*/18);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 32: // term_name_list ::= term_name_list COMMA new_term_id 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*term_name_list*/18);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 31: // symbol ::= NON TERMINAL error NT$6 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol*/15);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 30: // NT$6 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$6*/38);
+              
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 29: // symbol ::= TERMINAL error NT$5 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol*/15);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 28: // NT$5 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$5*/37);
+              
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 27: // symbol ::= NON TERMINAL type_id non_term_name_list NT$4 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol*/15);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 26: // NT$4 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$4*/36);
+              
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 25: // symbol ::= TERMINAL type_id term_name_list NT$3 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol*/15);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 24: // NT$3 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$3*/35);
+              
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 23: // symbol_list ::= symbol 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol_list*/7);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 22: // symbol_list ::= symbol_list symbol 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*symbol_list*/7);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 21: // debug_grammar ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*debug_grammar*/16);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 20: // debug_grammar ::= DEBUG WITH multipart_id SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*debug_grammar*/16);
+              
+      /* save the procedure name */
+          emit.debug_grammar = multipart_name;
+          /* reset the accumulated multipart name */
+          multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 19: // scan_code ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*scan_code*/14);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 18: // scan_code ::= SCAN WITH CODE_STRING SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*scan_code*/14);
+              
+      /* save the user code */
+      emit.scan_code = (/*user_code*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val;
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 17: // init_code ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*init_code*/13);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 16: // init_code ::= INIT WITH CODE_STRING SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*init_code*/13);
+              
+      /* save the user code */
+      emit.init_code = (/*user_code*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val;
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 15: // parser_code_part ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*parser_code_part*/6);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 14: // parser_code_part ::= PARSER CODE CODE_STRING SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*parser_code_part*/6);
+              
+      /* save the user included code string */
+      emit.parser_code = (/*user_code*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val;
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 13: // action_code_part ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*action_code_part*/5);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 12: // action_code_part ::= ACTION CODE CODE_STRING SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*action_code_part*/5);
+              
+      /* save the user included code string */
+      emit.action_code = (/*user_code*/(java_cup.runtime.str_token)CUP$stack.elementAt(CUP$top-1)).str_val;
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 11: // code_part ::= action_code_part parser_code_part 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*code_part*/4);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 10: // import_spec ::= IMPORT import_id NT$2 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*import_spec*/11);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 9: // NT$2 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$2*/34);
+              
+      /* save this import on the imports list */
+      emit.import_list.push(multipart_name);
+
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 8: // import_list ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*import_list*/3);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 7: // import_list ::= import_list import_spec 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*import_list*/3);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 6: // package_spec ::= empty 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*package_spec*/2);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 5: // package_spec ::= PACKAGE multipart_id NT$1 SEMI 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*package_spec*/2);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 4: // NT$1 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$1*/33);
+              
+      /* save the package name */
+      emit.package_name = multipart_name;
+
+      /* reset the accumulated multipart name */
+      multipart_name = new String();
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 3: // spec ::= error symbol_list start_spec production_list 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*spec*/1);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 2: // spec ::= NT$0 package_spec import_list code_part debug_grammar init_code scan_code symbol_list start_spec production_list 
+            {
+              CUP$result = new java_cup.runtime.symbol(/*spec*/1);
+              
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 1: // NT$0 ::= 
+            {
+              CUP$result = new java_cup.runtime.token(/*NT$0*/32);
+              
+          /* declare "error" as a terminal */
+          symbols.put("error", new symbol_part(terminal.error));
+
+          /* declare start non terminal */
+          non_terms.put("$START", non_terminal.START_nt);
+    
+            }
+          return CUP$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 0: // $START ::= spec EOF 
+            {
+              CUP$result = new java_cup.runtime.token(/*$START*/0);
+              
+            }
+          /* ACCEPT */
+          CUP$parser.done_parsing();
+          return CUP$result;
+
+          /* . . . . . .*/
+          default:
+            throw new Exception(
+               "Invalid action number found in internal parse table");
+
+        }
+    }
+};
+
diff --git a/tools/dasm/src/java_cup/production.java b/tools/dasm/src/java_cup/production.java
new file mode 100644
index 0000000..9c1d634
--- /dev/null
+++ b/tools/dasm/src/java_cup/production.java
@@ -0,0 +1,782 @@
+
+package java_cup;
+ 
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** This class represents a production in the grammar.  It contains
+ *  a LHS non terminal, and an array of RHS symbols.  As various 
+ *  transformations are done on the RHS of the production, it may shrink.
+ *  As a result a separate length is always maintained to indicate how much
+ *  of the RHS array is still valid.<p>
+ * 
+ *  I addition to construction and manipulation operations, productions provide
+ *  methods for factoring out actions (see  remove_embedded_actions()), for
+ *  computing the nullability of the production (i.e., can it derive the empty
+ *  string, see check_nullable()), and operations for computing its first
+ *  set (i.e., the set of terminals that could appear at the beginning of some
+ *  string derived from the production, see check_first_set()).
+ * 
+ * @see     java_cup.production_part
+ * @see     java_cup.symbol_part
+ * @see     java_cup.action_part
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class production {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor.  This constructor accepts a LHS non terminal,
+   *  an array of RHS parts (including terminals, non terminals, and 
+   *  actions), and a string for a final reduce action.   It does several
+   *  manipulations in the process of  creating a production object.
+   *  After some validity checking it translates labels that appear in
+   *  actions into code for accessing objects on the runtime parse stack.
+   *  It them merges adjacent actions if they appear and moves any trailing
+   *  action into the final reduce actions string.  Next it removes any
+   *  embedded actions by factoring them out with new action productions.  
+   *  Finally it assigns a unique index to the production.<p>
+   *
+   *  Factoring out of actions is accomplished by creating new "hidden"
+   *  non terminals.  For example if the production was originally: <pre>
+   *    A ::= B {action} C D
+   *  </pre>
+   *  then it is factored into two productions:<pre>
+   *    A ::= B X C D
+   *    X ::= {action}
+   *  </pre> 
+   *  (where X is a unique new non terminal).  This has the effect of placing
+   *  all actions at the end where they can be handled as part of a reduce by
+   *  the parser.
+   */
+  public production(
+    non_terminal    lhs_sym, 
+    production_part rhs_parts[], 
+    int             rhs_l,
+    String          action_str)
+    throws internal_error
+    {
+      int         i;
+      action_part tail_action;
+
+      /* remember the length */
+      if (rhs_l >= 0)
+    _rhs_length = rhs_l;
+      else if (rhs_parts != null)
+    _rhs_length = rhs_parts.length;
+      else
+    _rhs_length = 0;
+    
+      /* make sure we have a valid left-hand-side */
+      if (lhs_sym == null) 
+    throw new internal_error(
+      "Attempt to construct a production with a null LHS");
+
+      /* translate labels appearing in action strings */
+      action_str = translate_labels(
+             rhs_parts, rhs_l, action_str, lhs_sym.stack_type());
+
+      /* count use of lhs */
+      lhs_sym.note_use();
+
+      /* create the part for left-hand-side */
+      _lhs = new symbol_part(lhs_sym);
+
+      /* merge adjacent actions (if any) */
+      _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);
+
+      /* strip off any trailing action */
+      tail_action = strip_trailing_action(rhs_parts, _rhs_length);
+      if (tail_action != null) _rhs_length--;
+
+      /* allocate and copy over the right-hand-side */
+      _rhs = new production_part[_rhs_length];
+      for (i=0; i<_rhs_length; i++)
+    _rhs[i] = rhs_parts[i];
+
+      /* count use of each rhs symbol */
+      for (i=0; i<_rhs_length; i++)
+    if (!_rhs[i].is_action())
+      ((symbol_part)_rhs[i]).the_symbol().note_use();
+
+      /* merge any trailing action with action string parameter */
+      if (action_str == null) action_str = "";
+      if (tail_action != null && tail_action.code_string() != null)
+    action_str = tail_action.code_string() + action_str;
+
+      /* stash the action */
+      _action = new action_part(action_str);
+
+      /* rewrite production to remove any embedded actions */
+      remove_embedded_actions();
+
+      /* assign an index */
+      _index = next_index++;
+
+      /* put us in the global collection of productions */
+      _all.put(new Integer(_index),this);
+
+      /* put us in the production list of the lhs non terminal */
+      lhs_sym.add_production(this);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with no action string. */
+  public production(
+    non_terminal    lhs_sym, 
+    production_part rhs_parts[], 
+    int             rhs_l)
+    throws internal_error
+    {
+      this(lhs_sym,rhs_parts,rhs_l,null);
+    }
+ 
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+ 
+  /** Table of all productions.  Elements are stored using their index as 
+   *  the key.
+   */
+  protected static Hashtable _all = new Hashtable();
+ 
+  /** Access to all productions. */
+  public static Enumeration all() {return _all.elements();};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ 
+  /** Total number of productions. */
+  public static int number() {return _all.size();};
+
+  /** Static counter for assigning unique index numbers. */
+  protected static int next_index;
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The left hand side non-terminal. */
+  protected symbol_part _lhs;
+
+  /** The left hand side non-terminal. */
+  public symbol_part lhs() {return _lhs;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** A collection of parts for the right hand side. */
+  protected production_part _rhs[];
+
+  /** Access to the collection of parts for the right hand side. */
+  public production_part rhs(int indx) throws internal_error
+    {
+      if (indx >= 0 && indx < _rhs_length)
+    return _rhs[indx];
+      else
+    throw new internal_error(
+      "Index out of range for right hand side of production");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** How much of the right hand side array we are presently using. */
+  protected int _rhs_length;
+
+  /** How much of the right hand side array we are presently using. */
+  public int rhs_length() {return _rhs_length;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** An action_part containing code for the action to be performed when we 
+   *  reduce with this production. 
+   */
+  protected action_part _action;
+
+  /** An action_part containing code for the action to be performed when we 
+   *  reduce with this production. 
+   */
+  public action_part action() {return _action;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Index number of the production. */
+  protected int _index;
+
+  /** Index number of the production. */
+  public int index() {return _index;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Count of number of reductions using this production. */
+  protected int _num_reductions = 0;
+
+  /** Count of number of reductions using this production. */
+  public int num_reductions() {return _num_reductions;}
+
+  /** Increment the count of reductions with this non-terminal */
+  public void note_reduction_use() {_num_reductions++;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Is the nullability of the production known or unknown? */
+  protected boolean _nullable_known = false;
+
+  /** Is the nullability of the production known or unknown? */
+  public boolean nullable_known() {return _nullable_known;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Nullability of the production (can it derive the empty string). */
+  protected boolean _nullable = false;
+
+  /** Nullability of the production (can it derive the empty string). */
+  public boolean nullable() {return _nullable;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** First set of the production.  This is the set of terminals that 
+   *  could appear at the front of some string derived from this production.
+   */
+  protected terminal_set _first_set = new terminal_set();
+
+  /** First set of the production.  This is the set of terminals that 
+   *  could appear at the front of some string derived from this production.
+   */
+  public terminal_set first_set() {return _first_set;}
+
+  /*-----------------------------------------------------------*/
+  /*--- Static Methods ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Determine if a given character can be a label id starter. 
+   * @param c the character in question. 
+   */
+  protected static boolean is_id_start(char c)
+    {
+      return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
+
+      //later need to handle non-8-bit chars here
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if a character can be in a label id. 
+   * @param c the character in question.
+   */
+  protected static boolean is_id_char(char c)
+    {
+      return is_id_start(c) || (c >= '0' && c <= '9');
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Determine the translation for one label id found within a code_string. 
+   *  Symbols appearing in the RHS correspond to objects found on the parse
+   *  stack at runtime.  The code to access them, becomes code to access an
+   *  object at the appropriate offset from the top of the stack, and then
+   *  cast that to the proper type.
+   *
+   * @param id_str    the name of the id to be translated.
+   * @param act_pos   the original position of the action it appears in.
+   * @param label_map a hash table mapping labels to positions in the RHS.
+   * @param type_map  a hash table mapping labels to declared symbol types.
+   */
+  protected String label_translate(
+    String    id_str,     /* the id string we are (possibly) translating */
+    int       act_pos,    /* position of the action                      */
+    Hashtable label_map,  /* map from labels to positions in the RHS     */
+    Hashtable label_types)/* map from labels to stack types              */
+    {
+      Integer label_pos;
+      String  label_type;
+      int     offset;
+
+      /* look up the id */
+      label_pos  = (Integer)label_map.get(id_str);
+
+      /* if we don't find it, just return the id */
+      if (label_pos == null) return id_str;
+
+      /* extract the type of the labeled symbol */
+      label_type = (String)label_types.get(id_str);
+
+      /* is this for the LHS? */
+      if (label_pos.intValue() == -1)
+        {
+      /* return the result object cast properly */
+      return "((" + label_type + ")" + emit.pre("result") + ")";
+         }
+
+       /* its a RHS label */
+
+       /* if the label appears after the action, we have an error */
+       if (label_pos.intValue() > act_pos)
+         {
+       /* emit an error message */
+       System.err.println("*** Label \"" + id_str + 
+         "\" appears in action before it appears in production");
+        lexer.error_count++;
+
+        // later need to print the production this is in
+    
+        /* just return the id unchanged */
+          return id_str;
+      }
+
+      /* calculate the stack offset as the difference in position from 
+     label to action minus one */
+      offset = (act_pos - label_pos.intValue())-1;
+
+      /* translation is properly cast element at that offset from TOS */
+      return "(/*"+id_str+"*/("+label_type+")" + 
+       emit.pre("stack") + ".elementAt(" + emit.pre("top") +"-"+ offset + "))";
+   
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Translate all the label names within an action string to appropriate code.
+   * @param act_string  the string to be translated
+   * @param act_pos     the position that the action originally held in the 
+   *                    production.
+   * @param label_map   a hash table mapping labels to positions in the RHS.
+   * @param type_map    a hash table mapping labels to declared symbol types.
+   */
+  protected String action_translate(
+    String    act_string,  /* the action string                     */
+    int       act_pos,     /* the position of the action on the RHS */
+    Hashtable label_map,   /* map from labels to RHS positions      */
+    Hashtable label_types) /* map from labels to symbol stack types */
+    {
+      int          id_start;
+      int          pos;
+      int          len;
+      String       id_str;
+      boolean      in_id;
+      StringBuffer result;
+      char         buffer[];
+
+      /* if we have no string we are done */
+      if (act_string == null || act_string.length()== 0) return act_string;
+
+      len = act_string.length();
+
+      /* set up a place to put the result */
+      result = new StringBuffer(len + 50);
+
+      /* extract string into array */
+      buffer = new char[len + 1];
+      act_string.getChars(0, len, buffer, 0);
+
+      /* put terminator in buffer so we can look one past the end */
+      buffer[len] = '\0';
+
+      /* walk down the input buffer looking for identifiers */
+      in_id = false;
+      for (pos = id_start = 0; pos <= len; pos++)
+    {
+      /* are we currently working on an id? */
+      if (in_id)
+        {
+          /* does this end the id? */
+          if (!is_id_char(buffer[pos]))
+        {
+          /* extract the id string and translate it */
+          id_str = new String(buffer, id_start, pos - id_start);
+          result.append(
+              label_translate(id_str, act_pos, label_map,label_types));
+
+          /* copy over the ending character */
+          if (buffer[pos] != '\0')
+                result.append(buffer, pos, 1);
+
+          /* and we are done with this id */
+          in_id = false;
+        }
+          else
+        {
+          /* we are still in the id, so just keep going */
+        }
+        }
+      else /* we are not inside an id */
+        {
+          /* start a new id? */
+          if (is_id_start(buffer[pos]))
+            {
+          /* start keeping these chars as an id */
+              in_id = true;
+              id_start = pos;
+            }
+         else
+           {
+             /* just copy over the char */
+         if (buffer[pos] != '\0')
+               result.append(buffer, pos, 1);
+           }
+        }
+    }
+
+      /* return the accumulated result */
+      return result.toString();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Translate label names to appropriate code within all action strings. 
+   * @param rhs          array of RHS parts.
+   * @param rhs_len      how much of rhs to consider valid.
+   * @param final_action the final action string of the production. 
+   * @param lhs_type     the object type associated with the LHS symbol.
+   */ 
+  protected String translate_labels(
+    production_part  rhs[], 
+    int              rhs_len, 
+    String           final_action,
+    String           lhs_type)
+    {
+      Hashtable   label_map   = new Hashtable(11);
+      Hashtable   label_types = new Hashtable(11);
+      symbol_part part;
+      action_part act_part;
+      int         pos;
+
+      /* walk down the parts and extract the labels */
+      for (pos = 0; pos < rhs_len; pos++)
+    {
+      if (!rhs[pos].is_action())
+        {
+          part = (symbol_part)rhs[pos];
+
+          /* if it has a label enter it in the tables */
+          if (part.label() != null)
+        {
+          label_map.put(part.label(), new Integer(pos));
+          label_types.put(part.label(), part.the_symbol().stack_type());
+        }
+        }
+    }
+
+      /* add a label for the LHS */
+      label_map.put("RESULT", new Integer(-1));
+      label_types.put("RESULT", lhs_type);
+
+      /* now walk across and do each action string */
+      for (pos = 0; pos < rhs_len; pos++)
+    {
+      if (rhs[pos].is_action())
+        {
+           act_part = (action_part)rhs[pos];
+           act_part.set_code_string(
+         action_translate(
+           act_part.code_string(), pos, label_map, label_types));
+        }
+    }
+
+      /* now do the final action string at the position after the last */
+      return action_translate(final_action, rhs_len, label_map, label_types);
+
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Helper routine to merge adjacent actions in a set of RHS parts 
+   * @param rhs_parts array of RHS parts.
+   * @param len       amount of that array that is valid.
+   * @return          remaining valid length.
+   */
+  protected int merge_adjacent_actions(production_part rhs_parts[], int len)
+    {
+      int from_loc, to_loc, merge_cnt;
+
+      /* bail out early if we have no work to do */
+      if (rhs_parts == null || len == 0) return 0;
+
+      merge_cnt = 0;
+      to_loc = -1;
+      for (from_loc=0; from_loc<len; from_loc++)
+    {
+      /* do we go in the current position or one further */
+      if (to_loc < 0 || !rhs_parts[to_loc].is_action() 
+             || !rhs_parts[from_loc].is_action())
+        {
+          /* next one */
+          to_loc++;
+
+          /* clear the way for it */
+          if (to_loc != from_loc) rhs_parts[to_loc] = null;
+        }
+
+      /* if this is not trivial? */
+      if (to_loc != from_loc)
+        {
+          /* do we merge or copy? */
+          if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() && 
+          rhs_parts[from_loc].is_action())
+          {
+            /* merge */
+            rhs_parts[to_loc] = new action_part(
+          ((action_part)rhs_parts[to_loc]).code_string() +
+          ((action_part)rhs_parts[from_loc]).code_string());
+            merge_cnt++;
+          }
+        else
+          {
+            /* copy */
+            rhs_parts[to_loc] = rhs_parts[from_loc];
+          }
+        }
+    }
+
+      /* return the used length */
+      return len - merge_cnt;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Helper routine to strip a trailing action off rhs and return it
+   * @param rhs_parts array of RHS parts.
+   * @param len       how many of those are valid.
+   * @return          the removed action part.
+   */
+  protected action_part strip_trailing_action(
+    production_part rhs_parts[],
+    int             len)
+    {
+      action_part result;
+
+      /* bail out early if we have nothing to do */
+      if (rhs_parts == null || len == 0) return null;
+
+      /* see if we have a trailing action */
+      if (rhs_parts[len-1].is_action())
+    {
+      /* snip it out and return it */
+      result = (action_part)rhs_parts[len-1];
+      rhs_parts[len-1] = null;
+      return result;
+    }
+      else
+    return null;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove all embedded actions from a production by factoring them 
+   *  out into individual action production using new non terminals.
+   *  if the original production was:  <pre>
+   *    A ::= B {action1} C {action2} D 
+   *  </pre>
+   *  then it will be factored into: <pre>
+   *    A ::= B NT$1 C NT$2 D
+   *    NT$1 ::= {action1}
+   *    NT$2 ::= {action2}
+   *  </pre>
+   *  where NT$1 and NT$2 are new system created non terminals.
+   */
+  protected void remove_embedded_actions() throws internal_error
+    {
+      non_terminal new_nt;
+      production   new_prod;
+
+      /* walk over the production and process each action */
+      for (int act_loc = 0; act_loc < rhs_length(); act_loc++)
+    if (rhs(act_loc).is_action())
+      {
+        /* create a new non terminal for the action production */
+        new_nt = non_terminal.create_new();
+
+        /* create a new production with just the action */
+        new_prod = new action_production(this, new_nt, null, 0, 
+            ((action_part)rhs(act_loc)).code_string());
+
+        /* replace the action with the generated non terminal */
+        _rhs[act_loc] = new symbol_part(new_nt);
+      }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Check to see if the production (now) appears to be nullable.
+   *  A production is nullable if its RHS could derive the empty string.
+   *  This results when the RHS is empty or contains only non terminals
+   *  which themselves are nullable.
+   */
+  public boolean check_nullable() throws internal_error
+    {
+      production_part part;
+      symbol          sym;
+      int             pos;
+
+      /* if we already know bail out early */
+      if (nullable_known()) return nullable();
+
+      /* if we have a zero size RHS we are directly nullable */
+      if (rhs_length() == 0)
+    {
+      /* stash and return the result */
+      return set_nullable(true);
+    }
+
+      /* otherwise we need to test all of our parts */
+      for (pos=0; pos<rhs_length(); pos++)
+    {
+      part = rhs(pos);
+
+      /* only look at non-actions */
+      if (!part.is_action())
+        {
+          sym = ((symbol_part)part).the_symbol();
+
+          /* if its a terminal we are definitely not nullable */
+          if (!sym.is_non_term()) 
+        return set_nullable(false);
+          /* its a non-term, is it marked nullable */
+          else if (!((non_terminal)sym).nullable())
+        /* this one not (yet) nullable, so we aren't */
+            return false;
+        }
+    }
+
+      /* if we make it here all parts are nullable */
+      return set_nullable(true);
+    }
+
+  /** set (and return) nullability */
+  boolean set_nullable(boolean v)
+    {
+      _nullable_known = true;
+      _nullable = v;
+      return v;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Update (and return) the first set based on current NT firsts. 
+   *  This assumes that nullability has already been computed for all non 
+   *  terminals and productions. 
+   */
+  public terminal_set check_first_set() throws internal_error
+    {
+      int    part;
+      symbol sym;
+
+      /* walk down the right hand side till we get past all nullables */
+      for (part=0; part<rhs_length(); part++)
+    {
+      /* only look at non-actions */
+      if (!rhs(part).is_action())
+        {
+          sym = ((symbol_part)rhs(part)).the_symbol();
+
+          /* is it a non-terminal?*/
+          if (sym.is_non_term())
+        {
+          /* add in current firsts from that NT */
+          _first_set.add(((non_terminal)sym).first_set());
+
+          /* if its not nullable, we are done */
+          if (!((non_terminal)sym).nullable())
+            break;
+        }
+          else
+        {
+              /* its a terminal -- add that to the set */
+          _first_set.add((terminal)sym);
+
+          /* we are done */
+          break;
+        }
+        }
+    }
+
+      /* return our updated first set */
+      return first_set();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(production other)
+    {
+      if (other == null) return false;
+      return other._index == _index;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof production))
+    return false;
+      else
+    return equals((production)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a hash code. */
+  public int hashCode()
+    {
+      /* just use a simple function of the index */
+      return _index*13;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString() 
+    {
+      String result;
+      
+      /* catch any internal errors */
+      try {
+        result = "production [" + index() + "]: "; 
+        result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$");
+        result += " :: = ";
+        for (int i = 0; i<rhs_length(); i++)
+      result += rhs(i) + " ";
+        result += ";";
+        if (action()  != null && action().code_string() != null) 
+      result += " {" + action().code_string() + "}";
+
+        if (nullable_known())
+      if (nullable())
+        result += "[NULLABLE]";
+      else
+        result += "[NOT NULLABLE]";
+      } catch (internal_error e) {
+    /* crash on internal error since we can't throw it from here (because
+       superclass does not throw anything. */
+    e.crash();
+    result = null;
+      }
+
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a simpler string. */
+  public String to_simple_string() throws internal_error
+    {
+      String result;
+
+      result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS");
+      result += " ::= ";
+      for (int i = 0; i < rhs_length(); i++)
+    if (!rhs(i).is_action())
+      result += ((symbol_part)rhs(i)).the_symbol().name() + " ";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/production_part.java b/tools/dasm/src/java_cup/production_part.java
new file mode 100644
index 0000000..cdb92f7
--- /dev/null
+++ b/tools/dasm/src/java_cup/production_part.java
@@ -0,0 +1,94 @@
+package java_cup;
+
+/** This class represents one part (either a symbol or an action) of a 
+ *  production.  In this base class it contains only an optional label 
+ *  string that the user can use to refer to the part within actions.<p>
+ *
+ *  This is an abstract class.
+ *
+ * @see     java_cup.production
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public abstract class production_part {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** Simple constructor. */
+  public production_part(String lab)
+    {
+      _label = lab;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** Optional label for referring to the part within an action (null for 
+   *  no label). 
+   */
+  protected String _label;
+
+  /** Optional label for referring to the part within an action (null for 
+   *  no label). 
+   */
+  public String label() {return _label;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** Indicate if this is an action (rather than a symbol).  Here in the 
+   * base class, we don't this know yet, so its an abstract method.
+   */
+  public abstract boolean is_action();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(production_part other)
+    {
+      if (other == null) return false;
+
+      /* compare the labels */
+      if (label() != null)
+    return label().equals(other.label());
+      else
+    return other.label() == null;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof production_part))
+        return false;
+      else
+    return equals((production_part)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a hash code. */
+  public int hashCode()
+    {
+      return label()==null ? 0 : label().hashCode();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      if (label() != null)
+    return label() + ":";
+      else
+    return " ";
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/reduce_action.java b/tools/dasm/src/java_cup/reduce_action.java
new file mode 100644
index 0000000..646fe0c
--- /dev/null
+++ b/tools/dasm/src/java_cup/reduce_action.java
@@ -0,0 +1,84 @@
+
+package java_cup;
+
+/** This class represents a reduce action within the parse table. 
+ *  The action simply stores the production that it reduces with and 
+ *  responds to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class reduce_action extends parse_action {
+ 
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. 
+   * @param prod the production this action reduces with.
+   */
+  public reduce_action(production prod ) throws internal_error
+    {
+      /* sanity check */
+      if (prod == null)
+    throw new internal_error(
+      "Attempt to create a reduce_action with a null production");
+
+      _reduce_with = prod;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+  
+  /** The production we reduce with. */
+  protected production _reduce_with;
+
+  /** The production we reduce with. */
+  public production reduce_with() {return _reduce_with;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Quick access to type of action. */
+  public int kind() {return REDUCE;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality test. */
+  public boolean equals(reduce_action other)
+    {
+      return other != null && other.reduce_with() == reduce_with();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality test. */
+  public boolean equals(Object other)
+    {
+      if (other instanceof reduce_action)
+    return equals((reduce_action)other);
+      else
+       return false;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute a hash code. */
+  public int hashCode()
+    {
+      /* use the hash code of the production we are reducing with */
+      return reduce_with().hashCode();
+    }
+
+
+  /** Convert to string. */
+  public String toString() 
+    {
+      return "REDUCE(" + reduce_with().index() + ")";
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/runtime/char_token.java b/tools/dasm/src/java_cup/runtime/char_token.java
new file mode 100644
index 0000000..0b4502b
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/char_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  char value as an attribute.  It maintains that value in the public
+ *  field int_val.
+ *
+ * @see java_cup.runtime.str_token
+ * @version last updated: 1/7/96
+ * @author  Scott Hudson
+ */
+
+public class char_token extends token {
+
+  /** Full constructor. */
+  public char_token(int term_num, char v)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      char_val = v;
+    }
+
+  /** Constructor with default value of 0 */
+  public char_token(int term_num)
+    {
+      this(term_num, '\0');
+    }
+
+  /** The stored char value. */
+  public char char_val;
+};
diff --git a/tools/dasm/src/java_cup/runtime/double_token.java b/tools/dasm/src/java_cup/runtime/double_token.java
new file mode 100644
index 0000000..df95822
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/double_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  double value as an attribute.  It maintains that value in the public
+ *  field int_val.
+ *
+ * @see java_cup.runtime.str_token
+ * @version last updated: 1/7/96
+ * @author  Scott Hudson
+ */
+
+public class double_token extends token {
+
+  /** Full constructor. */
+  public double_token(int term_num, double v)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      double_val = v;
+    }
+
+  /** Constructor with default value of 0.0. */
+  public double_token(int term_num)
+    {
+      this(term_num,0.0f);
+    }
+
+  /** The stored double value. */
+  public double double_val;
+};
diff --git a/tools/dasm/src/java_cup/runtime/float_token.java b/tools/dasm/src/java_cup/runtime/float_token.java
new file mode 100644
index 0000000..d1b56da
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/float_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  float value as an attribute.  It maintains that value in the public
+ *  field int_val.
+ *
+ * @see java_cup.runtime.str_token
+ * @version last updated: 1/7/96
+ * @author  Scott Hudson
+ */
+
+public class float_token extends token {
+
+  /** Full constructor. */
+  public float_token(int term_num, float v)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      float_val = v;
+    }
+
+  /** Constructor with default value of 0.0. */
+  public float_token(int term_num)
+    {
+      this(term_num,0.0f);
+    }
+
+  /** The stored float value. */
+  public float float_val;
+};
diff --git a/tools/dasm/src/java_cup/runtime/int_token.java b/tools/dasm/src/java_cup/runtime/int_token.java
new file mode 100644
index 0000000..b78df69
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/int_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  int value as an attribute.  It maintains that value in the public
+ *  field int_val.
+ *
+ * @see java_cup.runtime.str_token
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class int_token extends token {
+
+  /** Full constructor. */
+  public int_token(int term_num, int iv)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      int_val = iv;
+    }
+
+  /** Constructor with default value of 0. */
+  public int_token(int term_num)
+    {
+      this(term_num,0);
+    }
+
+  /** The stored int value. */
+  public int int_val;
+};
diff --git a/tools/dasm/src/java_cup/runtime/long_token.java b/tools/dasm/src/java_cup/runtime/long_token.java
new file mode 100644
index 0000000..170a69b
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/long_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  long value as an attribute.  It maintains that value in the public
+ *  field int_val.
+ *
+ * @see java_cup.runtime.str_token
+ * @version last updated: 1/7/96
+ * @author  Scott Hudson
+ */
+
+public class long_token extends token {
+
+  /** Full constructor. */
+  public long_token(int term_num, long lv)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      long_val = lv;
+    }
+
+  /** Constructor with default value of 0. */
+  public long_token(int term_num)
+    {
+      this(term_num,0);
+    }
+
+  /** The stored long value. */
+  public long long_val;
+};
diff --git a/tools/dasm/src/java_cup/runtime/lr_parser.java b/tools/dasm/src/java_cup/runtime/lr_parser.java
new file mode 100644
index 0000000..b814390
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/lr_parser.java
@@ -0,0 +1,1121 @@
+
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a skeleton table driven LR parser.  In general,
+ *  LR parsers are a form of bottom up shift-reduce parsers.  Shift-reduce
+ *  parsers act by shifting input onto a parse stack until the symbols 
+ *  matching the right hand side of a production appear on the top of the 
+ *  stack.  Once this occurs, a reduce is performed.  This involves removing
+ *  the symbols corresponding to the right hand side of the production
+ *  (the so called "handle") and replacing them with the non-terminal from
+ *  the left hand side of the production.  <p>
+ *
+ *  To control the decision of whether to shift or reduce at any given point, 
+ *  the parser uses a state machine (the "viable prefix recognition machine" 
+ *  built by the parser generator).  The current state of the machine is placed
+ *  on top of the parse stack (stored as part of a symbol object representing
+ *  a terminal or non terminal).  The parse action table is consulted 
+ *  (using the current state and the current lookahead token as indexes) to 
+ *  determine whether to shift or to reduce.  When the parser shifts, it 
+ *  changes to a new state by pushing a new symbol (containing a new state) 
+ *  onto the stack.  When the parser reduces, it pops the handle (right hand 
+ *  side of a production) off the stack.  This leaves the parser in the state 
+ *  it was in before any of those symbols were matched.  Next the reduce-goto 
+ *  table is consulted (using the new state and current lookahead token as 
+ *  indexes) to determine a new state to go to.  The parser then shifts to 
+ *  this goto state by pushing the left hand side symbol of the production 
+ *  (also containing the new state) onto the stack.<p>
+ *
+ *  This class actually provides four LR parsers.  The methods parse() and 
+ *  debug_parse() provide two versions of the main parser (the only difference 
+ *  being that debug_parse() emits debugging trace messages as it parses).  
+ *  In addition to these main parsers, the error recovery mechanism uses two 
+ *  more.  One of these is used to simulate "parsing ahead" in the input 
+ *  without carrying out actions (to verify that a potential error recovery 
+ *  has worked), and the other is used to parse through buffered "parse ahead" 
+ *  input in order to execute all actions and re-synchronize the actual parser 
+ *  configuration.<p>
+ *
+ *  This is an abstract class which is normally filled out by a subclass
+ *  generated by the JavaCup parser generator.  In addition to supplying
+ *  the actual parse tables, generated code also supplies methods which 
+ *  invoke various pieces of user supplied code, provide access to certain
+ *  special symbols (e.g., EOF and error), etc.  Specifically, the following
+ *  abstract methods are normally supplied by generated code:
+ *  <dl compact>
+ *  <dt> short[][] production_table()
+ *  <dd> Provides a reference to the production table (indicating the index of
+ *       the left hand side non terminal and the length of the right hand side
+ *       for each production in the grammar).
+ *  <dt> short[][] action_table()
+ *  <dd> Provides a reference to the parse action table.
+ *  <dt> short[][] reduce_table()
+ *  <dd> Provides a reference to the reduce-goto table.
+ *  <dt> int start_state()      
+ *  <dd> Indicates the index of the start state.
+ *  <dt> int start_production() 
+ *  <dd> Indicates the index of the starting production.
+ *  <dt> int EOF_sym() 
+ *  <dd> Indicates the index of the EOF symbol.
+ *  <dt> int error_sym() 
+ *  <dd> Indicates the index of the error symbol.
+ *  <dt> symbol do_action() 
+ *  <dd> Executes a piece of user supplied action code.  This always comes at 
+ *       the point of a reduce in the parse, so this code also allocates and 
+ *       fills in the left hand side non terminal symbol object that is to be 
+ *       pushed onto the stack for the reduce.
+ *  <dt> void init_actions()
+ *  <dd> Code to initialize a special object that encapsulates user supplied
+ *       actions (this object is used by do_action() to actually carry out the 
+ *       actions).
+ *  <dt> token scan()
+ *  <dd> Used to get the next input token from the scanner.
+ *  </dl>
+ *  
+ *  In addition to these routines that <i>must</i> be supplied by the 
+ *  generated subclass there are also a series of routines that <i>may</i> 
+ *  be supplied.  These include:
+ *  <dl>
+ *  <dt> int error_sync_size()
+ *  <dd> This determines how many tokens past the point of an error 
+ *       must be parsed without error in order to consider a recovery to 
+ *       be valid.  This defaults to 3.  Values less than 2 are not 
+ *       recommended.
+ *  <dt> void report_error(String message, Object info)
+ *  <dd> This method is called to report an error.  The default implementation
+ *       simply prints a message to System.err and ignores its second parameter.
+ *       This method is often replaced in order to provide a more sophisticated
+ *       error reporting mechanism.
+ *  <dt> void report_fatal_error(String message, Object info)
+ *  <dd> This method is called when a fatal error that cannot be recovered from
+ *       is encountered.  In the default implementation, it calls 
+ *       report_error() to emit a message, then throws an exception.
+ *  <dt> void syntax_error(token cur_token)
+ *  <dd> This method is called as soon as syntax error is detected (but
+ *       before recovery is attempted).  In the default implementation it 
+ *       invokes: report_error("Syntax error", null);
+ *  <dt> void unrecovered_syntax_error(token cur_token)
+ *  <dd> This method is called if syntax error recovery fails.  In the default
+ *       implementation it invokes:<br> 
+ *         report_fatal_error("Couldn't repair and continue parse", null);
+ *  </dl>
+ *
+ * @see     java_cup.runtime.symbol
+ * @see     java_cup.runtime.token
+ * @see     java_cup.runtime.virtual_parse_stack
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public abstract class lr_parser {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. */
+  public lr_parser()
+    {
+      /* nothing to do here */
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The default number of tokens after an error we much match to consider 
+   *  it recovered from. 
+   */
+  protected final static int _error_sync_size = 3;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The number of tokens after an error we much match to consider it 
+   *  recovered from. 
+   */
+  protected int error_sync_size() {return _error_sync_size; }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Table of production information (supplied by generated subclass).
+   *  This table contains one entry per production and is indexed by 
+   *  the negative-encoded values (reduce actions) in the action_table.  
+   *  Each entry has two parts, the index of the non-terminal on the 
+   *  left hand side of the production, and the number of symbols 
+   *  on the right hand side. 
+   */
+  public abstract short[][] production_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The action table (supplied by generated subclass).  This table is
+   *  indexed by state and terminal number indicating what action is to
+   *  be taken when the parser is in the given state (i.e., the given state 
+   *  is on top of the stack) and the given terminal is next on the input.  
+   *  States are indexed using the first dimension, however, the entries for 
+   *  a given state are compacted and stored in adjacent index, value pairs 
+   *  which are searched for rather than accessed directly (see get_action()).  
+   *  The actions stored in the table will be either shifts, reduces, or 
+   *  errors.  Shifts are encoded as positive values (one greater than the 
+   *  state shifted to).  Reduces are encoded as negative values (one less 
+   *  than the production reduced by).  Error entries are denoted by zero. 
+   * 
+   * @see java_cup.runtime.lr_parser#get_action
+   */
+  public abstract short[][] action_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The reduce-goto table (supplied by generated subclass).  This
+   *  table is indexed by state and non-terminal number and contains
+   *  state numbers.  States are indexed using the first dimension, however,
+   *  the entries for a given state are compacted and stored in adjacent
+   *  index, value pairs which are searched for rather than accessed 
+   *  directly (see get_reduce()).  When a reduce occurs, the handle 
+   *  (corresponding to the RHS of the matched production) is popped off 
+   *  the stack.  The new top of stack indicates a state.  This table is 
+   *  then indexed by that state and the LHS of the reducing production to 
+   *  indicate where to "shift" to. 
+   *
+   * @see java_cup.runtime.lr_parser#get_reduce
+   */
+  public abstract short[][] reduce_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the start state (supplied by generated subclass). */
+  public abstract int start_state();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the start production (supplied by generated subclass). */
+  public abstract int start_production();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the end of file terminal symbol (supplied by generated 
+   *  subclass). 
+   */
+  public abstract int EOF_sym();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the special error symbol (supplied by generated subclass). */
+  public abstract int error_sym();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Internal flag to indicate when parser should quit. */
+  protected boolean _done_parsing = false;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called to indicate that the parser should quit.  This is 
+   *  normally called by an accept action, but can be used to cancel parsing 
+   *  early in other circumstances if desired. 
+   */
+  public void done_parsing()
+    {
+      _done_parsing = true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+  /* Global parse state shared by parse(), error recovery, and 
+   * debugging routines */
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indication of the index for top of stack (for use by actions). */
+  protected int tos;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The current lookahead token. */
+  protected token cur_token;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The parse stack itself. */
+  protected Stack stack = new Stack();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the production table. */ 
+  protected short[][] production_tab;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the action table. */
+  protected short[][] action_tab;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the reduce-goto table. */
+  protected short[][] reduce_tab;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Perform a bit of user supplied action code (supplied by generated 
+   *  subclass).  Actions are indexed by an internal action number assigned
+   *  at parser generation time.
+   *
+   * @param act_num   the internal index of the action to be performed.
+   * @param parser    the parser object we are acting for.
+   * @param stack     the parse stack of that object.
+   * @param top       the index of the top element of the parse stack.
+   */
+  public abstract symbol do_action(
+    int       act_num, 
+    lr_parser parser, 
+    Stack     stack, 
+    int       top) 
+    throws java.lang.Exception;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User code for initialization inside the parser.  Typically this 
+   *  initializes the scanner.  This is called before the parser requests
+   *  the first token.  Here this is just a placeholder for subclasses that 
+   *  might need this and we perform no action.   This method is normally
+   *  overridden by the generated code using this contents of the "init with"
+   *  clause as its body.
+   */
+  public void user_init() throws java.lang.Exception { }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Initialize the action object.  This is called before the parser does
+   *  any parse actions. This is filled in by generated code to create
+   *  an object that encapsulates all action code. 
+   */ 
+  protected abstract void init_actions() throws java.lang.Exception;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Get the next token from the input (supplied by generated subclass).
+   *  Once end of file has been reached, all subsequent calls to scan 
+   *  should return an EOF token (which is symbol number 0).  This method
+   *  is supplied by the generator using using the code declared in the 
+   *  "scan with" clause.
+   */
+  public abstract token scan() throws java.lang.Exception;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Report a fatal error.  This method takes a  message string and an 
+   *  additional object (to be used by specializations implemented in 
+   *  subclasses).  Here in the base class a very simple implementation 
+   *  is provided which reports the error then throws an exception. 
+   *
+   * @param message an error message.
+   * @param info    an extra object reserved for use by specialized subclasses.
+   */
+  public void report_fatal_error(
+    String   message, 
+    Object   info)
+    throws java.lang.Exception
+    {
+      /* stop parsing (not really necessary since we throw an exception, but) */
+      done_parsing();
+
+      /* use the normal error message reporting to put out the message */
+      report_error(message, info);
+
+      /* throw an exception */
+      throw new Exception("Can't recover from previous error(s)");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Report a non fatal error (or warning).  This method takes a message 
+   *  string and an additional object (to be used by specializations 
+   *  implemented in subclasses).  Here in the base class a very simple 
+   *  implementation is provided which simply prints the message to 
+   *  System.err. 
+   *
+   * @param message an error message.
+   * @param info    an extra object reserved for use by specialized subclasses.
+   */
+  public void report_error(String message, Object info)
+    {
+      System.err.println(message);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called when a syntax error has been detected and recovery 
+   *  is about to be invoked.  Here in the base class we just emit a 
+   *  "Syntax error" error message.  
+   *
+   * @param cur_token the current lookahead token.
+   */
+  public void syntax_error(token cur_token)
+    {
+      report_error("Syntax error", null);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called if it is determined that syntax error recovery 
+   *  has been unsuccessful.  Here in the base class we report a fatal error. 
+   *
+   * @param cur_token the current lookahead token.
+   */
+  public void unrecovered_syntax_error(token cur_token)
+    throws java.lang.Exception
+    {
+      report_fatal_error("Couldn't repair and continue parse", null);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Fetch an action from the action table.  The table is broken up into
+   *  rows, one per state (rows are indexed directly by state number).  
+   *  Within each row, a list of index, value pairs are given (as sequential
+   *  entries in the table), and the list is terminated by a default entry 
+   *  (denoted with a symbol index of -1).  To find the proper entry in a row 
+   *  we do a linear or binary search (depending on the size of the row).  
+   *
+   * @param state the state index of the action being accessed.
+   * @param sym   the symbol index of the action being accessed.
+   */
+  protected final short get_action(int state, int sym)
+    {
+      short tag;
+      int first, last, probe;
+      short[] row = action_tab[state];
+
+      /* linear search if we are < 10 entries */
+      if (row.length < 20)
+        for (probe = 0; probe < row.length; probe++)
+      {
+        /* is this entry labeled with our symbol or the default? */
+        tag = row[probe++];
+        if (tag == sym || tag == -1)
+          {
+            /* return the next entry */
+            return row[probe];
+          }
+      }
+      /* otherwise binary search */
+      else
+    {
+      first = 0; 
+      last = (row.length-1)/2 - 1;  /* leave out trailing default entry */
+      while (first <= last)
+        {
+          probe = (first+last)/2;
+          if (sym == row[probe*2])
+        return row[probe*2+1];
+          else if (sym > row[probe*2])
+        first = probe+1;
+          else
+            last = probe-1;
+        }
+
+      /* not found, use the default at the end */
+      return row[row.length-1];
+    }
+
+      /* shouldn't happened, but if we run off the end we return the 
+     default (error == 0) */
+      return 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Fetch a state from the reduce-goto table.  The table is broken up into
+   *  rows, one per state (rows are indexed directly by state number).  
+   *  Within each row, a list of index, value pairs are given (as sequential
+   *  entries in the table), and the list is terminated by a default entry 
+   *  (denoted with a symbol index of -1).  To find the proper entry in a row 
+   *  we do a linear search.  
+   *
+   * @param state the state index of the entry being accessed.
+   * @param sym   the symbol index of the entry being accessed.
+   */
+  protected final short get_reduce(int state, int sym)
+    {
+      short tag;
+      short[] row = reduce_tab[state];
+
+      /* if we have a null row we go with the default */
+      if (row == null)
+        return -1;
+
+      for (int probe = 0; probe < row.length; probe++)
+    {
+      /* is this entry labeled with our symbol or the default? */
+      tag = row[probe++];
+      if (tag == sym || tag == -1)
+        {
+          /* return the next entry */
+          return row[probe];
+        }
+    }
+      /* if we run off the end we return the default (error == -1) */
+      return -1;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method provides the main parsing routine.  It returns only when 
+   *  done_parsing() has been called (typically because the parser has 
+   *  accepted, or a fatal error has been reported).  See the header 
+   *  documentation for the class regarding how shift/reduce parsers operate
+   *  and how the various tables are used.
+   */
+  public void parse() throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the symbol/stack element returned by a reduce */
+      symbol lhs_sym;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* set up direct reference to tables to drive the parser */
+
+      production_tab = production_table();
+      action_tab     = action_table();
+      reduce_tab     = reduce_table();
+
+      /* initialize the action encapsulation object */
+      init_actions();
+
+      /* do user initialization */
+      user_init();
+
+      /* get the first token */
+      cur_token = scan(); 
+
+      /* push dummy symbol with start state to get us underway */
+      stack.push(new symbol(0, start_state()));
+      tos = 0;
+
+      /* continue until we are told to stop */
+      for (_done_parsing = false; !_done_parsing; )
+    {
+      /* current state is always on the top of the stack */
+
+      /* look up action out of the current state with the current input */
+      act = get_action(((symbol)stack.peek()).parse_state, cur_token.sym);
+
+      /* decode the action -- > 0 encodes shift */
+      if (act > 0)
+        {
+          /* shift to the encoded state by pushing it on the stack */
+          cur_token.parse_state = act-1;
+          stack.push(cur_token);
+          tos++;
+
+          /* advance to the next token */
+          cur_token = scan();
+        }
+      /* if its less than zero, then it encodes a reduce action */
+      else if (act < 0)
+        {
+          /* perform the action for the reduce */
+          lhs_sym = do_action((-act)-1, this, stack, tos);
+
+          /* look up information about the production */
+          lhs_sym_num = production_tab[(-act)-1][0];
+          handle_size = production_tab[(-act)-1][1];
+
+          /* pop the handle off the stack */
+          for (int i = 0; i < handle_size; i++)
+        {
+          stack.pop();
+          tos--;
+        }
+          
+          /* look up the state to go to from the one popped back to */
+          act = get_reduce(((symbol)stack.peek()).parse_state, lhs_sym_num);
+
+          /* shift to that state */
+          lhs_sym.parse_state = act;
+          stack.push(lhs_sym);
+          tos++;
+        }
+      /* finally if the entry is zero, we have an error */
+      else if (act == 0)
+        {
+          /* call user syntax error reporting routine */
+          syntax_error(cur_token);
+
+          /* try to error recover */
+          if (!error_recovery(false))
+        {
+          /* if that fails give up with a fatal syntax error */
+          unrecovered_syntax_error(cur_token);
+
+          /* just in case that wasn't fatal enough, end parse */
+          done_parsing();
+        }
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Write a debugging message to System.err for the debugging version 
+   *  of the parser. 
+   *
+   * @param mess the text of the debugging message.
+   */
+  public void debug_message(String mess)
+    {
+      System.err.println(mess);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Dump the parse stack for debugging purposes. */
+  public void dump_stack()
+    {
+      if (stack == null)
+    {
+      debug_message("# Stack dump requested, but stack is null");
+      return;
+    }
+
+      debug_message("============ Parse Stack Dump ============");
+
+      /* dump the stack */
+      for (int i=0; i<stack.size(); i++)
+    {
+      debug_message("Symbol: " + ((symbol)stack.elementAt(i)).sym +
+            " State: " + ((symbol)stack.elementAt(i)).parse_state);
+    }
+      debug_message("==========================================");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do debug output for a reduce. 
+   *
+   * @param prod_num  the production we are reducing with.
+   * @param nt_num    the index of the LHS non terminal.
+   * @param rhs_size  the size of the RHS.
+   */
+  public void debug_reduce(int prod_num, int nt_num, int rhs_size)
+    {
+      debug_message("# Reduce with prod #" + prod_num + " [NT=" + nt_num + 
+                ", " + "SZ=" + rhs_size + "]");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do debug output for shift. 
+   *
+   * @param shift_tkn the token being shifted onto the stack.
+   */
+  public void debug_shift(token shift_tkn)
+    {
+      debug_message("# Shift under term #" + shift_tkn.sym + 
+            " to state #" + shift_tkn.parse_state);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Perform a parse with debugging output.  This does exactly the
+   *  same things as parse(), except that it calls debug_shift() and
+   *  debug_reduce() when shift and reduce moves are taken by the parser
+   *  and produces various other debugging messages.  
+   */
+  public void debug_parse()
+    throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the symbol/stack element returned by a reduce */
+      symbol lhs_sym;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* set up direct reference to tables to drive the parser */
+      production_tab = production_table();
+      action_tab     = action_table();
+      reduce_tab     = reduce_table();
+
+      debug_message("# Initializing parser");
+
+      /* initialize the action encapsulation object */
+      init_actions();
+
+      /* do user initialization */
+      user_init();
+
+      /* the current token */
+      cur_token = scan(); 
+
+      debug_message("# Current token is #" + cur_token.sym);
+
+      /* push dummy symbol with start state to get us underway */
+      stack.push(new symbol(0, start_state()));
+      tos = 0;
+
+      /* continue until we are told to stop */
+      for (_done_parsing = false; !_done_parsing; )
+    {
+      /* current state is always on the top of the stack */
+
+      /* look up action out of the current state with the current input */
+      act = get_action(((symbol)stack.peek()).parse_state, cur_token.sym);
+
+      /* decode the action -- > 0 encodes shift */
+      if (act > 0)
+        {
+          /* shift to the encoded state by pushing it on the stack */
+          cur_token.parse_state = act-1;
+          debug_shift(cur_token);
+          stack.push(cur_token);
+          tos++;
+
+          /* advance to the next token */
+          cur_token = scan();
+              debug_message("# Current token is #" + cur_token.sym);
+        }
+      /* if its less than zero, then it encodes a reduce action */
+      else if (act < 0)
+        {
+          /* perform the action for the reduce */
+          lhs_sym = do_action((-act)-1, this, stack, tos);
+
+          /* look up information about the production */
+          lhs_sym_num = production_tab[(-act)-1][0];
+          handle_size = production_tab[(-act)-1][1];
+
+          debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+          /* pop the handle off the stack */
+          for (int i = 0; i < handle_size; i++)
+        {
+          stack.pop();
+          tos--;
+        }
+          
+          /* look up the state to go to from the one popped back to */
+          act = get_reduce(((symbol)stack.peek()).parse_state, lhs_sym_num);
+
+          /* shift to that state */
+          lhs_sym.parse_state = act;
+          stack.push(lhs_sym);
+          tos++;
+
+          debug_message("# Goto state #" + act);
+        }
+      /* finally if the entry is zero, we have an error */
+      else if (act == 0)
+        {
+          /* call user syntax error reporting routine */
+          syntax_error(cur_token);
+
+          /* try to error recover */
+          if (!error_recovery(true))
+        {
+          /* if that fails give up with a fatal syntax error */
+          unrecovered_syntax_error(cur_token);
+
+          /* just in case that wasn't fatal enough, end parse */
+          done_parsing();
+        }
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+  /* Error recovery code */
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Attempt to recover from a syntax error.  This returns false if recovery 
+   *  fails, true if it succeeds.  Recovery happens in 4 steps.  First we
+   *  pop the parse stack down to a point at which we have a shift out
+   *  of the top-most state on the error symbol.  This represents the
+   *  initial error recovery configuration.  If no such configuration is
+   *  found, then we fail.  Next a small number of "lookahead" or "parse
+   *  ahead" tokens are read into a buffer.  The size of this buffer is 
+   *  determined by error_sync_size() and determines how many tokens beyond
+   *  the error must be matched to consider the recovery a success.  Next, 
+   *  we begin to discard tokens in attempt to get past the point of error
+   *  to a point where we can continue parsing.  After each token, we attempt 
+   *  to "parse ahead" though the buffered lookahead tokens.  The "parse ahead"
+   *  process simulates that actual parse, but does not modify the real 
+   *  parser's configuration, nor execute any actions. If we can  parse all 
+   *  the stored tokens without error, then the recovery is considered a 
+   *  success.  Once a successful recovery point is determined, we do an
+   *  actual parse over the stored input -- modifying the real parse 
+   *  configuration and executing all actions.  Finally, we return the the 
+   *  normal parser to continue with the overall parse.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean error_recovery(boolean debug)
+    throws java.lang.Exception
+    {
+      if (debug) debug_message("# Attempting error recovery");
+
+      /* first pop the stack back into a state that can shift on error and 
+     do that shift (if that fails, we fail) */
+      if (!find_recovery_config(debug))
+    {
+      if (debug) debug_message("# Error recovery fails");
+      return false;
+    }
+
+      /* read ahead to create lookahead we can parse multiple times */
+      read_lookahead();
+
+      /* repeatedly try to parse forward until we make it the required dist */
+      for (;;)
+    {
+      /* try to parse forward, if it makes it, bail out of loop */
+      if (debug) debug_message("# Trying to parse ahead");
+      if (try_parse_ahead(debug))
+        {
+          break;
+        }
+
+      /* if we are now at EOF, we have failed */
+      if (lookahead[0].sym == EOF_sym()) 
+        {
+          if (debug) debug_message("# Error recovery fails at EOF");
+          return false;
+        }
+
+      /* otherwise, we consume another token and try again */
+      if (debug) 
+      debug_message("# Consuming token #" + cur_err_token().sym);
+      restart_lookahead();
+    }
+
+      /* we have consumed to a point where we can parse forward */
+      if (debug) debug_message("# Parse-ahead ok, going back to normal parse");
+
+      /* do the real parse (including actions) across the lookahead */
+      parse_lookahead(debug);
+
+      /* we have success */
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if we can shift under the special error symbol out of the 
+   *  state currently on the top of the (real) parse stack. 
+   */
+  protected boolean shift_under_error()
+    {
+      /* is there a shift under error symbol */
+      return get_action(((symbol)stack.peek()).parse_state, error_sym()) > 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Put the (real) parse stack into error recovery configuration by 
+   *  popping the stack down to a state that can shift on the special 
+   *  error symbol, then doing the shift.  If no suitable state exists on 
+   *  the stack we return false 
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean find_recovery_config(boolean debug)
+    {
+      token error_token;
+      int act;
+
+      if (debug) debug_message("# Finding recovery state on stack");
+
+      /* pop down until we can shift under error token */
+      while (!shift_under_error())
+    {
+      /* pop the stack */
+      if (debug) 
+        debug_message("# Pop stack by one, state was # " +
+                      ((symbol)stack.peek()).parse_state);
+          stack.pop();    
+      tos--;
+
+      /* if we have hit bottom, we fail */
+      if (stack.empty()) 
+        {
+          if (debug) debug_message("# No recovery state found on stack");
+          return false;
+        }
+    }
+
+      /* state on top of the stack can shift under error, find the shift */
+      act = get_action(((symbol)stack.peek()).parse_state, error_sym());
+      if (debug) 
+    {
+      debug_message("# Recover state found (#" + 
+            ((symbol)stack.peek()).parse_state + ")");
+      debug_message("# Shifting on error to state #" + (act-1));
+    }
+
+      /* build and shift a special error token */
+      error_token = new token(error_sym());
+      error_token.parse_state = act-1;
+      stack.push(error_token);
+      tos++;
+
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Lookahead tokens used for attempting error recovery "parse aheads". */
+  protected token lookahead[];
+
+  /** Position in lookahead input buffer used for "parse ahead". */
+  protected int lookahead_pos;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Read from input to establish our buffer of "parse ahead" lookahead 
+   *  symbols. 
+   */
+  protected void read_lookahead() throws java.lang.Exception
+    {
+      /* create the lookahead array */
+      lookahead = new token[error_sync_size()];
+
+      /* fill in the array */
+      for (int i = 0; i < error_sync_size(); i++)
+    {
+      lookahead[i] = cur_token;
+      cur_token = scan();
+    }
+
+      /* start at the beginning */
+      lookahead_pos = 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return the current lookahead in our error "parse ahead" buffer. */
+  protected token cur_err_token() { return lookahead[lookahead_pos]; }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Advance to next "parse ahead" input symbol. Return true if we have 
+   *  input to advance to, false otherwise. 
+   */
+  protected boolean advance_lookahead()
+    {
+      /* advance the input location */
+      lookahead_pos++;
+
+      /* return true if we didn't go off the end */
+      return lookahead_pos < error_sync_size();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Reset the parse ahead input to one token past where we started error 
+   *  recovery (this consumes one new token from the real input). 
+   */
+  protected void restart_lookahead() throws java.lang.Exception
+    {
+      /* move all the existing input over */
+      for (int i = 1; i < error_sync_size(); i++)
+    lookahead[i-1] = lookahead[i];
+
+      /* read a new token into the last spot */
+      cur_token = scan();
+      lookahead[error_sync_size()-1] = cur_token;
+
+      /* reset our internal position marker */
+      lookahead_pos = 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do a simulated parse forward (a "parse ahead") from the current 
+   *  stack configuration using stored lookahead input and a virtual parse
+   *  stack.  Return true if we make it all the way through the stored 
+   *  lookahead input without error. This basically simulates the action of 
+   *  parse() using only our saved "parse ahead" input, and not executing any 
+   *  actions.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean try_parse_ahead(boolean debug)
+    throws java.lang.Exception
+    {
+      int act;
+      short lhs, rhs_size;
+
+      /* create a virtual stack from the real parse stack */
+      virtual_parse_stack vstack = new virtual_parse_stack(stack);
+
+      /* parse until we fail or get past the lookahead input */
+      for (;;)
+    {
+      /* look up the action from the current state (on top of stack) */
+      act = get_action(vstack.top(), cur_err_token().sym);
+
+      /* if its an error, we fail */
+      if (act == 0) return false;
+
+      /* > 0 encodes a shift */
+      if (act > 0)
+        {
+          /* push the new state on the stack */
+          vstack.push(act-1);
+
+          if (debug) debug_message("# Parse-ahead shifts token #" + 
+               cur_err_token().sym + " into state #" + (act-1));
+
+          /* advance simulated input, if we run off the end, we are done */
+          if (!advance_lookahead()) return true;
+        }
+      /* < 0 encodes a reduce */
+      else
+        {
+          /* if this is a reduce with the start production we are done */
+          if ((-act)-1 == start_production()) 
+        {
+          if (debug) debug_message("# Parse-ahead accepts");
+          return true;
+        }
+
+          /* get the lhs symbol and the rhs size */
+          lhs = production_tab[(-act)-1][0];
+          rhs_size = production_tab[(-act)-1][1];
+
+          /* pop handle off the stack */
+          for (int i = 0; i < rhs_size; i++)
+        vstack.pop();
+
+          if (debug) 
+        debug_message("# Parse-ahead reduces: handle size = " + 
+              rhs_size + " lhs = #" + lhs + " from state #" + vstack.top());
+
+          /* look up goto and push it onto the stack */
+          vstack.push(get_reduce(vstack.top(), lhs));
+          if (debug) 
+        debug_message("# Goto state #" + vstack.top());
+        }
+    }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Parse forward using stored lookahead symbols.  In this case we have
+   *  already verified that parsing will make it through the stored lookahead
+   *  symbols and we are now getting back to the point at which we can hand
+   *  control back to the normal parser.  Consequently, this version of the
+   *  parser performs all actions and modifies the real parse configuration.  
+   *  This returns once we have consumed all the stored input or we accept.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected void parse_lookahead(boolean debug)
+    throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the symbol/stack element returned by a reduce */
+      symbol lhs_sym;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* restart the saved input at the beginning */
+      lookahead_pos = 0;
+
+      if (debug) 
+    {
+      debug_message("# Reparsing saved input with actions");
+      debug_message("# Current token is #" + cur_err_token().sym);
+      debug_message("# Current state is #" + 
+            ((symbol)stack.peek()).parse_state);
+    }
+
+      /* continue until we accept or have read all lookahead input */
+      while(!_done_parsing)
+    {
+      /* current state is always on the top of the stack */
+
+      /* look up action out of the current state with the current input */
+      act = 
+        get_action(((symbol)stack.peek()).parse_state, cur_err_token().sym);
+
+      /* decode the action -- > 0 encodes shift */
+      if (act > 0)
+        {
+          /* shift to the encoded state by pushing it on the stack */
+          cur_err_token().parse_state = act-1;
+          if (debug) debug_shift(cur_err_token());
+          stack.push(cur_err_token());
+          tos++;
+
+          /* advance to the next token, if there is none, we are done */
+          if (!advance_lookahead()) 
+        {
+          if (debug) debug_message("# Completed reparse");
+
+          /* scan next token so we can continue parse */
+          cur_token = scan();
+
+          /* go back to normal parser */
+          return;
+        }
+          
+          if (debug) 
+        debug_message("# Current token is #" + cur_err_token().sym);
+        }
+      /* if its less than zero, then it encodes a reduce action */
+      else if (act < 0)
+        {
+          /* perform the action for the reduce */
+          lhs_sym = do_action((-act)-1, this, stack, tos);
+
+          /* look up information about the production */
+          lhs_sym_num = production_tab[(-act)-1][0];
+          handle_size = production_tab[(-act)-1][1];
+
+          if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+          /* pop the handle off the stack */
+          for (int i = 0; i < handle_size; i++)
+        {
+          stack.pop();
+          tos--;
+        }
+          
+          /* look up the state to go to from the one popped back to */
+          act = get_reduce(((symbol)stack.peek()).parse_state, lhs_sym_num);
+
+          /* shift to that state */
+          lhs_sym.parse_state = act;
+          stack.push(lhs_sym);
+          tos++;
+           
+          if (debug) debug_message("# Goto state #" + act);
+
+        }
+      /* finally if the entry is zero, we have an error 
+         (shouldn't happen here, but...)*/
+      else if (act == 0)
+        {
+          report_fatal_error("Syntax error", null);
+          return;
+        }
+    }
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/runtime/str_token.java b/tools/dasm/src/java_cup/runtime/str_token.java
new file mode 100644
index 0000000..96e2c94
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/str_token.java
@@ -0,0 +1,32 @@
+
+package java_cup.runtime;
+
+/** This subclass of token represents symbols that need to maintain one
+ *  String value as an attribute.  It maintains that value in the public
+ *  field str_val.
+ *
+ * @see java_cup.runtime.int_token
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class str_token extends token {
+  /** Full constructor. */
+  public str_token(int term_num, String v)
+    {
+      /* super class does most of the work */
+      super(term_num);
+
+      str_val = v;
+    }
+
+  /** Constructor for value defaulting to an empty string. */
+  public str_token(int term_num)
+    {
+      this(term_num, "");
+    }
+
+  /** The stored string value. */
+  public String str_val;
+
+};
diff --git a/tools/dasm/src/java_cup/runtime/symbol.java b/tools/dasm/src/java_cup/runtime/symbol.java
new file mode 100644
index 0000000..ac0fe5a
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/symbol.java
@@ -0,0 +1,50 @@
+
+package java_cup.runtime;
+
+/** This class represents a (terminal or non-terminal) symbol that, among
+ *  other things can be placed on the parse stack.  Symbols are used to 
+ *  keep track of state on the parse stack.  The symbol currently on top
+ *  of the stack contains the current state in the parse_state field.
+ *  In addition to the parse_state field, symbols also maintain a record
+ *  of the symbol number that they represent in the sym field.  Finally, 
+ *  symbols are used contain to any attributes used by semantic action (this
+ *  is done via fields added in subclasses -- see for example, int_token and
+ *  str_token).
+ *
+ * @see java_cup.runtime.token
+ * @see java_cup.runtime.int_token
+ * @see java_cup.runtime.str_token
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class symbol {
+
+  /** Full constructor. */
+  public symbol(int sym_num, int state)
+    {
+      sym = sym_num;
+      parse_state = state;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor without a known state. */
+  public symbol(int sym_num)
+    {
+      this(sym_num, -1);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The symbol number of the terminal or non terminal being represented */
+  public int sym;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The parse state to be recorded on the parse stack with this symbol.
+   *  This field is for the convenience of the parser and shouldn't be 
+   *  modified except by the parser. 
+   */
+  public int parse_state;
+};
diff --git a/tools/dasm/src/java_cup/runtime/token.java b/tools/dasm/src/java_cup/runtime/token.java
new file mode 100644
index 0000000..0df9b81
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/token.java
@@ -0,0 +1,21 @@
+
+package java_cup.runtime;
+
+/** This subclass of symbol represents (at least) terminal symbols returned 
+ *  by the scanner and placed on the parse stack.  At present, this 
+ *  class does nothing more than its super class.
+ *  
+ * @see java_cup.runtime.int_token
+ * @see java_cup.runtime.str_token
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class token extends symbol {
+
+  /* Simple constructor -- just delegates to the super class. */
+  public token(int term_num)
+    {
+      /* super class does all the work */
+      super(term_num);
+    }
+};
diff --git a/tools/dasm/src/java_cup/runtime/virtual_parse_stack.java b/tools/dasm/src/java_cup/runtime/virtual_parse_stack.java
new file mode 100644
index 0000000..507b755
--- /dev/null
+++ b/tools/dasm/src/java_cup/runtime/virtual_parse_stack.java
@@ -0,0 +1,145 @@
+
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a temporary or "virtual" parse stack that 
+ *  replaces the top portion of the actual parse stack (the part that 
+ *  has been changed by some set of operations) while maintaining its
+ *  original contents.  This data structure is used when the parse needs 
+ *  to "parse ahead" to determine if a given error recovery attempt will 
+ *  allow the parse to continue far enough to consider it successful.  Once 
+ *  success or failure of parse ahead is determined the system then 
+ *  reverts to the original parse stack (which has not actually been 
+ *  modified).  Since parse ahead does not execute actions, only parse
+ *  state is maintained on the virtual stack, not full symbol objects.
+ *
+ * @see     java_cup.runtime.lr_parser
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+
+public class virtual_parse_stack {
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constructor to build a virtual stack out of a real stack. */
+  public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception
+    {
+      /* sanity check */
+      if (shadowing_stack == null)
+    throw new Exception(
+      "Internal parser error: attempt to create null virtual stack");
+
+      /* set up our internals */
+      real_stack = shadowing_stack;
+      vstack     = new Stack();
+      real_next  = 0;
+
+      /* get one element onto the virtual portion of the stack */
+      get_from_real();
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** The real stack that we shadow.  This is accessed when we move off
+   *  the bottom of the virtual portion of the stack, but is always left
+   *  unmodified.
+   */
+  protected Stack real_stack;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Top of stack indicator for where we leave off in the real stack.
+   *  This is measured from top of stack, so 0 would indicate that no
+   *  elements have been "moved" from the real to virtual stack. 
+   */
+  protected int real_next;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The virtual top portion of the stack.  This stack contains Integer
+   *  objects with state numbers.  This stack shadows the top portion
+   *  of the real stack within the area that has been modified (via operations
+   *  on the virtual stack).  When this portion of the stack becomes empty we 
+   *  transfer elements from the underlying stack onto this stack. 
+   */
+  protected Stack vstack;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Transfer an element from the real to the virtual stack.  This assumes 
+   *  that the virtual stack is currently empty.  
+   */
+  protected void get_from_real()
+    {
+      symbol stack_sym;
+
+      /* don't transfer if the real stack is empty */
+      if (real_next >= real_stack.size()) return;
+
+      /* get a copy of the first symbol we have not transfered */
+      stack_sym = (symbol)real_stack.elementAt(real_stack.size()-1-real_next);
+
+      /* record the transfer */
+      real_next++;
+
+      /* put the state number from the symbol onto the virtual stack */
+      vstack.push(new Integer(stack_sym.parse_state));
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indicate whether the stack is empty. */
+  public boolean empty()
+    {
+      /* if vstack is empty then we were unable to transfer onto it and 
+     the whole thing is empty. */
+      return vstack.empty();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+      
+  /** Return value on the top of the stack (without popping it). */
+  public int top() throws java.lang.Exception
+    {
+      if (vstack.empty())
+    throw new Exception(
+          "Internal parser error: top() called on empty virtual stack");
+
+      return ((Integer)vstack.peek()).intValue();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Pop the stack. */
+  public void pop() throws java.lang.Exception
+    {
+      if (vstack.empty())
+    throw new Exception(
+          "Internal parser error: pop from empty virtual stack");
+
+      /* pop it */
+      vstack.pop();
+
+      /* if we are now empty transfer an element (if there is one) */
+      if (vstack.empty())
+        get_from_real();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Push a state number onto the stack. */
+  public void push(int state_num)
+    {
+      vstack.push(new Integer(state_num));
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/shift_action.java b/tools/dasm/src/java_cup/shift_action.java
new file mode 100644
index 0000000..f1513cd
--- /dev/null
+++ b/tools/dasm/src/java_cup/shift_action.java
@@ -0,0 +1,82 @@
+
+package java_cup;
+
+/** This class represents a shift action within the parse table. 
+ *  The action simply stores the state that it shifts to and responds 
+ *  to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class shift_action extends parse_action {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. 
+   * @param shft_to the state that this action shifts to.
+   */
+  public shift_action(lalr_state shft_to) throws internal_error
+    {
+      /* sanity check */
+      if (shft_to == null)
+    throw new internal_error(
+      "Attempt to create a shift_action to a null state");
+
+      _shift_to = shft_to;
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The state we shift to. */
+  protected lalr_state _shift_to;
+
+  /** The state we shift to. */
+  public lalr_state shift_to() {return _shift_to;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Quick access to type of action. */
+  public int kind() {return SHIFT;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality test. */
+  public boolean equals(shift_action other)
+    {
+      return other != null && other.shift_to() == shift_to();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality test. */
+  public boolean equals(Object other)
+    {
+      if (other instanceof shift_action)
+    return equals((shift_action)other);
+      else
+       return false;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute a hash code. */
+  public int hashCode()
+    {
+      /* use the hash code of the state we are shifting to */
+      return shift_to().hashCode();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString() {return "SHIFT(" + shift_to().index() + ")";}
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/sym.java b/tools/dasm/src/java_cup/sym.java
new file mode 100644
index 0000000..3987e25
--- /dev/null
+++ b/tools/dasm/src/java_cup/sym.java
@@ -0,0 +1,36 @@
+
+//----------------------------------------------------
+// The following code was generated by Java(tm) CUP v0.9d
+// Thu Aug 10 03:51:39 MSD 2006
+//----------------------------------------------------
+
+package java_cup;
+
+/** JavaCup generated class containing symbol constants. */
+public class sym {
+  /* terminals */
+  static final int IMPORT = 3;
+  static final int INIT = 9;
+  static final int CODE_STRING = 22;
+  static final int DEBUG = 20;
+  static final int SEMI = 13;
+  static final int STAR = 15;
+  static final int CODE = 4;
+  static final int COLON = 17;
+  static final int NON = 8;
+  static final int ID = 21;
+  static final int WITH = 11;
+  static final int TERMINAL = 7;
+  static final int COLON_COLON_EQUALS = 18;
+  static final int COMMA = 14;
+  static final int EOF = 0;
+  static final int PARSER = 6;
+  static final int error = 1;
+  static final int DOT = 16;
+  static final int ACTION = 5;
+  static final int START = 12;
+  static final int PACKAGE = 2;
+  static final int BAR = 19;
+  static final int SCAN = 10;
+};
+
diff --git a/tools/dasm/src/java_cup/symbol.java b/tools/dasm/src/java_cup/symbol.java
new file mode 100644
index 0000000..1c99640
--- /dev/null
+++ b/tools/dasm/src/java_cup/symbol.java
@@ -0,0 +1,107 @@
+package java_cup;
+
+/** This abstract class serves as the base class for grammar symbols (i.e.,
+ * both terminals and non-terminals).  Each symbol has a name string, and
+ * a string giving the type of object that the symbol will be represented by
+ * on the runtime parse stack.  In addition, each symbol maintains a use count
+ * in order to detect symbols that are declared but never used, and an index
+ * number that indicates where it appears in parse tables (index numbers are
+ * unique within terminals or non terminals, but not across both).
+ *
+ * @see     java_cup.terminal
+ * @see     java_cup.non_terminal
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public abstract class symbol {
+   /*-----------------------------------------------------------*/
+   /*--- Constructor(s) ----------------------------------------*/
+   /*-----------------------------------------------------------*/
+
+   /** Full constructor.
+    * @param nm the name of the symbol.
+    * @param tp a string with the type name.
+    */
+   public symbol(String nm, String tp)
+     {
+       /* sanity check */
+       if (nm == null) nm = "";
+
+       /* apply default if no type given */
+       if (tp == null) tp = "java_cup.runtime.token";
+
+       _name = nm;
+       _stack_type = tp;
+     }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+   /** Constructor with default type. 
+    * @param nm the name of the symbol.
+    */
+   public symbol(String nm)
+     {
+       this(nm, null);
+     }
+
+   /*-----------------------------------------------------------*/
+   /*--- (Access to) Instance Variables ------------------------*/
+   /*-----------------------------------------------------------*/
+
+   /** String for the human readable name of the symbol. */
+   protected String _name; 
+ 
+   /** String for the human readable name of the symbol. */
+   public String name() {return _name;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+   /** String for the type of object used for the symbol on the parse stack. */
+   protected String _stack_type;
+
+   /** String for the type of object used for the symbol on the parse stack. */
+   public String stack_type() {return _stack_type;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+   /** Count of how many times the symbol appears in productions. */
+   protected int _use_count = 0;
+
+   /** Count of how many times the symbol appears in productions. */
+   public int use_count() {return _use_count;}
+
+   /** Increment the use count. */ 
+   public void note_use() {_use_count++;}
+ 
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ 
+  /** Index of this symbol (terminal or non terminal) in the parse tables.
+   *  Note: indexes are unique among terminals and unique among non terminals,
+   *  however, a terminal may have the same index as a non-terminal, etc. 
+   */
+   protected int _index;
+ 
+  /** Index of this symbol (terminal or non terminal) in the parse tables.
+   *  Note: indexes are unique among terminals and unique among non terminals,
+   *  however, a terminal may have the same index as a non-terminal, etc. 
+   */
+   public int index() {return _index;}
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indicate if this is a non-terminal.  Here in the base class we
+   *  don't know, so this is abstract.  
+   */
+  public abstract boolean is_non_term();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      return name();
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/symbol_part.java b/tools/dasm/src/java_cup/symbol_part.java
new file mode 100644
index 0000000..e923af6
--- /dev/null
+++ b/tools/dasm/src/java_cup/symbol_part.java
@@ -0,0 +1,100 @@
+package java_cup;
+
+/** This class represents a part of a production which is a symbol (terminal
+ *  or non terminal).  This simply maintains a reference to the symbol in 
+ *  question.
+ *
+ * @see     java_cup.production
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class symbol_part extends production_part {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor. 
+   * @param sym the symbol that this part is made up of.
+   * @param lab an optional label string for the part.
+   */
+  public symbol_part(symbol sym, String lab) throws internal_error
+    {
+      super(lab);
+
+      if (sym == null)
+    throw new internal_error(
+      "Attempt to construct a symbol_part with a null symbol");
+      _the_symbol = sym;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with no label. 
+   * @param sym the symbol that this part is made up of.
+   */
+  public symbol_part(symbol sym) throws internal_error
+    {
+      this(sym,null);
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The symbol that this part is made up of. */
+  protected symbol _the_symbol;
+
+  /** The symbol that this part is made up of. */
+  public symbol the_symbol() {return _the_symbol;}
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Respond that we are not an action part. */
+  public boolean is_action() { return false; }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(symbol_part other)
+    {
+      return other != null && super.equals(other) && 
+         the_symbol().equals(other.the_symbol());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof symbol_part))
+    return false;
+      else
+    return equals((symbol_part)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Produce a hash code. */
+  public int hashCode()
+    {
+      return super.hashCode() ^ 
+         (the_symbol()==null ? 0 : the_symbol().hashCode());
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      if (the_symbol() != null)
+    return super.toString() + the_symbol();
+      else
+    return super.toString() + "$$MISSING-SYMBOL$$";
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/symbol_set.java b/tools/dasm/src/java_cup/symbol_set.java
new file mode 100644
index 0000000..ef478be
--- /dev/null
+++ b/tools/dasm/src/java_cup/symbol_set.java
@@ -0,0 +1,231 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** This class represents a set of symbols and provides a series of 
+ *  set operations to manipulate them.
+ *
+ * @see     java_cup.symbol
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class symbol_set {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constructor for an empty set. */
+  public symbol_set() { };
+
+  /** Constructor for cloning from another set. 
+   * @param other the set we are cloning from.
+   */
+  public symbol_set(symbol_set other) throws internal_error
+    {
+      not_null(other);
+      _all = (Hashtable)other._all.clone();
+    };
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** A hash table to hold the set. Symbols are keyed using their name string. 
+   */
+  protected Hashtable _all = new Hashtable(11);
+
+  /** Access to all elements of the set. */
+  public Enumeration all() {return _all.elements();};
+
+  /** size of the set */
+  public int size() {return _all.size();};
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Helper function to test for a null object and throw an exception
+   *  if one is found.
+   * @param obj the object we are testing.
+   */
+  protected void not_null(Object obj) throws internal_error
+    {
+      if (obj == null) 
+    throw new internal_error("Null object used in set operation");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if the set contains a particular symbol. 
+   * @param sym the symbol we are looking for.
+   */
+  public boolean contains(symbol sym) {return _all.containsKey(sym.name());};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if this set is an (improper) subset of another. 
+   * @param other the set we are testing against.
+   */
+  public boolean is_subset_of(symbol_set other) throws internal_error
+    {
+      not_null(other);
+
+      /* walk down our set and make sure every element is in the other */
+      for (Enumeration e = all(); e.hasMoreElements(); )
+    if (!other.contains((symbol)e.nextElement()))
+      return false;
+
+      /* they were all there */
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if this set is an (improper) superset of another. 
+   * @param other the set we are are testing against.
+   */
+  public boolean is_superset_of(symbol_set other) throws internal_error
+    {
+      not_null(other);
+      return other.is_subset_of(this);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a single symbol to the set.  
+   * @param sym the symbol we are adding.
+   * @return true if this changes the set.
+   */
+  public boolean add(symbol sym) throws internal_error
+    {
+      Object previous;
+
+      not_null(sym); 
+
+      /* put the object in */
+      previous = _all.put(sym.name(),sym);
+
+      /* if we had a previous, this is no change */
+      return previous == null;
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove a single symbol if it is in the set. 
+   * @param sym the symbol we are removing.
+   */
+  public void remove(symbol sym) throws internal_error
+    {
+      not_null(sym); 
+      _all.remove(sym.name());
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add (union) in a complete set.  
+   * @param other the set we are adding in.
+   * @return true if this changes the set. 
+   */
+  public boolean add(symbol_set other) throws internal_error
+    {
+      boolean result = false;
+
+      not_null(other);
+
+      /* walk down the other set and do the adds individually */
+      for (Enumeration e = other.all(); e.hasMoreElements(); )
+    result = add((symbol)e.nextElement()) || result;
+
+      return result;
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove (set subtract) a complete set. 
+   * @param other the set we are removing.
+   */
+  public void remove(symbol_set other) throws internal_error
+    {
+      not_null(other);
+
+      /* walk down the other set and do the removes individually */
+      for (Enumeration e = other.all(); e.hasMoreElements(); )
+    remove((symbol)e.nextElement());
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(symbol_set other) 
+    {
+      if (other == null || other.size() != size()) return false;
+
+      /* once we know they are the same size, then improper subset does test */
+      try {
+        return is_subset_of(other);
+      } catch (internal_error e) {
+    /* can't throw the error (because super class doesn't), so we crash */
+    e.crash();
+    return false;
+      }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof symbol_set))
+    return false;
+      else
+    return equals((symbol_set)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Compute a hash code. */
+  public int hashCode()
+    {
+      int result = 0;
+      int cnt;
+      Enumeration e;
+
+      /* hash together codes from at most first 5 elements */
+      for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
+    result ^= ((symbol)e.nextElement()).hashCode();
+
+      return result;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      String result;
+      boolean comma_flag;
+
+      result = "{";
+      comma_flag = false;
+      for (Enumeration e = all(); e.hasMoreElements(); )
+    {
+      if (comma_flag)
+        result += ", ";
+      else
+        comma_flag = true;
+
+      result += ((symbol)e.nextElement()).name();
+    }
+      result += "}";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
+
diff --git a/tools/dasm/src/java_cup/terminal.java b/tools/dasm/src/java_cup/terminal.java
new file mode 100644
index 0000000..bb8dfdd
--- /dev/null
+++ b/tools/dasm/src/java_cup/terminal.java
@@ -0,0 +1,130 @@
+package java_cup;
+ 
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** This class represents a terminal symbol in the grammar.  Each terminal 
+ *  has a textual name, an index, and a string which indicates the type of 
+ *  object it will be implemented with at runtime (i.e. the class of object 
+ *  that will be returned by the scanner and pushed on the parse stack to 
+ *  represent it). 
+ *
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class terminal extends symbol {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Full constructor.
+   * @param nm the name of the terminal.
+   * @param tp the type of the terminal.
+   */
+  public terminal(String nm, String tp) 
+    {
+      /* superclass does most of the work */
+      super(nm, tp);
+
+      /* add to set of all terminals and check for duplicates */
+      Object conflict = _all.put(nm,this);
+      if (conflict != null)
+    // can't throw an execption here because this is used in static 
+    // initializers, so we do a crash instead
+    // was:
+    // throw new internal_error("Duplicate terminal (" + nm + ") created");
+    (new internal_error("Duplicate terminal (" + nm + ") created")).crash();
+
+      /* assign a unique index */
+      _index = next_index++;
+
+      /* add to by_index set */
+      _all_by_index.put(new Integer(_index), this);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor with default type. 
+   * @param nm the name of the terminal.
+   */
+  public terminal(String nm) 
+    {
+      this(nm, null);
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Table of all terminals.  Elements are stored using name strings as 
+   *  the key 
+   */
+  protected static Hashtable _all = new Hashtable();
+
+  /** Access to all terminals. */
+  public static Enumeration all() {return _all.elements();};
+
+  /** Lookup a terminal by name string. */ 
+  public static terminal find(String with_name)
+    {
+      if (with_name == null)
+    return null;
+      else 
+    return (terminal)_all.get(with_name);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Table of all terminals indexed by their index number. */
+  protected static Hashtable _all_by_index = new Hashtable();
+
+  /** Lookup a terminal by index. */
+  public static terminal find(int indx)
+    {
+      Integer the_indx = new Integer(indx);
+
+      return (terminal)_all_by_index.get(the_indx);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Total number of terminals. */
+  public static int number() {return _all.size();};
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ 
+  /** Static counter to assign unique index. */
+  protected static int next_index = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Special terminal for end of input. */
+  public static final terminal EOF = new terminal("EOF");
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** special terminal used for error recovery */
+  public static final terminal error = new terminal("error");
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Report this symbol as not being a non-terminal. */
+  public boolean is_non_term() 
+    {
+      return false;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to a string. */
+  public String toString()
+    {
+      return super.toString() + "[" + index() + "]";
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
diff --git a/tools/dasm/src/java_cup/terminal_set.java b/tools/dasm/src/java_cup/terminal_set.java
new file mode 100644
index 0000000..591233b
--- /dev/null
+++ b/tools/dasm/src/java_cup/terminal_set.java
@@ -0,0 +1,253 @@
+
+package java_cup;
+
+import java.util.BitSet;
+
+/** A set of terminals implemented as a bitset. 
+ * @version last updated: 11/25/95
+ * @author  Scott Hudson
+ */
+public class terminal_set {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constructor for an empty set. */
+  public terminal_set() 
+    { 
+      /* allocate the bitset at what is probably the right size */
+      _elements = new BitSet(terminal.number());
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Constructor for cloning from another set. 
+   * @param other the set we are cloning from.
+   */
+  public terminal_set(terminal_set other) 
+    throws internal_error
+    {
+      not_null(other);
+      _elements = (BitSet)other._elements.clone();
+    };
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constant for the empty set. */
+  public static final terminal_set EMPTY = new terminal_set();
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Bitset to implement the actual set. */
+  protected BitSet _elements;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Helper function to test for a null object and throw an exception if
+   *  one is found. 
+   * @param obj the object we are testing.
+   */
+  protected void not_null(Object obj) throws internal_error
+    {
+      if (obj == null) 
+    throw new internal_error("Null object used in set operation");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if the set is empty. */
+  public boolean empty()
+    {
+      return equals(EMPTY);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if the set contains a particular terminal. 
+   * @param sym the terminal symbol we are looking for.
+   */
+  public boolean contains(terminal sym) 
+    throws internal_error
+    {
+      not_null(sym); 
+      return _elements.get(sym.index());
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Given its index determine if the set contains a particular terminal. 
+   * @param indx the index of the terminal in question.
+   */
+  public boolean contains(int indx) 
+    {
+      return _elements.get(indx);
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if this set is an (improper) subset of another.
+   * @param other the set we are testing against.
+   */
+  public boolean is_subset_of(terminal_set other)
+    throws internal_error
+    {
+      not_null(other);
+
+      /* make a copy of the other set */
+      BitSet copy_other = (BitSet)other._elements.clone();
+
+      /* and or in */
+      copy_other.or(_elements);
+
+      /* if it hasn't changed, we were a subset */
+      return copy_other.equals(other._elements);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if this set is an (improper) superset of another.
+   * @param other the set we are testing against.
+   */
+  public boolean is_superset_of(terminal_set other)
+    throws internal_error
+    {
+      not_null(other);
+      return other.is_subset_of(this);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add a single terminal to the set.  
+   * @param sym the terminal being added.
+   * @return true if this changes the set.
+   */
+  public boolean add(terminal sym) 
+    throws internal_error
+    {
+      boolean result;
+
+      not_null(sym); 
+
+      /* see if we already have this */ 
+      result = _elements.get(sym.index());
+
+      /* if not we add it */
+      if (!result)
+    _elements.set(sym.index());
+
+      return result;
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Remove a terminal if it is in the set.
+   * @param sym the terminal being removed.
+   */
+  public void remove(terminal sym) 
+    throws internal_error
+    {
+      not_null(sym); 
+      _elements.clear(sym.index());
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Add (union) in a complete set.  
+   * @param other the set being added.
+   * @return true if this changes the set.
+   */
+  public boolean add(terminal_set other)
+    throws internal_error
+    {
+      not_null(other);
+
+      /* make a copy */
+      BitSet copy = (BitSet)_elements.clone();
+
+      /* or in the other set */
+      _elements.or(other._elements);
+
+      /* changed if we are not the same as the copy */
+      return !_elements.equals(copy);
+    };
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if this set intersects another.
+   * @param other the other set in question.
+   */
+   public boolean intersects(terminal_set other)
+     throws internal_error
+     {
+       not_null(other);
+
+       /* make a copy of the other set */
+       BitSet copy = (BitSet)other._elements.clone();
+
+       /* xor out our values */
+       copy.xor(this._elements);
+
+       /* see if its different */
+       return !copy.equals(other._elements);
+     }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Equality comparison. */
+  public boolean equals(terminal_set other)
+    {
+      if (other == null) 
+    return false;
+      else
+    return _elements.equals(other._elements);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Generic equality comparison. */
+  public boolean equals(Object other)
+    {
+      if (!(other instanceof terminal_set))
+    return false;
+      else
+    return equals((terminal_set)other);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Convert to string. */
+  public String toString()
+    {
+      String result;
+      boolean comma_flag;
+      
+      result = "{";
+      comma_flag = false;
+      for (int t = 0; t < terminal.number(); t++)
+    {
+      if (_elements.get(t))
+        {
+          if (comma_flag)
+            result += ", ";
+          else
+            comma_flag = true;
+
+          result += terminal.find(t).name();
+        }
+    }
+      result += "}";
+
+      return result;
+    }
+
+  /*-----------------------------------------------------------*/
+
+};
+
diff --git a/tools/dasm/src/java_cup/version.java b/tools/dasm/src/java_cup/version.java
new file mode 100644
index 0000000..40a9581
--- /dev/null
+++ b/tools/dasm/src/java_cup/version.java
@@ -0,0 +1,54 @@
+
+package java_cup;
+
+/** This class contains version and authorship information. 
+ *  It contains only static data elements and basically just a central 
+ *  place to put this kind of information so it can be updated easily
+ *  for each release.  
+ *
+ *  Version numbers used here are broken into 3 parts: major, minor, and 
+ *  update, and are written as v<major>.<minor><update> (e.g. v0.9a).  
+ *  Major numbers will change at the time of major reworking of some 
+ *  part of the system.  Minor numbers for each public release or 
+ *  change big enough to cause incompatibilities.  Finally update
+ *  letter will be incremented for small bug fixes and changes that
+ *  probably wouldn't be noticed by a user.  
+ *
+ * @version last updated: 1/7/96
+ * @author  Scott Hudson
+ */
+
+public class version {
+  /** String for the current version. */
+  public static final String version_str = "v0.9d";
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The major version number. */
+  public static final int major = 0;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The minor version number. */
+  public static final int minor = 9;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The update letter. */
+  public static final char update = 'd';
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Full title of the system */
+  public static final String title_str = "Java(tm) CUP " + version_str;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Name of the author */
+  public static final String author_str = "Scott E. Hudson";
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The command name normally used to invoke this program */ 
+  public static final String program_name = "java_cup";
+};