Beispiel #1
0
    def build_LR1_automaton(self, G):
        assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'
        
        firsts = compute_firsts(G)
        firsts[G.EOF] = ContainerSet(G.EOF)
        
        start_production = G.startSymbol.productions[0]
        start_item = Item(start_production, 0, lookaheads=(G.EOF,))
        start = frozenset([start_item])
        
        closure = self.closure_lr1(start, firsts)
        automaton = State(frozenset(closure), True)
        
        pending = [ start ]
        visited = { start: automaton }
        
        while pending:
            current = pending.pop()
            current_state = visited[current]
            for symbol in G.terminals + G.nonTerminals:
                closure_current = self.closure_lr1(current, firsts)
                goto = self.goto_lr1(closure_current, symbol, just_kernel=True)
                if len(goto) == 0:
                    continue
                try:
                    next_state = visited[goto]
                except KeyError:
                    next_closure = self.closure_lr1(goto, firsts)
                    visited[goto] = next_state = State(frozenset(next_closure), True)
                    pending.append(goto)

                current_state.add_transition(symbol.Name, next_state)
        
        automaton.set_formatter(multiline_formatter)
        return automaton
Beispiel #2
0
def build_LR0_automaton(G: Grammar):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        current_state = visited[current_item]
        next_symbol = current_item.NextSymbol
        next_item = current_item.NextItem()

        #- $(X --> a.cB) ---c---> (X --> ac.B)  con c in V_T
        #- $(X --> a.YB) ---Y---> (X --> aY.B)  con Y in V_N
        next_state = get_state(visited, pending, next_item)
        current_state.add_transition(next_symbol.Name, next_state)

        if next_symbol in G.nonTerminals:
            sym_productions = G.symbDict[next_symbol.Name].productions
            #- $(X --> a.YB) ---e---> (Y --> .Z)  con Y in V_N
            for pr in [Item(x, 0) for x in sym_productions]:
                trans_state = get_state(visited, pending, pr)
                current_state.add_epsilon_transition(trans_state)

    return automaton.to_deterministic(lr0_formatter)
def build_lr0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)
    start = frozenset([start_item])

    automaton = State(closure_lr0(start), True)

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]
        current_closure = current_state.state
        for symbol in G.terminals + G.nonTerminals:
            kernel = goto_lr0(current_closure, symbol)

            if kernel == frozenset():
                continue

            try:
                next_state = visited[kernel]
            except KeyError:
                next_state = visited[kernel] = State(closure_lr0(kernel), True)
                pending.append(kernel)

            current_state.add_transition(symbol.Name, next_state)
    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #4
0
 def _build_automaton(self):
     start = State('start')
     automatons = self.regexs
     for i in automatons:
         start.add_epsilon_transition(i)
     final = start.to_deterministic()
     return final
def build_LALR_automaton(G):
    assert len(G.startSymbol.productions) == 1, "Grammar must be augmented"

    lr1_automaton = build_LR1_automaton(G)

    same_kernel = {}
    for node in lr1_automaton:
        just_center = frozenset([item.Center() for item in node.state])
        try:
            same_kernel[just_center].append(node)
        except KeyError:
            same_kernel[just_center] = [node]

    start = frozenset([item.Center() for item in lr1_automaton.state
                       ])  # como cabecera solo quedan los items sin lookahead
    automaton = State(
        lr1_automaton.state, True
    )  # en visited se guarda el estado que corresponde a la fusion de estaods ocn el mismo nucleo

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]  # se van a actualizar
        # todos los estados con los que el estado actual tiene alguna transicion
        lr1_state = same_kernel[current][0]

        # chequear que cada estado del cjto analizado tenga esa transicion
        for symbol in G.terminals + G.nonTerminals:
            if lr1_state.has_transition(symbol.Name):
                state = lr1_state.transitions[symbol.Name][0]
                center_items = frozenset(
                    [item.Center() for item in state.state])
                try:
                    next_state = visited[center_items]
                except KeyError:
                    kernel_set = same_kernel[center_items]
                    items_with_lookahead = {}
                    for node in kernel_set:
                        for item in node.state:
                            try:
                                current_item = items_with_lookahead[
                                    item.Center()]
                            except KeyError:
                                current_item = items_with_lookahead[
                                    item.Center()] = set()
                            current_item.update(item.lookaheads)
                    completed_items = [
                        Item(item.production, item.pos, lookaheads)
                        for item, lookaheads in items_with_lookahead.items()
                    ]
                    next_state = State(frozenset(completed_items), True)
                    visited[center_items] = next_state
                    pending.append(center_items)

                current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #6
0
def DerivationTree(derivation, G):
    lent = len(derivation)

    nonTerminalstack = []
    root = State(G.startSymbol.Name)
    nonTerminalstack.append(root)

    while lent > 0:
        lent -= 1
        next_production = derivation[lent]
        print("next_production", next_production)
        currentNode = nonTerminalstack.pop()
        # assert currentNode.state == next_production.Left.Name, "Wrong derivation"

        if next_production.IsEpsilon:
            currentNode.add_transition(" ", State("epsilon", True))

        for symbol in next_production.Right:
            if symbol.IsTerminal:
                currentNode.add_transition(" ", State(symbol.Name, True))
            else:
                nonTerminalstack.append(State(symbol.Name))
                currentNode.add_transition(
                    " ", nonTerminalstack[len(nonTerminalstack) - 1])

    return root
def build_larl1_automaton(G, firsts=None):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    if not firsts:
        firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, lookaheads=ContainerSet(G.EOF))
    start = frozenset([start_item.Center()])

    closure = closure_lr1([start_item], firsts)
    automaton = State(frozenset(closure), True)

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]

        current_closure = current_state.state
        for symbol in G.terminals + G.nonTerminals:
            goto = goto_lr1(current_closure, symbol, just_kernel=True)
            closure = closure_lr1(goto, firsts)
            center = frozenset(item.Center() for item in goto)

            if center == frozenset():
                continue

            try:
                next_state = visited[center]
                centers = {item.Center(): item for item in next_state.state}
                centers = {
                    item.Center(): (centers[item.Center()], item)
                    for item in closure
                }

                updated_items = set()
                for c, (itemA, itemB) in centers.items():
                    item = Item(c.production, c.pos,
                                itemA.lookaheads | itemB.lookaheads)
                    updated_items.add(item)

                updated_items = frozenset(updated_items)
                if next_state.state != updated_items:
                    pending.append(center)
                next_state.state = updated_items
            except KeyError:
                visited[center] = next_state = State(frozenset(closure), True)
                pending.append(center)

            if current_state[symbol.Name] is None:
                current_state.add_transition(symbol.Name, next_state)
            else:
                assert current_state.get(
                    symbol.Name) is next_state, 'Bad build!!!'

    automaton.set_formatter(multiline_formatter)
    return automaton
    def _build_automaton(self):
        start = State('start')
        regexs = self.regexs

        for regex in regexs:
            start.add_epsilon_transition(regex)

        return start.to_deterministic()
    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)
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, "Grammar must be augmented"

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        # (Decide which transitions to add)
        # agregar las epsilon transiciones
        # a estados donde el item posee producciones a partir del simbolo actual en la posicion 0
        # y agregar la transicion a partir del simbolo siguiente

        next_item = current_item.NextItem()
        try:
            next_state = visited[next_item]
        except KeyError:
            next_state = State(next_item, True)
            visited[next_item] = next_state
            pending.append(next_item)

        if current_item.NextSymbol.IsNonTerminal:
            epsilon_productions = current_item.NextSymbol.productions
        else:
            epsilon_productions = None

        current_state = visited[current_item]
        # (Adding the decided transitions)
        current_state.add_transition(current_item.NextSymbol.Name, next_state)

        if epsilon_productions:
            for eproduction in epsilon_productions:
                epItem = Item(eproduction, 0)
                try:
                    epState = visited[epItem]
                except KeyError:
                    epState = State(epItem, True)
                    visited[epItem] = epState
                    pending.append(epItem)
                current_state.add_epsilon_transition(epState)

    return automaton
def build_LALR1_automaton(G):
    automaton = build_LR1_automaton(G)

    stKernel = {}
    for node in automaton:
        kernel = frozenset([item.Center() for item in node.state])
        try:
            stKernel[kernel].append(node)
        except KeyError:
            stKernel[kernel] = [node]

    initial = frozenset([item.Center() for item in automaton.state])
    automaton = State(automaton.state, True)

    visited = {initial: automaton}
    pending = [initial]

    while pending:
        current = pending.pop()
        current_state = visited[current]
        lr1_state = stKernel[current][0]

        for symbol in G.terminals + G.nonTerminals:
            if symbol.Name in lr1_state.transitions:
                dest_core = frozenset([
                    item.Center()
                    for item in lr1_state.transitions[symbol.Name][0].state
                ])

                try:
                    next_state = visited[dest_core]

                except KeyError:
                    union_core = {center: set() for center in dest_core}
                    for node in stKernel[dest_core]:
                        for item in node.state:
                            union_core[item.Center()].update(item.lookaheads)
                    union_core = frozenset([
                        Item(center.production,
                             center.pos,
                             lookaheads=lookaheads)
                        for center, lookaheads in union_core.items()
                    ])
                    next_state = State(union_core, True)
                    visited[dest_core] = next_state
                    pending.append(dest_core)
                current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #12
0
def get_state(visited, pending, item):
    if not item in visited.keys():
        new_state = State(item, True)
        pending.append(item)
        visited[item] = new_state
        return new_state
    return visited[item]
Beispiel #13
0
def build_lalr_automaton(G):
    def centers(items: [Item]):
        return frozenset(item.Center() for item in items)

    def lookaheads(items: [Item]):
        return {item.Center(): item.lookaheads for item in items}

    def subset(items1, items2):
        return all(items1[i] <= items2[i] for i in items1)

    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'
    firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, (G.EOF, ))

    start = State(frozenset(closure_lr1([start_item], firsts)), True)

    pending = [start_item]
    visisted_centers = {centers(start.state): start}
    visited = {start_item: start}

    while pending:
        current_state = visited[pending.pop()]
        for symbol in G.terminals + G.nonTerminals:
            next_item = frozenset(goto_lr1(current_state.state, symbol,
                                           firsts))

            if next_item:
                try:
                    next_state = visisted_centers[centers(next_item)]
                    if not subset(lookaheads(next_item),
                                  lookaheads(next_state.state)):
                        next_state.state = compress(
                            list(next_state.state) + list(next_item))
                        pending.append(frozenset(next_state.state))
                        visited[frozenset(next_state.state)] = next_state
                except KeyError:
                    next_state = State(next_item, True)
                    pending += [next_item]
                    visisted_centers[centers(next_item)] = next_state
                    visited[next_item] = next_state
                current_state.add_transition(symbol.Name, next_state)

    return start
Beispiel #14
0
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        # Your code here!!! (Decide which transitions to add)
        current_state = visited[current_item]
        next_symbol = current_item.NextSymbol
        next_item = current_item.NextItem()
        try:
            next_state = visited[next_item]
        except KeyError:
            next_state = State(next_item, True)
            visited[next_item] = next_state
        current_state.add_transition(next_symbol.Name, next_state)
        # print('Added trans:  ', current_state, f'==={next_symbol.Name}===>', next_state)
        pending.append(next_item)

        if next_symbol.IsNonTerminal:   # If symbol is non terminal, add e-productions to Y->.alpha
            for prod in next_symbol.productions:
                new_item = Item(prod, 0)
                try:
                    new_state = visited[new_item]
                    item_was_found = True
                except KeyError:
                    new_state = State(new_item, True)
                    visited[new_item] = new_state
                    item_was_found = False
                current_state.add_epsilon_transition(new_state)
                # print('Added e-trans:', current_state, '==>', new_state)
                if not item_was_found:
                    pending.append(new_item)

    return automaton
Beispiel #15
0
    def _build_regexs(self, table):
        regexs = []
        for n, (token_type, text_regex) in enumerate(table):
            automaton = State.from_nfa(self.regex(text_regex))
            for state in automaton:
                if state.final: state.tag = (n, token_type)

            regexs.append(automaton)
        return regexs
Beispiel #16
0
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        if current_item.NextSymbol.IsTerminal:
            if not current_item.NextItem in visited:
                visited[current_item.NextItem] = State(current_item.NextItem,
                                                       True)
                pending.append(current_item.NextItem)
        else:
            for production in current_item.NextSymbol.productions:
                item = Item(production, 0)
                if not item in visited:
                    visited[item] = State(item, True)
                    pending.append(item)
            if not current_item.NextItem in visited:
                visited[current_item.NextItem] = State(current_item.NextItem,
                                                       True)
                pending.append(current_item.NextItem)

        current_state = visited[current_item]
        # Your code here!!! (Add the decided transitions)
        current_state.add_transition(current_item.NextSymbol.Name,
                                     visited[current_item.NextItem])

        if current_item.NextSymbol.IsNonTerminal:
            for production in current_item.NextSymbol.productions:
                current_state.add_epsilon_transition(visited[Item(
                    production, 0)])

    # automaton.set_formatter(multiline_formatter_lr0)
    return automaton
Beispiel #17
0
    def build_automaton(G: Grammar):
        """
        Build the finite automaton for
        a regular grammar
        """
        states = {
            nonTerminal: State(nonTerminal.Name)
            for nonTerminal in G.nonTerminals
        }
        final_state = State('F\'', True)

        start_in_right = False
        epsilon_production = False

        for nonTerminal in G.nonTerminals:
            for production in nonTerminal.productions:
                right = production.Right

                # Start Symbol produces epsilon
                if isinstance(right, Epsilon) and nonTerminal == G.startSymbol:
                    epsilon_production = True
                    continue

                start_in_right |= G.startSymbol in right
                n = len(right)

                # X --> w
                if n == 1 and isinstance(right[0], Terminal):
                    states[nonTerminal].add_transition(right[0].Name,
                                                       final_state)
                    continue

                # X --> w Y
                if n == 2 and isinstance(right[0], Terminal) and isinstance(
                        right[1], NonTerminal):
                    states[nonTerminal].add_transition(right[0].Name,
                                                       states[right[1]])
                    continue

                return states[G.startSymbol], False

        states[G.startSymbol].final = epsilon_production
        return states[G.startSymbol], not (start_in_right
                                           and epsilon_production)
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        # Your code here!!! (Decide which transitions to add)
        new_item = current_item.NextItem()
        transition_symbol = current_item.NextSymbol.Name
        next_items = [(new_item, transition_symbol)]

        if current_item.NextSymbol in G.nonTerminals:
            for production in current_item.NextSymbol.productions:
                new_item = Item(production, 0)
                next_items.append((new_item, G.Epsilon))

        current_state = visited[current_item]
        # Your code here!!! (Add the decided transitions)
        for item, symbol in next_items:
            try:
                state = visited[item]
            except KeyError:
                state = State(item, True)
                visited[item] = state
                pending.append(item)

            if symbol == G.Epsilon:
                current_state.add_epsilon_transition(state)
            else:
                current_state.add_transition(symbol, state)

    return automaton
Beispiel #19
0
def build_LR1_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, lookaheads=(G.EOF, ))
    start = frozenset([start_item])

    closure = closure_lr1(start, firsts)
    automaton = State(frozenset(closure), True)

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]

        for symbol in G.terminals + G.nonTerminals:
            # Your code here!!! (Get/Build `next_state`)
            dest = goto_lr1(current_state.state, symbol, just_kernel=True)

            if not dest:
                continue

            if dest in visited:
                next_state = visited[dest]
            else:
                items = goto_lr1(current_state.state,
                                 symbol,
                                 firsts,
                                 just_kernel=False)
                next_state = State(frozenset(items), True)
                visited[dest] = next_state
                pending.append(dest)

            current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #20
0
    def Compact_Automata(self, automata):
        new_states = {}
        for state in automata:
            new_states[state] = state

        states_to_compress = []

        for state1 in automata:
            if not new_states[state1] == state1:
                continue
            states_to_compress = [state1] 
            for state2 in automata:
                if state1 == state2 or not new_states[state2] == state2:
                    continue
                
                node1 = state1.state
                node2 = state2.state

                are_equals = False
                if len(node1) == len(node2):
                    for item1 in node1:
                        are_equals = False
                        for item2 in node2:
                            if item1.Center() == item2.Center():
                                are_equals = True
                        if not are_equals:
                            break

                if are_equals:
                    states_to_compress.append(state2)

            compress_set = ContainerSet()

            for state in states_to_compress:
                node = state.state
                compress_set.update(ContainerSet(*node))

            new_node = self.compress(compress_set)
            new_state = State(frozenset(new_node), True)
            
            for state in states_to_compress:
                new_states[state] = new_state

        new_automata = new_states[automata]

        for state in automata:
            for key in state.transitions:
                for to_state in state.transitions[key]:
                    try:
                        assert new_states[to_state] in new_states[state].transitions[key] 
                    except:
                        new_states[state].add_transition(key, new_states[to_state])   
                        
        return new_automata
Beispiel #21
0
    def _build_regexs(table):
        regexs = []
        for n, (token_type, regex) in enumerate(table):
            NFA = Regex.build_automaton(regex)
            automaton, states = State.from_nfa(NFA, get_states=True)
            for state in automaton:
                if state.final:
                    state.tag = [(n, token_type)]
            regexs.append(automaton)

        return regexs
def build_LR1_automaton(G):
    assert len(G.startSymbol.productions) == 1, "Grammar must be augmented"

    firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, lookaheads=(G.EOF, ))
    start = frozenset([start_item])  # como cabecera solo queda el kernel

    closure = closure_lr1(start, firsts)
    automaton = State(frozenset(closure),
                      True)  # en visited si se guarda el estado completo

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]

        closure = closure_lr1(current, firsts)
        for symbol in G.terminals + G.nonTerminals:
            # (Get/Build `next_state`)
            # closure = closure_lr1(current,firsts)
            goto = goto_lr1(closure, symbol, firsts, True)

            if not goto:
                continue

            try:
                next_state = visited[goto]
            except KeyError:
                next_state = visited[goto] = State(
                    frozenset(closure_lr1(goto, firsts)), True)
                pending.append(goto)

            current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #23
0
    def _build_regexs(self, table):
        regexs = []
        for n, (token_type, regex) in enumerate(table):
            dfa = Regex(regex)
            automaton_list = State.from_nfa(
                dfa.automaton, 'texto random pra que haga lo que quiero')
            for i in automaton_list[1]:
                if (i.final):
                    i.tag = (n, token_type)
            regexs.append(automaton_list[0])

        return regexs
Beispiel #24
0
def build_LR1_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, lookaheads=(G.EOF, ))
    start = frozenset([start_item])

    closure = closure_lr1(start, firsts)
    automaton = State(frozenset(closure), True)

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]

        for symbol in G.terminals + G.nonTerminals:
            # Your code here!!! (Get/Build `next_state`)
            next_state_key = goto_lr1(current_state.state,
                                      symbol,
                                      just_kernel=True)
            # next_state_key = frozenset([i.NextItem() for i in current_state.state if i.NextSymbol == symbol])
            if not next_state_key:
                continue
            try:
                next_state = visited[next_state_key]
            except KeyError:
                next_state_items = goto_lr1(current_state.state, symbol,
                                            firsts)
                next_state = State(frozenset(next_state_items), True)
                pending.append(next_state_key)
                visited[next_state_key] = next_state
            current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
Beispiel #25
0
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)

    pending = [ start_item ]
    visited = { start_item: automaton }

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue
            
        state = visited[current_item]
        next_item = current_item.NextItem()
        try:
            new_state = visited[next_item]
        except KeyError:
            new_state = visited[next_item] = State(next_item, True)
            pending.append(next_item)
        
        next_symbol = current_item.NextSymbol
        state.add_transition(next_symbol.Name, new_state)
        
        if next_symbol.IsNonTerminal:
            for prod in next_symbol.productions:
                item = Item(prod, 0)
                try:
                    visited[item]
                except KeyError:
                    visited[item] = State(item, True)
                    pending.append(item)
                state.add_epsilon_transition(visited[item])

        current_state = visited[current_item]
        
    return automaton
Beispiel #26
0
def build_LR0_automaton(G):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0)

    automaton = State(start_item, True)
    pending = [start_item]
    visited = {start_item: automaton}

    while pending:
        current_item = pending.pop()
        if current_item.IsReduceItem:
            continue

        next_item = current_item.NextItem()
        symbol = current_item.NextSymbol

        try:
            visited[current_item].add_transition(symbol.Name,
                                                 visited[next_item])
        except:
            visited[next_item] = State(next_item, True)
            visited[current_item].add_transition(symbol.Name,
                                                 visited[next_item])
            pending.append(next_item)

        if symbol.IsNonTerminal:
            prod = symbol.productions
            for p in prod:
                item = Item(p, 0)
                try:
                    visited[current_item].add_epsilon_transition(visited[item])
                except KeyError:
                    visited[item] = State(item, True)
                    visited[current_item].add_epsilon_transition(visited[item])
                    pending.append(item)

    return automaton
 def _build_regexs(self, table):
     regexs = {}
     for n, (token_type, regex) in enumerate(table):
         # Your code here!!!
         # - Remember to tag the final states with the token_type and priority.
         # - <State>.tag might be useful for that purpose ;-)
         auto = regex_automaton(regex)
         auto, states = State.from_nfa(auto, True)
         for st in states:
             if st.final:
                 st.tag = (n, token_type)
         regexs[token_type] = auto
     return regexs
Beispiel #28
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
Beispiel #29
0
    def build_tree(self, current_node, index, parse_list, left_to_right):

        new_nodes = []
        if parse_list[index[0]].Right:
            for x in parse_list[index[0]].Right:
                new_nodes.append(State(x))
        else:
            new_nodes.append(State(parse_list[index[0]].Right))

        if not left_to_right: new_nodes.reverse()

        for x in new_nodes:
            current_node.add_transition('', x)
            if x.state.IsNonTerminal:
                index[0] += 1
                self.build_tree(x, index, parse_list, left_to_right)

        if not left_to_right:
            try:
                current_node.transitions[''].reverse()
            except:
                pass
def build_lr1_automaton(G, firsts=None):
    assert len(G.startSymbol.productions) == 1, 'Grammar must be augmented'

    if not firsts:
        firsts = compute_firsts(G)
    firsts[G.EOF] = ContainerSet(G.EOF)

    start_production = G.startSymbol.productions[0]
    start_item = Item(start_production, 0, lookaheads=(G.EOF, ))
    start = frozenset([start_item])

    closure = closure_lr1(start, firsts)
    automaton = State(frozenset(closure), True)

    pending = [start]
    visited = {start: automaton}

    while pending:
        current = pending.pop()
        current_state = visited[current]

        current_closure = current_state.state
        for symbol in G.terminals + G.nonTerminals:
            kernel = goto_lr1(current_closure, symbol, just_kernel=True)

            if kernel == frozenset():
                continue

            try:
                next_state = visited[kernel]
            except KeyError:
                goto = closure_lr1(kernel, firsts)
                visited[kernel] = next_state = State(frozenset(goto), True)
                pending.append(kernel)
            current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton