コード例 #1
0
def populate_action_table_from_state(grammar, state_set, action_table,
                                     handle_shift_reduce, to_id):
    '''Builds the Action table.'''
    for item in state_set:
        next_symbol = item.next_symbol(grammar)
        if item.sym_production == grammar.START and item.position == 1:
            #Item is S' -> S*
            action = Driver.Accept()
            if grammar.EOF in action_table[to_id[state_set]] and \
                  action != action_table[to_id[state_set]][grammar.EndOfSource]:
                raise KeyError(grammar.EOF)

            action_table[to_id[state_set]][grammar.EOF] = action

        elif next_symbol and not grammar.is_a_nonterminal(next_symbol):
            #Item is A -> a*bc
            assert not grammar.is_empty(next_symbol)
            goto_state_hash = to_id[goto(state_set, next_symbol, grammar)]
            action = Driver.Shift(
                goto_state_hash, item.sym_production,
                grammar[item.sym_production][item.alternative])

            if next_symbol in action_table[to_id[state_set]] and \
                  action != action_table[to_id[state_set]][next_symbol]:
                action = handler_conflict(
                    action, action_table[to_id[state_set]][next_symbol],
                    next_symbol, handle_shift_reduce)

            action_table[to_id[state_set]][next_symbol] = action

        elif not next_symbol:  #Item is A -> abc*
            for terminal in item.followers(grammar):
                semantic_definition = grammar.semantic_definition(
                    item.sym_production, item.alternative)
                action = Driver.Reduce(
                    item.sym_production,
                    grammar[item.sym_production][item.alternative],
                    semantic_definition,
                    grammar.is_empty_rule(
                        (grammar[item.sym_production][item.alternative])))
                if terminal in action_table[to_id[state_set]] and \
                      action != action_table[to_id[state_set]][terminal]:
                    action = handler_conflict(
                        action, action_table[to_id[state_set]][terminal],
                        terminal, handle_shift_reduce)

                action_table[to_id[state_set]][terminal] = action