/*-----------------------------------------------------------*/
        /*--- 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();
        }
        /*-----------------------------------------------------------*/
        /*--- 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();
            }
        }
Exemplo n.º 3
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/


        /** Procedure that attempts to fix a shift/reduce error by using
         * precedences.  --frankf 6/26/96
         *
         *  if a production (also called rule) or the lookahead terminal
         *  has a precedence, then the table can be fixed.  if the rule
         *  has greater precedence than the terminal, a reduce by that rule
         *  in inserted in the table.  If the terminal has a higher precedence,
         *  it is shifted.  if they have equal precedence, then the associativity
         *  of the precedence is used to determine what to put in the table:
         *  if the precedence is left associative, the action is to reduce.
         *  if the precedence is right associative, the action is to shift.
         *  if the precedence is non associative, then it is a syntax error.
         *
         *  @param p           the production
         *  @param term_index  the index of the lokahead terminal
         *  @param parse_action_row  a row of the action table
         *  @param act         the rule in conflict with the table entry
         */

        protected bool fix_with_precedence(
            production p,
            int term_index,
            parse_action_row table_row,
            parse_action act)

        {
            terminal term = terminal.find(term_index);

            /* if the production has a precedence number, it can be fixed */
            if (p.precedence_num() > assoc.no_prec)
            {
                /* if production precedes terminal, put reduce in table */
                if (p.precedence_num() > term.precedence_num())
                {
                    table_row.under_term[term_index] =
                        insert_reduce(table_row.under_term[term_index], act);
                    return(true);
                }

                /* if terminal precedes rule, put shift in table */
                else if (p.precedence_num() < term.precedence_num())
                {
                    table_row.under_term[term_index] =
                        insert_shift(table_row.under_term[term_index], act);
                    return(true);
                }
                else /* they are == precedence */

                /* equal precedences have equal sides, so only need to
                 * look at one: if it is right, put shift in table */
                {
                    if (term.precedence_side() == assoc.right)
                    {
                        table_row.under_term[term_index] =
                            insert_shift(table_row.under_term[term_index], act);
                        return(true);
                    }

                    /* if it is left, put reduce in table */
                    else if (term.precedence_side() == assoc.left)
                    {
                        table_row.under_term[term_index] =
                            insert_reduce(table_row.under_term[term_index], act);
                        return(true);
                    }

                    /* if it is nonassoc, we're not allowed to have two nonassocs
                     * of equal precedence in a row, so put in NONASSOC */
                    else if (term.precedence_side() == assoc.nonassoc)
                    {
                        table_row.under_term[term_index] = new nonassoc_action();
                        return(true);
                    }
                    else
                    {
                        /* something really went wrong */
                        throw new internal_error("Unable to resolve conflict correctly");
                    }
                }
            }

            /* check if terminal has precedence, if so, shift, since
             * rule does not have precedence */
            else if (term.precedence_num() > assoc.no_prec)
            {
                table_row.under_term[term_index] =
                    insert_shift(table_row.under_term[term_index], act);
                return(true);
            }

            /* otherwise, neither the rule nor the terminal has a precedence,
             * so it can't be fixed. */
            return(false);
        }
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /** Procedure that attempts to fix a shift/reduce error by using
           * precedences.  --frankf 6/26/96
           *
           *  if a production (also called rule) or the lookahead terminal
           *  has a precedence, then the table can be fixed.  if the rule
           *  has greater precedence than the terminal, a reduce by that rule
           *  in inserted in the table.  If the terminal has a higher precedence,
           *  it is shifted.  if they have equal precedence, then the associativity
           *  of the precedence is used to determine what to put in the table:
           *  if the precedence is left associative, the action is to reduce.
           *  if the precedence is right associative, the action is to shift.
           *  if the precedence is non associative, then it is a syntax error.
           *
           *  @param p           the production
           *  @param term_index  the index of the lokahead terminal
           *  @param parse_action_row  a row of the action table
           *  @param act         the rule in conflict with the table entry
           */
        protected bool fix_with_precedence(
		        production       p,
			int              term_index,
			parse_action_row table_row,
			parse_action     act)
        {
            terminal term = terminal.find(term_index);

              /* if the production has a precedence number, it can be fixed */
              if (p.precedence_num() > assoc.no_prec) {

            /* if production precedes terminal, put reduce in table */
            if (p.precedence_num() > term.precedence_num()) {
              table_row.under_term[term_index] =
            insert_reduce(table_row.under_term[term_index],act);
              return true;
            }

            /* if terminal precedes rule, put shift in table */
            else if (p.precedence_num() < term.precedence_num()) {
              table_row.under_term[term_index] =
            insert_shift(table_row.under_term[term_index],act);
              return true;
            }
            else {  /* they are == precedence */

              /* equal precedences have equal sides, so only need to
             look at one: if it is right, put shift in table */
              if (term.precedence_side() == assoc.right) {
              table_row.under_term[term_index] =
            insert_shift(table_row.under_term[term_index],act);
            return true;
              }

              /* if it is left, put reduce in table */
              else if (term.precedence_side() == assoc.left) {
            table_row.under_term[term_index] =
              insert_reduce(table_row.under_term[term_index],act);
            return true;
              }

              /* if it is nonassoc, we're not allowed to have two nonassocs
             of equal precedence in a row, so put in NONASSOC */
              else if (term.precedence_side() == assoc.nonassoc) {
            table_row.under_term[term_index] = new nonassoc_action();
            return true;
              } else {
            /* something really went wrong */
            throw new internal_error("Unable to resolve conflict correctly");
              }
            }
              }
              /* check if terminal has precedence, if so, shift, since
             rule does not have precedence */
              else if (term.precedence_num() > assoc.no_prec) {
             table_row.under_term[term_index] =
               insert_shift(table_row.under_term[term_index],act);
             return true;
              }

              /* otherwise, neither the rule nor the terminal has a precedence,
             so it can't be fixed. */
              return false;
        }