def _build_parsing_table(self):
        G = self.G.AugmentedGrammar(True)
        automaton = build_LR1_automaton(G)
        centers = {}

        for i, node in enumerate(automaton):
            node.idx = i
            try:
                same_center = centers[node_centers(node)]
                centers[node_centers(node)] = State(
                    compress(node.state.union(same_center.state)), True)
            except KeyError:
                centers[node_centers(node)] = node
            centers[node_centers(node)].idx = i

        self.automaton = automaton
        self.centers = centers

        Goto = {}
        firsts = compute_firsts(G)
        firsts[G.EOF] = ContainerSet(G.EOF)
        for node in centers.values():
            for symbol in G.terminals + G.nonTerminals:
                temp = goto_lr1(node.state, symbol, firsts)
                if not temp:
                    continue
                Goto[(node.idx,
                      symbol)] = centers[node_centers(State(temp, True))]

        for node in centers.values():
            idx = node.idx
            for item in node.state:
                # Your code here!!!
                # - Fill `self.Action` and `self.Goto` according to `item`)
                # - Feel free to use `self._register(...)`)
                if item.IsReduceItem:
                    production = item.production
                    if production.Left == G.startSymbol:
                        self._register(self.action, (idx, G.EOF), ("OK", None))
                    else:
                        for lookahead in item.lookaheads:
                            self._register(self.action, (idx, lookahead),
                                           ("REDUCE", production))
                else:
                    next_symbol = item.NextSymbol
                    if next_symbol.IsTerminal:
                        self._register(
                            self.action, (idx, next_symbol),
                            ("SHIFT", Goto[(node.idx, next_symbol)].idx))
                    else:
                        self._register(self.goto, (idx, next_symbol),
                                       Goto[(node.idx, next_symbol)].idx)
Example #2
0
def state_transpose(initial_state: State):
    """
    returns the state equivalent to initial_state on the transpose graph and a dictionary mapping idx to new states transposed
    """
    state_dict = {
    }  # state_dict[key] = (original_state,copy_of_original_state_with_transposed_transitions)
    idx = 0
    for x in initial_state:
        new_state = State(x.state, x.final, x.formatter, x.shape)
        if not hasattr(x, 'idx'):
            x.idx = idx
            idx += 1
        new_state.idx = x.idx
        state_dict[x.idx] = (x, new_state)

    for x in initial_state:
        for key, states in x.transitions.items():
            for state in states:
                state_dict[state.idx][1].add_transition(
                    key, state_dict[x.idx][1])

    return state_dict[initial_state.idx][1], state_dict