예제 #1
0
        /* find the reduce in the two actions */
        protected parse_action insert_reduce(
            parse_action a1,
            parse_action a2)

        {
            return(insert_action(a1, a2, parse_action.REDUCE));
        }
예제 #2
0
        /* find the shift in the two actions */
        protected parse_action insert_shift(
            parse_action a1,
            parse_action a2)

        {
            return(insert_action(a1, a2, parse_action.SHIFT));
        }
예제 #3
0
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/


        /*  given two actions, and an action type, return the
         *  action of that action type.  give an error if they are of
         *  the same action, because that should never have tried
         *  to be fixed
         *
         */
        protected parse_action insert_action(
            parse_action a1,
            parse_action a2,
            int act_type)

        {
            if ((a1.kind() == act_type) && (a2.kind() == act_type))
            {
                throw new internal_error("Conflict resolution of bogus actions");
            }
            else if (a1.kind() == act_type)
            {
                return(a1);
            }
            else if (a2.kind() == act_type)
            {
                return(a2);
            }
            else
            {
                throw new internal_error("Conflict resolution of bogus actions");
            }
        }
예제 #4
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);
        }
        /* find the shift in the two actions */
        protected parse_action insert_shift(
					parse_action a1,
					parse_action a2)
        {
            return insert_action(a1, a2, parse_action.SHIFT);
        }
        /* find the reduce in the two actions */
        protected parse_action insert_reduce(
					parse_action a1,
					parse_action a2)
        {
            return insert_action(a1, a2, parse_action.REDUCE);
        }
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /*  given two actions, and an action type, return the
          action of that action type.  give an error if they are of
          the same action, because that should never have tried
          to be fixed

          */
        protected parse_action insert_action(
					parse_action a1,
					parse_action a2,
					int act_type)
        {
            if ((a1.kind() == act_type) && (a2.kind() == act_type)) {
            throw new internal_error("Conflict resolution of bogus actions");
              } else if (a1.kind() == act_type) {
            return a1;
              } else if (a2.kind() == act_type) {
            return a2;
              } else {
            throw new internal_error("Conflict resolution of bogus actions");
              }
        }
        /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
        /** 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;
        }