Exemplo n.º 1
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /** 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()
        {
            /* compute nullability of all non terminals */
            if (opt_do_debug || print_progress)
                System.Console.Error.WriteLine("  Computing non-terminal nullability...");
            non_terminal.compute_nullability();

            nullability_end = DateTime.Now.Ticks;

            /* compute first sets of all non terminals */
            if (opt_do_debug || print_progress)
                System.Console.Error.WriteLine("  Computing first sets...");
            non_terminal.compute_first_sets();

            first_end = DateTime.Now.Ticks;

            /* build the LR viable prefix recognition machine */
            if (opt_do_debug || print_progress)
                System.Console.Error.WriteLine("  Building state machine...");
            start_state = lalr_state.build_machine(emit.start_production);

            machine_end = DateTime.Now.Ticks;

            /* build the LR parser action and reduce-goto tables */
            if (opt_do_debug || print_progress)
                System.Console.Error.WriteLine("  Filling in tables...");
            action_table = new parse_action_table();
            reduce_table = new parse_reduce_table();
            IEnumerator st = lalr_state.all();
            while ( st.MoveNext() )
            {
                lalr_state lst = (lalr_state)st.Current;
                lst.build_table_entries(
                    action_table, reduce_table);
            }

            table_end = DateTime.Now.Ticks;

            /* check and warn for non-reduced productions */
            if (opt_do_debug || print_progress)
                System.Console.Error.WriteLine("  Checking for non-reduced productions...");
            action_table.check_reductions();

            reduce_check_end = DateTime.Now.Ticks;

            /* if we have more conflicts than we expected issue a message and die */
            if (emit.num_conflicts > expect_conflicts)
            {
                System.Console.Error.WriteLine("*** More conflicts encountered than expected " +
                    "-- parser generation aborted");
                lexer.error_count++; // indicate the problem.
                // we'll die on return, after clean up.
            }
        }
Exemplo n.º 2
0
  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** 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?
   * @param suppress_scanner should scanner be suppressed for compatibility?
   */

  public static void parser(
    TextWriter        cout, 
    parse_action_table action_table,
    parse_reduce_table reduce_table,
    int                start_st,
    production         start_prod,
    bool            compact_reduces,
    bool            suppress_scanner)
   
    {
      long start_time = DateTime.Now.Ticks;

      /* top of file */
      cout.WriteLine();
      cout.WriteLine("//----------------------------------------------------"); 
      cout.WriteLine("// The following code was generated by " + 
							version.title_str);
      cout.WriteLine("// " +  DateTime.Now);
      cout.WriteLine("//----------------------------------------------------"); 
      cout.WriteLine();
      emit_package(cout);

      /* user supplied imports */
	  IEnumerator myEnum= import_list.GetEnumerator();
      while (myEnum.MoveNext())
	cout.WriteLine("using " + myEnum.Current.ToString() + ";");

      /* class header */
      cout.WriteLine();
      cout.WriteLine("/** "+version.title_str+" generated parser.");
      cout.WriteLine("  * @version " +  DateTime.Now);
      cout.WriteLine("  */");
      cout.WriteLine("public class " + parser_class_name + 
		  " : TUVienna.CS_CUP.Runtime.lr_parser {");

      /* constructors [CSA/davidm, 24-jul-99] */
      cout.WriteLine();
      cout.WriteLine("  /** Default constructor. */");
      cout.WriteLine("  public " + parser_class_name + "():base() {;}");
      if (!suppress_scanner) {
	  cout.WriteLine();
	  cout.WriteLine("  /** Constructor which sets the default scanner. */");
	  cout.WriteLine("  public " + parser_class_name + 
		      "(TUVienna.CS_CUP.Runtime.Scanner s): base(s) {;}");
      }

      /* emit the various tables */
      emit_production_table(cout);
      do_action_table(cout, action_table, compact_reduces);
      do_reduce_table(cout, reduce_table);

      /* instance of the action encapsulation class */
      cout.WriteLine("  /** Instance of action encapsulation class. */");
      cout.WriteLine("  protected " + pre("actions") + " action_obj;");
      cout.WriteLine();

      /* action object initializer */
      cout.WriteLine("  /** Action encapsulation object initializer. */");
      cout.WriteLine("  protected override void init_actions()");
      cout.WriteLine("    {");
      cout.WriteLine("      action_obj = new " + pre("actions") + "(this);");
      cout.WriteLine("    }");
      cout.WriteLine();

      /* access to action code */
      cout.WriteLine("  /** Invoke a user supplied parse action. */");
      cout.WriteLine("  public override TUVienna.CS_CUP.Runtime.Symbol do_action(");
      cout.WriteLine("    int                        act_num,");
      cout.WriteLine("    TUVienna.CS_CUP.Runtime.lr_parser parser,");
      cout.WriteLine("    System.Collections.Stack            xstack1,");
      cout.WriteLine("    int                        top)");
      cout.WriteLine("  {");
      cout.WriteLine("  mStack CUP_parser_stack= new mStack(xstack1);");
      cout.WriteLine("    /* call code in generated class */");
      cout.WriteLine("    return action_obj." + pre("do_action(") +
                  "act_num, parser, stack, top);");
      cout.WriteLine("  }");
      cout.WriteLine("");


      /* method to tell the parser about the start state */
      cout.WriteLine("  /** Indicates start state. */");
      cout.WriteLine("  public override int start_state() {return " + start_st + ";}");

      /* method to indicate start production */
      cout.WriteLine("  /** Indicates start production. */");
      cout.WriteLine("  public override int start_production() {return " + 
		     start_production.index() + ";}");
      cout.WriteLine();

      /* methods to indicate EOF and error symbol indexes */
      cout.WriteLine("  /** <code>EOF</code> Symbol index. */");
      cout.WriteLine("  public override int EOF_sym() {return " + terminal.EOF.index() + 
					  ";}");
      cout.WriteLine();
      cout.WriteLine("  /** <code>error</code> Symbol index. */");
      cout.WriteLine("  public override int error_sym() {return " + terminal.error.index() +
					  ";}");
      cout.WriteLine();

      /* user supplied code for user_init() */
      if (init_code != null)
	{
          cout.WriteLine();
	  cout.WriteLine("  /** User initialization code. */");
	  cout.WriteLine("  public override void user_init() ");
	  cout.WriteLine("    {");
	  cout.WriteLine(init_code);
	  cout.WriteLine("    }");
	}

      /* user supplied code for scan */
      if (scan_code != null)
	{
          cout.WriteLine();
	  cout.WriteLine("  /** Scan to get the next Symbol. */");
	  cout.WriteLine("  public override TUVienna.CS_CUP.Runtime.Symbol scan()");
	  cout.WriteLine("    {");
	  cout.WriteLine(scan_code);
	  cout.WriteLine("    }");
	}

      /* user supplied code */
      if (parser_code != null)
	{
	  cout.WriteLine();
          cout.WriteLine(parser_code);
	}

      /* end of class */
      cout.WriteLine("}");

      /* put out the action code class */
      emit_action_code(cout, start_prod);
      if (package_name!=null)
            cout.WriteLine("}");
      parser_time = DateTime.Now.Ticks - start_time;
    }
Exemplo n.º 3
0
  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** 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(
    TextWriter        cout, 
    parse_action_table act_tab,
    bool            compact_reduces)

    {
      parse_action_row row;
      parse_action     act;
      int              red;

      long start_time = DateTime.Now.Ticks;

      /* collect values for the action table */
      short[][] action_table = new short[act_tab.num_states()][];
      /* 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;

	  /* make temporary table for the row. */
	  short[] temp_table = new short[2*parse_action_row.size()];
	  int nentries = 0;

	  /* do each column */
	  for (int j = 0; j < parse_action_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)
		    {
		      /* make entry */
		      temp_table[nentries++] = (short) j;
		      temp_table[nentries++] = (short)
			(((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) {
			/* make entry */
			temp_table[nentries++] = (short) j;
			temp_table[nentries++] = (short) (-(red+1));
		      }
		    } else if (act.kind() == parse_action.NONASSOC)
		      {
			/* do nothing, since we just want a syntax error */
		      }
		  /* shouldn't be anything else */
		  else
		    throw new internal_error("Unrecognized action code " + 
					     act.kind() + " found in parse table");
		}
	    }

	  /* now we know how big to make the row */
	  action_table[i] = new short[nentries + 2];

	  //System.arraycopy(temp_table, 0, action_table[i], 0, nentries);
		Array.Copy(temp_table,action_table[i],nentries);

	  /* finish off the row with a default entry */
	  action_table[i][nentries++] = -1;
	  if (row.default_reduce != -1)
	    action_table[i][nentries++] = (short) (-(row.default_reduce+1));
	  else
	    action_table[i][nentries++] = 0;
	}

      /* finish off the init of the table */
      cout.WriteLine();
      cout.WriteLine("  /** Parse-action table. */");
      cout.WriteLine("  protected static readonly short[][] _action_table = "); 
      cout.Write  ("    unpackFromStrings(");
      do_table_as_string(cout, action_table);
      cout.WriteLine(");");

      /* do the public accessor method */
      cout.WriteLine();
      cout.WriteLine("  /** Access to parse-action table. */");
      cout.WriteLine("  public override short[][] action_table() {return _action_table;}");

      action_table_time = DateTime.Now.Ticks - start_time;
    }
Exemplo n.º 4
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

        /** 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?
         * @param suppress_scanner should scanner be suppressed for compatibility?
         */

        public static void parser(
            TextWriter cout,
            parse_action_table action_table,
            parse_reduce_table reduce_table,
            int start_st,
            production start_prod,
            bool compact_reduces,
            bool suppress_scanner)

        {
            long start_time = DateTime.Now.Ticks;

            /* top of file */
            cout.WriteLine();
            cout.WriteLine("//----------------------------------------------------");
            cout.WriteLine("// The following code was generated by " +
                           version.title_str);
            cout.WriteLine("// " + DateTime.Now);
            cout.WriteLine("//----------------------------------------------------");
            cout.WriteLine();
            emit_package(cout);

            /* user supplied imports */
            IEnumerator myEnum = import_list.GetEnumerator();

            while (myEnum.MoveNext())
            {
                cout.WriteLine("using " + myEnum.Current.ToString() + ";");
            }

            /* class header */
            cout.WriteLine();
            cout.WriteLine("/** " + version.title_str + " generated parser.");
            cout.WriteLine("  * @version " + DateTime.Now);
            cout.WriteLine("  */");
            cout.WriteLine("public class " + parser_class_name +
                           " : TUVienna.CS_CUP.Runtime.lr_parser {");

            /* constructors [CSA/davidm, 24-jul-99] */
            cout.WriteLine();
            cout.WriteLine("  /** Default constructor. */");
            cout.WriteLine("  public " + parser_class_name + "():base() {;}");
            if (!suppress_scanner)
            {
                cout.WriteLine();
                cout.WriteLine("  /** Constructor which sets the default scanner. */");
                cout.WriteLine("  public " + parser_class_name +
                               "(TUVienna.CS_CUP.Runtime.Scanner s): base(s) {;}");
            }

            /* emit the various tables */
            emit_production_table(cout);
            do_action_table(cout, action_table, compact_reduces);
            do_reduce_table(cout, reduce_table);

            /* instance of the action encapsulation class */
            cout.WriteLine("  /** Instance of action encapsulation class. */");
            cout.WriteLine("  protected " + pre("actions") + " action_obj;");
            cout.WriteLine();

            /* action object initializer */
            cout.WriteLine("  /** Action encapsulation object initializer. */");
            cout.WriteLine("  protected override void init_actions()");
            cout.WriteLine("    {");
            cout.WriteLine("      action_obj = new " + pre("actions") + "(this);");
            cout.WriteLine("    }");
            cout.WriteLine();

            /* access to action code */
            cout.WriteLine("  /** Invoke a user supplied parse action. */");
            cout.WriteLine("  public override TUVienna.CS_CUP.Runtime.Symbol do_action(");
            cout.WriteLine("    int                        act_num,");
            cout.WriteLine("    TUVienna.CS_CUP.Runtime.lr_parser parser,");
            cout.WriteLine("    System.Collections.Stack            xstack1,");
            cout.WriteLine("    int                        top)");
            cout.WriteLine("  {");
            cout.WriteLine("  mStack CUP_parser_stack= new mStack(xstack1);");
            cout.WriteLine("    /* call code in generated class */");
            cout.WriteLine("    return action_obj." + pre("do_action(") +
                           "act_num, parser, stack, top);");
            cout.WriteLine("  }");
            cout.WriteLine("");


            /* method to tell the parser about the start state */
            cout.WriteLine("  /** Indicates start state. */");
            cout.WriteLine("  public override int start_state() {return " + start_st + ";}");

            /* method to indicate start production */
            cout.WriteLine("  /** Indicates start production. */");
            cout.WriteLine("  public override int start_production() {return " +
                           start_production.index() + ";}");
            cout.WriteLine();

            /* methods to indicate EOF and error symbol indexes */
            cout.WriteLine("  /** <code>EOF</code> Symbol index. */");
            cout.WriteLine("  public override int EOF_sym() {return " + terminal.EOF.index() +
                           ";}");
            cout.WriteLine();
            cout.WriteLine("  /** <code>error</code> Symbol index. */");
            cout.WriteLine("  public override int error_sym() {return " + terminal.error.index() +
                           ";}");
            cout.WriteLine();

            /* user supplied code for user_init() */
            if (init_code != null)
            {
                cout.WriteLine();
                cout.WriteLine("  /** User initialization code. */");
                cout.WriteLine("  public override void user_init() ");
                cout.WriteLine("    {");
                cout.WriteLine(init_code);
                cout.WriteLine("    }");
            }

            /* user supplied code for scan */
            if (scan_code != null)
            {
                cout.WriteLine();
                cout.WriteLine("  /** Scan to get the next Symbol. */");
                cout.WriteLine("  public override TUVienna.CS_CUP.Runtime.Symbol scan()");
                cout.WriteLine("    {");
                cout.WriteLine(scan_code);
                cout.WriteLine("    }");
            }

            /* user supplied code */
            if (parser_code != null)
            {
                cout.WriteLine();
                cout.WriteLine(parser_code);
            }

            /* end of class */
            cout.WriteLine("}");

            /* put out the action code class */
            emit_action_code(cout, start_prod);
            if (package_name != null)
            {
                cout.WriteLine("}");
            }
            parser_time = DateTime.Now.Ticks - start_time;
        }
Exemplo n.º 5
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

        /** 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(
            TextWriter cout,
            parse_action_table act_tab,
            bool compact_reduces)

        {
            parse_action_row row;
            parse_action     act;
            int red;

            long start_time = DateTime.Now.Ticks;

            /* collect values for the action table */
            short[][] action_table = new short[act_tab.num_states()][];
            /* 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;
                }

                /* make temporary table for the row. */
                short[] temp_table = new short[2 * parse_action_row.size()];
                int     nentries   = 0;

                /* do each column */
                for (int j = 0; j < parse_action_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)
                        {
                            /* make entry */
                            temp_table[nentries++] = (short)j;
                            temp_table[nentries++] = (short)
                                                     (((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)
                            {
                                /* make entry */
                                temp_table[nentries++] = (short)j;
                                temp_table[nentries++] = (short)(-(red + 1));
                            }
                        }
                        else if (act.kind() == parse_action.NONASSOC)
                        {
                            /* do nothing, since we just want a syntax error */
                        }
                        /* shouldn't be anything else */
                        else
                        {
                            throw new internal_error("Unrecognized action code " +
                                                     act.kind() + " found in parse table");
                        }
                    }
                }

                /* now we know how big to make the row */
                action_table[i] = new short[nentries + 2];

                //System.arraycopy(temp_table, 0, action_table[i], 0, nentries);
                Array.Copy(temp_table, action_table[i], nentries);

                /* finish off the row with a default entry */
                action_table[i][nentries++] = -1;
                if (row.default_reduce != -1)
                {
                    action_table[i][nentries++] = (short)(-(row.default_reduce + 1));
                }
                else
                {
                    action_table[i][nentries++] = 0;
                }
            }

            /* finish off the init of the table */
            cout.WriteLine();
            cout.WriteLine("  /** Parse-action table. */");
            cout.WriteLine("  protected static readonly short[][] _action_table = ");
            cout.Write("    unpackFromStrings(");
            do_table_as_string(cout, action_table);
            cout.WriteLine(");");

            /* do the public accessor method */
            cout.WriteLine();
            cout.WriteLine("  /** Access to parse-action table. */");
            cout.WriteLine("  public override short[][] action_table() {return _action_table;}");

            action_table_time = DateTime.Now.Ticks - start_time;
        }
Exemplo n.º 6
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

        /** 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)

        {
            parse_action_row our_act_row;
            parse_reduce_row our_red_row;
            lalr_item        itm;
            parse_action     act, other_act;
            symbol           sym;
            terminal_set     conflict_set = new terminal_set();

            /* 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 */
            IEnumerator i = items().all();

            while (i.MoveNext())
            {
                itm = (lalr_item)i.Current;


                /* 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 */
                            terminal term = terminal.find(t);
                            other_act = our_act_row.under_term[t];

                            /* if the other act was not a shift */
                            if ((other_act.kind() != parse_action.SHIFT) &&
                                (other_act.kind() != parse_action.NONASSOC))
                            {
                                /* 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;
                                }
                            }
                            else
                            {
                                /*  Check precedences,see if problem is correctable */
                                if (fix_with_precedence(itm.the_production(),
                                                        t, our_act_row, act))
                                {
                                    term = null;
                                }
                            }
                            if (term != null)
                            {
                                conflict_set.add(term);
                            }
                        }
                    }
                }
            }

            /* 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 */
                        production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with();

                        /* shift always wins */
                        if (!fix_with_precedence(p, sym.index(), our_act_row, act))
                        {
                            our_act_row.under_term[sym.index()] = act;
                            conflict_set.add(terminal.find(sym.index()));
                        }
                    }
                }
                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 (!conflict_set.empty())
            {
                report_conflicts(conflict_set);
            }
        }
Exemplo n.º 7
0
		/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

		/** 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() 
		{
			/* compute nullability of all non terminals */
			if (opt_do_debug || print_progress) 
				System.Console.Error.WriteLine("  Computing non-terminal nullability...");
			non_terminal.compute_nullability();

			nullability_end = DateTime.Now.Ticks;

			/* compute first sets of all non terminals */
			if (opt_do_debug || print_progress) 
				System.Console.Error.WriteLine("  Computing first sets...");
			non_terminal.compute_first_sets();

			first_end = DateTime.Now.Ticks;

			/* build the LR viable prefix recognition machine */
			if (opt_do_debug || print_progress) 
				System.Console.Error.WriteLine("  Building state machine...");
			start_state = lalr_state.build_machine(emit.start_production);

			machine_end = DateTime.Now.Ticks;

			/* build the LR parser action and reduce-goto tables */
			if (opt_do_debug || print_progress) 
				System.Console.Error.WriteLine("  Filling in tables...");
			action_table = new parse_action_table();
			reduce_table = new parse_reduce_table();
			IEnumerator st = lalr_state.all();
			while ( st.MoveNext() )
			{
				lalr_state lst = (lalr_state)st.Current;
				lst.build_table_entries(
					action_table, reduce_table);
			}

			table_end = DateTime.Now.Ticks;

			/* check and warn for non-reduced productions */
			if (opt_do_debug || print_progress) 
				System.Console.Error.WriteLine("  Checking for non-reduced productions...");
			action_table.check_reductions();

			reduce_check_end = DateTime.Now.Ticks;

			/* if we have more conflicts than we expected issue a message and die */
			if (emit.num_conflicts > expect_conflicts)
			{
				System.Console.Error.WriteLine("*** More conflicts encountered than expected " +
					"-- parser generation aborted");
				lexer.error_count++; // indicate the problem.
				// we'll die on return, after clean up.
			}
		}
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /** 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)
        {
            parse_action_row our_act_row;
              parse_reduce_row our_red_row;
              lalr_item        itm;
              parse_action     act, other_act;
              symbol           sym;
              terminal_set     conflict_set = new terminal_set();

              /* 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 */
              IEnumerator i = items().all();
              while ( i.MoveNext() )
            {
              itm = (lalr_item)i.Current;

              /* 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 */
              terminal term = terminal.find(t);
              other_act = our_act_row.under_term[t];

              /* if the other act was not a shift */
              if ((other_act.kind() != parse_action.SHIFT) &&
              (other_act.kind() != parse_action.NONASSOC))
                {
                /* 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;
                }
                } else {
              /*  Check precedences,see if problem is correctable */
              if(fix_with_precedence(itm.the_production(),
                         t, our_act_row, act)) {
                term = null;
              }
            }
              if(term!=null) {

            conflict_set.add(term);
              }
            }
            }
            }
            }

              /* 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 */
              production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with();

              /* shift always wins */
              if (!fix_with_precedence(p, sym.index(), our_act_row, act)) {
            our_act_row.under_term[sym.index()] = act;
            conflict_set.add(terminal.find(sym.index()));
              }
            }
            }
              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 (!conflict_set.empty())
            report_conflicts(conflict_set);
        }