示例#1
0
        /*-----------------------------------------------------------*/
        /*--- 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)

        {
            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;
        }
示例#2
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.
            }
        }
示例#3
0
        /*-----------------------------------------------------------*/
        /*--- Static Methods ----------------------------------------*/
        /*-----------------------------------------------------------*/

        /** Helper routine for debugging -- produces a dump of the given state
         * onto System.out.
         */
        protected static void dump_state(lalr_state st)
        {
            lalr_item_set   itms;
            lalr_item       itm;
            production_part part;

            if (st == null)
            {
                Console.WriteLine("NULL lalr_state");
                return;
            }

            Console.WriteLine("lalr_state [" + st.index() + "] {");
            itms = st.items();
            IEnumerator e = itms.all();

            while (e.MoveNext())
            {
                itm = (lalr_item)e.Current;
                Console.Write("  [");
                Console.Write(itm.the_production().lhs().the_symbol().name());
                Console.Write(" ::= ");
                for (int i = 0; i < itm.the_production().rhs_length(); i++)
                {
                    if (i == itm.dot_pos())
                    {
                        Console.Write("(*) ");
                    }
                    part = itm.the_production().rhs(i);
                    if (part.is_action())
                    {
                        Console.Write("{action} ");
                    }
                    else
                    {
                        Console.Write(((symbol_part)part).the_symbol().name() + " ");
                    }
                }
                if (itm.dot_at_end())
                {
                    Console.Write("(*) ");
                }
                Console.WriteLine("]");
            }
            Console.WriteLine("}");
        }
示例#4
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /** 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 */
                IEnumerator s = lalr_state.all();
                while ( s.MoveNext() )
                {
                    lalr_state st = (lalr_state)s.Current;
                    ordered[st.index()] = st;
                }

            System.Console.Error.WriteLine("===== Viable Prefix Recognizer =====");
            for (int i = 0; i<lalr_state.number(); i++)
            {
                if (ordered[i] == start_state) System.Console.Error.Write("START ");
                System.Console.Error.WriteLine(ordered[i]);
                System.Console.Error.WriteLine("-------------------");
            }
        }
示例#5
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

        /** Equality comparison. */
        public bool Equals(lalr_state other)
        {
            /* we are equal if our item sets are equal */
            return(other != null && items().Equals(other.items()));
        }
示例#6
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

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

        {
            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;
            IEnumerator   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.Add(kernel, start_state);

            /* continue looking at new states until we have no more work to do */
            while (work_stack.Count != 0)
            {
                /* 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();
                i        = st.items().all();
                while (i.MoveNext())
                {
                    itm = (lalr_item)i.Current;

                    /* 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 */
                s = outgoing.all();
                while (s.MoveNext())
                {
                    sym = (symbol)s.Current;

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

                        /* 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[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.Add(kernel, new_st);
                    }
                    /* otherwise relink propagation to items in existing state */
                    else
                    {
                        /* walk through the items that have links to the new state */
                        fix = linked_items.all();
                        while (fix.MoveNext())
                        {
                            fix_itm = (lalr_item)fix.Current;

                            /* look at each propagate link out of that item */

                            for (int l = 0; l < fix_itm.propagate_items().Count; l++)
                            {
                                /* pull out item linked to in the new state */
                                new_itm = (lalr_item)fix_itm.propagate_items().ToArray()[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.set_propagate_item(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);
        }
示例#7
0
		/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

		/** 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 */
				IEnumerator s = lalr_state.all();
				while ( s.MoveNext() )
				{
					lalr_state st = (lalr_state)s.Current;
					ordered[st.index()] = st;
				}

			System.Console.Error.WriteLine("===== Viable Prefix Recognizer =====");
			for (int i = 0; i<lalr_state.number(); i++)
			{
				if (ordered[i] == start_state) System.Console.Error.Write("START ");
				System.Console.Error.WriteLine(ordered[i]);
				System.Console.Error.WriteLine("-------------------");
			}
		}
示例#8
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.
			}
		}
        /*-----------------------------------------------------------*/
        /*--- Static Methods ----------------------------------------*/
        /*-----------------------------------------------------------*/
        /** Helper routine for debugging -- produces a dump of the given state
        * onto System.out.
        */
        protected static void dump_state(lalr_state st)
        {
            lalr_item_set itms;
              lalr_item itm;
              production_part part;

              if (st == null)
            {
              Console.WriteLine("NULL lalr_state");
              return;
            }

              Console.WriteLine("lalr_state [" + st.index() + "] {");
              itms = st.items();
              IEnumerator e = itms.all();
              while ( e.MoveNext() )
            {
              itm = (lalr_item)e.Current;
              Console.Write("  [");
              Console.Write(itm.the_production().lhs().the_symbol().name());
              Console.Write(" ::= ");
              for (int i = 0; i<itm.the_production().rhs_length(); i++)
            {
              if (i == itm.dot_pos()) Console.Write("(*) ");
              part = itm.the_production().rhs(i);
              if (part.is_action())
            Console.Write("{action} ");
              else
            Console.Write(((symbol_part)part).the_symbol().name() + " ");
            }
              if (itm.dot_at_end()) Console.Write("(*) ");
              Console.WriteLine("]");
            }
              Console.WriteLine("}");
        }
 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 /** Equality comparison. */
 public bool Equals(lalr_state other)
 {
     /* we are equal if our item sets are equal */
       return other != null && items().Equals(other.items());
 }
        /*-----------------------------------------------------------*/
        /*--- 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)
        {
            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)
        {
            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;
              IEnumerator   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.Add(kernel, start_state);

              /* continue looking at new states until we have no more work to do */
              while (work_stack.Count!=0)
            {
              /* 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();
              i = st.items().all();
              while ( i.MoveNext() )
            {
              itm = (lalr_item)i.Current;

              /* 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 */
              s = outgoing.all();
              while ( s.MoveNext())
            {
              sym = (symbol)s.Current;

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

              /* 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[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.Add(kernel, new_st);
            }
              /* otherwise relink propagation to items in existing state */
              else
            {
              /* walk through the items that have links to the new state */
              fix = linked_items.all();
              while ( fix.MoveNext() )
            {
              fix_itm = (lalr_item)fix.Current;

              /* look at each propagate link out of that item */

              for (int l =0; l < fix_itm.propagate_items().Count; l++)
            {
              /* pull out item linked to in the new state */
              new_itm =(lalr_item) fix_itm.propagate_items().ToArray()[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.set_propagate_item(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;
        }