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
Example #2
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
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
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_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
Example #6
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
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
Example #8
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
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