/*-----------------------------------------------------------*/ /*--- Constructor(s) ----------------------------------------*/ /*-----------------------------------------------------------*/ /// <summary>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. /// </summary> 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) ----------------------------------------*/ /*-----------------------------------------------------------*/ /// <summary>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. /// </summary> 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(); } }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>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. /// * /// </summary> /// <param name="p"> the production /// </param> /// <param name="term_index"> the index of the lokahead terminal /// </param> /// <param name="parse_action_row"> a row of the action table /// </param> /// <param name="act"> the rule in conflict with the table entry /// /// </param> protected internal virtual 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; } 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; } else if (term.precedence_side() == assoc.left) { table_row.under_term[term_index] = insert_reduce(table_row.under_term[term_index], act); return true; } 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"); } } } 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; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>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. /// * /// </summary> /// <param name="p"> the production /// </param> /// <param name="term_index"> the index of the lokahead terminal /// </param> /// <param name="parse_action_row"> a row of the action table /// </param> /// <param name="act"> the rule in conflict with the table entry /// /// </param> protected internal virtual 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); } 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); } else if (term.precedence_side() == assoc.left) { table_row.under_term[term_index] = insert_reduce(table_row.under_term[term_index], act); return(true); } 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"); } } } 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); }