def _build_parsing_table(self):
        G = self.G.AugmentedGrammar(True)
        firsts = compute_firsts(G)
        follows = compute_follows(G, firsts)

        automaton = build_LR0_automaton(G).to_deterministic()
        for i, node in enumerate(automaton):
            if self.verbose:
                print(i, '\t', '\n\t '.join(str(x) for x in node.state), '\n')
            node.idx = i

        for node in automaton:
            idx = node.idx
            for state in node.state:
                item = state.state
                # Your code here!!!
                # - Fill `self.Action` and `self.Goto` according to `item`)
                # - Feel free to use `self._register(...)`)
                if item.IsReduceItem and item.production.Left == G.startSymbol:
                    self._register(self.action, (idx, G.EOF), (self.OK, 0))
                elif item.IsReduceItem:
                    for symbol in follows[item.production.Left]:
                        self._register(self.action, (idx, symbol), (self.REDUCE, item.production))
                elif item.NextSymbol.IsTerminal:
                    next_idx = node.transitions[item.NextSymbol.Name][0].idx
                    self._register(self.action, (idx, item.NextSymbol), (self.SHIFT, next_idx))
                elif item.NextSymbol.IsNonTerminal:
                    next_idx = node.transitions[item.NextSymbol.Name][0].idx
                    self._register(self.goto, (idx, item.NextSymbol), next_idx)
Exemple #2
0
def deprecated_metodo_predictivo_no_recursivo(G, M=None, firsts=None, follows=None):
    if M is None:
        if firsts is None:
            firsts = compute_firsts(G)
        if follows is None:
            follows = compute_follows(G, firsts)
        M = build_parsing_table(G, firsts, follows)

    def parser(w):
        stack = [G.startSymbol]
        cursor = 0
        output = []
        while len(stack) != 0:
            top = stack.pop()
            a = w[cursor]
            if top.IsTerminal:
                if a == top:
                    cursor += 1
                else:
                    raise Exception("Parsing error")
            elif top.IsNonTerminal:
                production = M[top, a]
                for i in reversed(production[0].Right):
                    stack.append(i)
                output.append(production[0])
        return output

    return parser
def _regex(expression: str) -> DFA:
    tokens = regex_tokenizer(expression, G)
    first = compute_firsts(G)
    follow = compute_follows(G, first)
    parsing_table = build_parsing_table(G, first, follow)
    parser = metodo_predictivo_no_recursivo(G, parsing_table)
    left_parse = parser(tokens)
    ast = evaluate_parse(left_parse, tokens)
    nfa = ast.evaluate()
    dfa = nfa_to_dfa(nfa)
    mini = automata_minimization(dfa)
    return mini
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`)
            closure = closure_lr1(current, firsts)
            goto = goto_lr1(closure, symbol, firsts, True)

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

            current_state.add_transition(symbol.Name, next_state)

    automaton.set_formatter(multiline_formatter)
    return automaton
import first_follow as ff
from cmp.pycompiler import Grammar

G = Grammar()
E = G.NonTerminal('E', True)
T, F, X, Y = G.NonTerminals('T F X Y')
plus, minus, star, div, opar, cpar, num = G.Terminals('+ - * / ( ) num')

E %= T + X
X %= plus + T + X | minus + T + X | G.Epsilon
T %= F + Y
Y %= star + F + Y | div + F + Y | G.Epsilon
F %= num | opar + E + cpar

import cmp.languages

xcool = cmp.languages.BasicXCool(G)

firsts = ff.compute_firsts(G)
assert firsts == xcool.firsts
from first_follow import compute_firsts, compute_follows
from ll1_parser import metodo_predictivo_no_recursivo, build_parsing_table

G = Grammar()
E = G.NonTerminal('E', True)
T, F, X, Y = G.NonTerminals('T F X Y')
plus, minus, star, div, opar, cpar, num = G.Terminals('+ - * / ( ) num')

E %= T + X
X %= plus + T + X | minus + T + X | G.Epsilon
T %= F + Y
Y %= star + F + Y | div + F + Y | G.Epsilon
F %= num | opar + E + cpar
print(G)

firsts = compute_firsts(G)
follows = compute_follows(G, firsts)
M = build_parsing_table(G, firsts, follows)
parser = metodo_predictivo_no_recursivo(G, M)
left_parse = parser([
    num, star, num, star, num, plus, num, star, num, plus, num, plus, num,
    G.EOF
])

assert left_parse == [
    Production(E, Sentence(T, X)),
    Production(T, Sentence(F, Y)),
    Production(F, Sentence(num)),
    Production(Y, Sentence(star, F, Y)),
    Production(F, Sentence(num)),
    Production(Y, Sentence(star, F, Y)),