示例#1
0
def delete_common_prefix(G: Grammar):
    """
    Algoritmo para eliminar los prefijos comunes de las producciones con la misma cabecera
    Por cada no terminal busca si dos de sus produciones tiene prefijos comunes
    """
    for nonterminal in G.nonTerminals:
        change = True
        primes = ''
        while change:
            change = False
            for production0 in nonterminal.productions:
                _continue = False
                for production1 in nonterminal.productions:
                    if production0 != production1:
                        lpc = 0
                        for i in range((min(len(production0.Right),
                                            len(production1.Right)))):
                            if production0.Right[i] == production1.Right[i]:
                                lpc += 1
                            else:
                                break
                        # En caso de que si tengan prefijos comunes se realiza el siguiente cambio:
                        # E -> aA | aB
                        # Entonces se cambia por :
                        # E -> aE'
                        # E' -> A | B
                        if lpc > 0:
                            primes += '\''
                            temp = G.NonTerminal(f"{nonterminal.Name}{primes}",
                                                 False)
                            nonterminal.productions.remove(production0)
                            nonterminal.productions.remove(production1)
                            G.Productions.remove(production0)
                            G.Productions.remove(production1)
                            nonterminal %= Sentence(*production0.Right[0:lpc] +
                                                    (temp, ))
                            alpha = production0.Right[lpc:]
                            betha = production1.Right[lpc:]
                            if len(alpha) == 0:
                                temp %= G.Epsilon
                            else:
                                temp %= Sentence(*alpha)
                            if len(betha) == 0:
                                temp %= G.Epsilon
                            else:
                                temp %= Sentence(*betha)
                            change = True
                            _continue = True
                            break
                if _continue:
                    continue
    return G
示例#2
0
def parse_production(production, G):
    production = production.split(' ')
    match(production[0], 'id')
    match(production[1], '->')

    if errors:
        return

    left = f[production[0]]

    it = 2
    right = SentenceList()
    while it < len(production):
        s = Sentence()
        while it < len(production) and production[it] != '|':
            match(production[it], 'id')

            if errors:
                return

            if production[it] == 'epsilon':
                s = G.Epsilon
            else:
                s += f[production[it]]

            it += 1
        it += 1

        right.Add(s)

    left %= right
示例#3
0
def delete_immediate_left_recursion(G: Grammar):
    """
    Algoritmo para eliminar la recursion izquierda inmediata
    """

    for symbol in G.nonTerminals:
        if any(not body.IsEpsilon and body[0] == symbol
               for _, body in symbol.productions):
            last_productions = set(symbol.productions)
            A = G.NonTerminal(f"{symbol}'")

            new_sents = [
                body + A for _, body in symbol.productions
                if body.IsEpsilon or body[0] != symbol
            ]
            for _, body in symbol.productions:
                if not body.IsEpsilon and body[0] == symbol:
                    # A' -> b A'
                    A %= Sentence(*(body[1:] + (A, )))
            A %= G.Epsilon

            for sent in new_sents:
                # A -> b A'
                symbol %= sent

            symbol.productions = list(
                set(symbol.productions) - last_productions)
            G.Productions = list(set(G.Productions) - last_productions)

    return G
示例#4
0
def eliminate_left_recursion(G: Grammar):
    recursive_prod = {}
    for production in G.Productions:
        if production.Left == production.Right[0]:
            non_terminal = production.Left
            for prod in non_terminal.productions:
                try:
                    recursive_prod[non_terminal].add(prod)
                except KeyError:
                    recursive_prod[non_terminal] = {prod}

    for non_terminal in recursive_prod.keys():
        new_non_teminal = G.NonTerminals(non_terminal.Name + "'")
        for prod in recursive_prod[non_terminal]:
            new_sentence = Sentence()
            if prod.Right[0] == non_terminal:
                for i in range(1, len(prod.Right)):
                    new_sentence += prod.Right[i]
                new_sentence += new_non_teminal[0]
                new_production = Production(new_non_teminal[0], new_sentence)
                G.Productions.append(new_production)
            else:
                for i in range(len(prod.Right)):
                    new_sentence += prod.Right[i]
                new_sentence += new_non_teminal[0]
                new_production = Production(non_terminal, new_sentence)
                G.Productions.append(new_production)
            G.Productions.remove(prod)
        G.Productions.append(Production(new_non_teminal[0], G.Epsilon))
示例#5
0
 def firsts(self):
     G = self.G
     return {
         G['|']:
         ContainerSet(G['|'], contains_epsilon=False),
         G['*']:
         ContainerSet(G['*'], contains_epsilon=False),
         G['(']:
         ContainerSet(G['('], contains_epsilon=False),
         G[')']:
         ContainerSet(G[')'], contains_epsilon=False),
         G['symbol']:
         ContainerSet(G['symbol'], contains_epsilon=False),
         G['ε']:
         ContainerSet(G['ε'], contains_epsilon=False),
         G['E']:
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         G['T']:
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         G['F']:
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         G['A']:
         ContainerSet(G['ε'], G['symbol'], G['('], contains_epsilon=False),
         G['X']:
         ContainerSet(G['|'], contains_epsilon=True),
         G['Y']:
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=True),
         G['Z']:
         ContainerSet(G['*'], contains_epsilon=True),
         Sentence(G['T'], G['X']):
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         Sentence(G['|'], G['E']):
         ContainerSet(G['|'], contains_epsilon=False),
         G.Epsilon:
         ContainerSet(contains_epsilon=True),
         Sentence(G['F'], G['Y']):
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         Sentence(G['T']):
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         Sentence(G['A'], G['Z']):
         ContainerSet(G['symbol'], G['ε'], G['('], contains_epsilon=False),
         Sentence(G['*']):
         ContainerSet(G['*'], contains_epsilon=False),
         Sentence(G['symbol']):
         ContainerSet(G['symbol'], contains_epsilon=False),
         Sentence(G['ε']):
         ContainerSet(G['ε'], contains_epsilon=False),
         Sentence(G['('], G['E'], G[')']):
         ContainerSet(G['('], contains_epsilon=False)
     }
示例#6
0
def fill_sentences_dict(G):
    sentence = {t: Sentence(t) for t in G.terminals}

    change = True
    while change:
        n = len(sentence)
        for production in G.Productions:
            head, body = production

            if head in sentence:
                continue

            if body.IsEpsilon or all(symbol in sentence for symbol in body):
                sentence[head] = Sentence(*[sentence[symbol] for symbol in body])

        change = n != len(sentence)

    return sentence
示例#7
0
def remove_ambiguity(G: Grammar):
    """
    Transforms productions of a non terminal for remove ambiguity.
    """
    change = True
    while change:
        change = False
        prods = G.Productions

        for nt in G.nonTerminals:
            p_dict = {}  # pi.Right[0] : {p1, p2, ..., pn}
            for p in nt.productions:
                if p.IsEpsilon:
                    continue
                try:
                    p_dict[p.Right[0].Name].append(p)
                except KeyError:
                    p_dict[p.Right[0].Name] = [p]

            next_appendix = "'"
            for p_set in p_dict.values():
                if len(
                        p_set
                ) > 1:  # Means nt has ambiguous production (all in p_set)
                    new_left = G.NonTerminal(nt.Name + next_appendix)
                    next_appendix = next_appendix + "'"
                    for p in p_set:
                        new_right = p.Right[1:]
                        if len(new_right) == 0:
                            prods.append(Production(new_left, G.Epsilon))
                        else:
                            prods.append(
                                Production(new_left, Sentence(*new_right)))
                        prods.remove(p)
                    prods.append(Production(nt, Sentence(p.Right[0],
                                                         new_left)))
                    change = True

        # Replacing old productions by new productions
        G.Productions = []  # Clean grammar productions
        for nt in G.nonTerminals:  # Clean non terminals productions
            nt.productions = []
        for p in prods:  # Add new productions
            G.Add_Production(p)
def shortest_production_path(G, x):
    """
    Compute the shortest poduction path from start symbol of
    Grammar G to a sentence form thad Contains the Non Temrinal X
    """
    queue = deque([x])
    sentence_form = {x: Sentence(x)}
    production_path = {
        x: [Production(x, Sentence(x))]
    }  # Eliminar esta linea de testeo

    productions = set(G.Productions)
    while queue:
        current = queue.popleft()

        visited_productions = set()
        for production in productions:

            head, body = production

            if head in sentence_form:
                continue

            sentence = Sentence()
            current_belong = False
            for i, symbol in enumerate(body):
                if symbol == current:
                    current_belong = True
                    sentence += sentence_form[current]
                else:
                    sentence += symbol

            if current_belong:
                queue.append(head)
                sentence_form[head] = sentence
                production_path[head] = [production] + production_path[current]
                visited_productions.add(production)

        productions -= visited_productions

    assert G.startSymbol in sentence_form, f'{x} is not reacheable from start symbol {G.startSymbol}'

    return sentence_form[G.startSymbol], production_path[G.startSymbol][:-1]
示例#9
0
    def evaluate(self, context):

        if isinstance(self.der, SentenceNodeGrammar):
            p = self.der.evaluate(context)
            context.Productions[context.NTerminals[str(
                self.izq)]] = Production(context.NTerminals[str(self.izq)], p)
            context.NTerminals[str(self.izq)].Grammar.Add_Production(
                Production(context.NTerminals[str(self.izq)], p))
            return

        elif isinstance(self.der, SentencesNodeGrammar):
            for i in self.der.evaluate(context):
                sentence = i
                if isinstance(sentence, SentenceNodeGrammar):
                    sentence = i.evaluate(context)

                try:
                    context.Productions[context.NTerminals[str(
                        self.izq)]].append(
                            Production(context.NTerminals[str(self.izq)],
                                       sentence))
                except:
                    context.Productions[context.NTerminals[str(self.izq)]] = [
                        Production(context.NTerminals[str(self.izq)], sentence)
                    ]

                context.NTerminals[str(self.izq)].Grammar.Add_Production(
                    Production(context.NTerminals[str(self.izq)], sentence))
            return

        b = context.Terminals[str(self.der)] if str(
            self.der) in context.Terminals else context.NTerminals[str(
                self.der)]

        if (str(self.der) == 'epsilon'):
            b = context.Grammar.Epsilon

        # print(b)

        context.Productions[context.NTerminals[str(self.izq)]] = Production(
            context.NTerminals[str(self.izq)], Sentence(b))
        context.NTerminals[str(self.izq)].Grammar.Add_Production(
            Production(context.NTerminals[str(self.izq)], Sentence(b)))
示例#10
0
def fill_fixed_sentences_dict(G, t, sentence_forms):
    fixed_sentences = {t: Sentence(t)}

    change = True
    while change:
        n = len(fixed_sentences)
        for production in G.Productions:
            left, right = production

            if left in fixed_sentences:
                continue

            if not right.IsEpsilon and right[0] in fixed_sentences:
                fixed_sentences[left] = \
                Sentence(
                    *([fixed_sentences[right[0]]] + [sentence_forms[symbol] for symbol in right[1:]])
                )

        change = n != len(fixed_sentences)

    return fixed_sentences
示例#11
0
 def evaluate(self, context):
     ret = []
     if not isinstance(self.der, SentenceNodeGrammar):
         if (str(self.der) == 'epsilon'):
             self.der = context.Grammar.Epsilon
         else:
             der = context.Terminals[str(self.der)] if str(
                 self.der) in context.Terminals else context.NTerminals[str(
                     self.der)]
             self.der = Sentence(der)
     if isinstance(self.izq, SentenceNodeGrammar):
         return [self.izq, self.der]
     elif isinstance(self.izq, SentencesNodeGrammar):
         temp = self.izq.evaluate(context)
         for i in temp:
             ret.append(i)
         ret.append(self.der)
         return ret
     b = context.Terminals[str(self.izq)] if str(
         self.izq) in context.Terminals else context.NTerminals[str(
             self.izq)]
     return [Sentence(b)]
def compute_sentence(G):
    """
    For each non terminal 'X' in the Grammar G compute a sentence of terminals 'S' where X ->* S
    """
    sentence = {t: Sentence(t) for t in G.terminals}

    change = True
    while change:
        n = len(sentence)
        for production in G.Productions:
            head, body = production

            if head in sentence:
                continue

            if body.IsEpsilon or all(symbol in sentence for symbol in body):
                sentence[head] = Sentence(
                    *[sentence[symbol] for symbol in body])

        change = n != len(sentence)

    return sentence
    def __generate_conflict(self):
        G = self.G
        x = self.conflict.nonterminal
        s = self.conflict.terminal
        table = self.table

        conflict1, conflict2 = table[x, s][0], table[x, s][1]
        sentence, _ = shortest_production_path(G, x)
        sentence_forms = compute_sentence(G)
        sentence_forms_fixxed = compute_fixxed_sentence(G, s, sentence_forms)

        i = tuple(sentence).index(x)

        x1 = conflict1.Right[0]
        x2 = conflict2.Right[0]

        s1 = Sentence(*(sentence[:i] + tuple(conflict1.Right) +
                        sentence[i + 1:]))
        s2 = Sentence(*(sentence[:i] + tuple(conflict2.Right) +
                        sentence[i + 1:]))

        ss1 = Sentence()
        for symbol in s1:
            if symbol == x1:
                ss1 += sentence_forms_fixxed[symbol]
            else:
                ss1 += sentence_forms[symbol]

        ss2 = Sentence()
        for symbol in s2:
            if symbol == x2:
                ss2 += sentence_forms_fixxed[symbol]
            else:
                ss2 += sentence_forms[symbol]

        self.prod1 = conflict1
        self.prod2 = conflict2
        return ss1, ss2
示例#14
0
def eliminate_left_recursion(G, left, dict):
    new_prods = []
    new_non_terminal = str(left) + '1'
    ('nnt---->', new_non_terminal)
    conflict_prods = dict[left]
    for prod in left.productions:
        l, r = prod
        nt = NonTerminal(new_non_terminal, G)
        if prod not in conflict_prods:
            ####A ->b1A'|b2A'|...|bnA'####
            s_r = [i for i in r]
            s_r = Sentence(*s_r, nt)
            new_p = Production(left, s_r)
            s = '+'.join([str(i) for i in s_r._symbols])
            new_prods.append((new_p, f'{left}%={s}'))
        else:
            new_r = [i for i in r._symbols]
            new_r.remove(left)
            s_r = Sentence(*new_r, nt)
            new_p = Production(left, s_r)
            s = '+'.join([str(i) for i in s_r._symbols])
            new_prods.append((new_p, f'{new_non_terminal}%={s}'))
    return new_prods, new_non_terminal
示例#15
0
 def firsts(self):
     G = self.G
     return {
         G['+']:
         ContainerSet(G['+'], contains_epsilon=False),
         G['-']:
         ContainerSet(G['-'], contains_epsilon=False),
         G['*']:
         ContainerSet(G['*'], contains_epsilon=False),
         G['/']:
         ContainerSet(G['/'], contains_epsilon=False),
         G['(']:
         ContainerSet(G['('], contains_epsilon=False),
         G[')']:
         ContainerSet(G[')'], contains_epsilon=False),
         G['num']:
         ContainerSet(G['num'], contains_epsilon=False),
         G['E']:
         ContainerSet(G['num'], G['('], contains_epsilon=False),
         G['T']:
         ContainerSet(G['num'], G['('], contains_epsilon=False),
         G['F']:
         ContainerSet(G['num'], G['('], contains_epsilon=False),
         G['X']:
         ContainerSet(G['-'], G['+'], contains_epsilon=True),
         G['Y']:
         ContainerSet(G['/'], G['*'], contains_epsilon=True),
         Sentence(G['T'], G['X']):
         ContainerSet(G['num'], G['('], contains_epsilon=False),
         Sentence(G['+'], G['T'], G['X']):
         ContainerSet(G['+'], contains_epsilon=False),
         Sentence(G['-'], G['T'], G['X']):
         ContainerSet(G['-'], contains_epsilon=False),
         G.Epsilon:
         ContainerSet(contains_epsilon=True),
         Sentence(G['F'], G['Y']):
         ContainerSet(G['num'], G['('], contains_epsilon=False),
         Sentence(G['*'], G['F'], G['Y']):
         ContainerSet(G['*'], contains_epsilon=False),
         Sentence(G['/'], G['F'], G['Y']):
         ContainerSet(G['/'], contains_epsilon=False),
         Sentence(G['num']):
         ContainerSet(G['num'], contains_epsilon=False),
         Sentence(G['('], G['E'], G[')']):
         ContainerSet(G['('], contains_epsilon=False)
     }
示例#16
0
 def search_prefix(self):
     root = self.root
     if len(root.children) == 1:
         prefix = Sentence()
         root = list(root.children.values())[0]
         while True:
             prefix += root.value
             if len(root.children) > 1 or len(root.children) == 0:
                 break
             root = list(root.children.values())[0]
         if root.terminating:
             return
         return prefix
     else:
         return
def compute_fixxed_sentence(G, t, sentence_forms):
    """
    For each non terminal 'X' in the Grammar G compute a sentence of terminals that start with t 'tS'
    where X ->* tS
    """
    fixxed_sentence = {t: Sentence(t)}

    change = True
    while change:
        n = len(fixxed_sentence)
        for production in G.Productions:
            head, body = production

            if head in fixxed_sentence:
                continue

            if not body.IsEpsilon and body[0] in fixxed_sentence:
                fixxed_sentence[head] = Sentence(
                    *([fixxed_sentence[body[0]]] +
                      [sentence_forms[symbol] for symbol in body[1:]]))

        change = n != len(fixxed_sentence)

    return fixxed_sentence
示例#18
0
def remove_left_recursion(G: Grammar):
    """
    Eliminates all left-recursion for any CFG with no e-productions and no cycles.
    """
    def has_lr(nt: NonTerminal) -> bool:
        """
        True if `nt` has left recursion.
        """
        return any(p.Left == p.Right[0] for p in nt.productions)

    prods = [p for p in G.Productions]
    new_prods = []
    for nt in G.nonTerminals:
        if has_lr(nt):
            new_symbol = G.NonTerminal(nt.Name + "'")
            for p in nt.productions:
                if p.Right[0] == p.Left:  # Production has the from A -> Axyz
                    new_right = [s for s in p.Right[1:]]
                    new_right.append(new_symbol)
                    new_prods.append(
                        Production(new_symbol, Sentence(*new_right)))
                else:  # Production has the from A -> xyz
                    new_right = [s for s in p.Right[0:]]
                    new_right.append(new_symbol)
                    new_prods.append(Production(p.Left, Sentence(*new_right)))
            new_prods.append(Production(new_symbol, G.Epsilon))
        else:
            for p in nt.productions:
                new_prods.append(p)

    # Replacing old productions by new productions
    G.Productions = []  # Clean grammar productions
    for nt in G.nonTerminals:  # Clean non terminals productions
        nt.productions = []
    for p in new_prods:  # Add new productions
        G.Add_Production(p)
示例#19
0
def delete_epsilon(G: Grammar):
    """
    Delete all Epsilon productions in Grammar G
    :param G: Grammar
    :return: G whithout epsilon productions
    """

    # To eliminate the epsilon productions we find a set of non terminals 'nullables'.
    # These non termimnals are those that after one or more productions they become in epsilon.
    #
    # Example:
    # A ->* epsilon => A is nullable
    nullable = set()
    change = True
    while change:
        n = len(nullable)
        for head, body in G.Productions:

            if head in nullable:
                continue

            if len(body) == 0:
                nullable.add(head)
            else:
                if all(symbol in nullable for symbol in body):
                    nullable.add(head)
        change = n != len(nullable)

    # Now we have al non terminals nullables for every production
    # then if a production contains a nullable non terminal it will be replaced by the same production
    # but without the nullable non terminal. Then we eliminate all epsilon productions.
    for nonterminal in G.nonTerminals:
        stack = [x for x in nonterminal.productions]
        dic = {}
        while stack:
            production = stack.pop()
            if production.Right.IsEpsilon:
                G.Productions.remove(production)
                nonterminal.productions.remove(production)
            else:
                _, body = production
                for i, symbol in enumerate(body):
                    if symbol in nullable:
                        add_production(nonterminal,
                                       Sentence(*(body[:i] + body[i + 1:])),
                                       dic, stack)
    return G
示例#20
0
def create_productions(G, left, right, new=False, new_symbol=None):
    _G = Grammar()
    left = NonTerminal(left, _G)
    list_symbols = []
    if right == G.Epsilon:
        return Production(left, _G.Epsilon)
    for r in right:
        s = search(G, r)
        if not s:
            s = NonTerminal(r, _G)
        list_symbols.append(s)
    if new:
        s = NonTerminal(new_symbol, _G)
        list_symbols.append(s)
    right = Sentence(list_symbols[0])
    for i in range(1, len(list_symbols)):
        right = right + list_symbols[i]
    return Production(left, right)
示例#21
0
def expand_path(init, path, follows):
    """
    Expand the non terminal symbols in the given path until all becomes in terminals
    and return a sentence with these sequenced terminals
    """
    i = -2
    table = {s: set(s.state) for s in init}

    lookahead = path[-1]
    while i >= -len(path):
        current = path[i]
        symbol = path[i + 1]

        if symbol.IsTerminal:
            lookahead = symbol
            i -= 2
            continue

        reductors = [
            item for item in current.state
            if item.production.Left == current and item in table[current]
        ]

        while reductors:
            reductor = reductors.pop()

            subpath = guided_path(current, reductor.production.Right)

            last = subpath.pop()
            ritem = [
                item for item in last.state
                if item.IsReduceItem and item.production == reductor.production
            ][0]
            lookaheads = follows[
                ritem.Left] if not ritem.lookaheads else ritem.lookaheads

            if lookahead in lookaheads:
                table[current].remove(reductor)
                path = path[:i] + subpath + path[i + 2:]
                break

    return Sentence(*[s for s in path if not isinstance(s, State)])
def delete_epsilon_from_grammar(G):
    # primero marca como nulleable los posibles no terminales
    # los cuales pueden ser alcanzados por derivaciones de epsilon
    # (en uno o mas pasos)

    nullable_non_term = {}

    for nt in G.nonTerminals:
        prod = nt.productions
        for p in prod:
            if p.IsEpsilon:
                nullable_non_term[p.Left] = True

    augment = True
    while augment:
        len_null = len(nullable_non_term)

        for prod in G.Productions:
            left, right = prod

            if left in nullable_non_term:
                continue

            if len(right) == 0:
                nullable_non_term[left] = True

            else:
                null = True
                for item in right:
                    if item not in nullable_non_term:
                        null = False
                        break
                if left not in nullable_non_term:
                    nullable_non_term[left] = null
                else:
                    if not nullable_non_term[left] and null:
                        nullable_non_term[left] = True

        augment = len_null != len(nullable_non_term)

    # se encarga de eliminar las producciones sobrantes
    # y tambien de agregar las nuevas producciones luego de la sustitucion

    for nt in G.nonTerminals:
        prod = nt.productions
        mask = {}

        counter = 0
        while counter < len(prod):
            pr = prod[counter]

            if len(pr.Right) == 0:
                G.Productions.remove(pr)
                nt.productions.remove(pr)
            else:
                for pos, elem in enumerate(pr.Right):
                    try:
                        if nullable_non_term[elem]:
                            temp = [
                                item for i, item in enumerate(pr.Right)
                                if i != pos
                            ]
                            sent = Sentence(*temp)
                            if sent not in mask:
                                mask[sent] = True
                                if len(sent):
                                    pr.Left %= sent
                                prod.append(pr.Left.productions[-1])
                    except KeyError:
                        pass
                counter += 1

    return G
示例#23
0
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)),
    Production(F, Sentence(num)),
    Production(Y, G.Epsilon),
    Production(X, Sentence(plus, T, X)),
    Production(T, Sentence(F, Y)),
    Production(F, Sentence(num)),
    Production(Y, Sentence(star, F, Y)),
    Production(F, Sentence(num)),
    Production(Y, G.Epsilon),
    Production(X, Sentence(plus, T, X)),
    Production(T, Sentence(F, Y)),
示例#24
0
def expand_path(init, path, follows):
    """
    Expand the non terminal symbols in the given path until all becomes in terminals
    and return a sentence with these sequenced terminals
    """
    i = -2
    table = {s: set(s.state) for s in init}

    lookahead = path[-1]
    while i >= -len(path):
        current = path[i]
        symbol = path[i + 1]
        print('expanding path')
        print(i)
        print(current)
        print(symbol)
        input()

        if symbol.IsTerminal:
            lookahead = symbol
            i -= 2
            continue

        reductors = [
            item for item in current.state
            if item.production.Left == current and item in table[current]
        ]

        for item in current.state:
            print(f'item: {item}')
            print(f'table[current]: {table[current]}')
            print(
                f'item.production.Left: {item.production.Left}, type: {type(item.production.Left)}'
            )
            print(f'type current: {type(current)}')
            print(f'item in table: {item in table[current]}')

        print(f'reductors: {reductors}')
        input()

        while reductors:
            reductor = reductors.pop()

            subpath = move(current, reductor.production.Right)

            print(f'reductor: {reductor}')
            print(f'subpath: {subpath}')
            input()

            last = subpath.pop()
            ritem = [
                item for item in last.state
                if item.IsReduceItem and item.production == reductor.production
            ][0]
            lookaheads = follows[
                ritem.Left] if not ritem.lookaheads else ritem.lookaheads

            if lookahead in lookaheads:
                table[current].remove(reductor)
                path = path[:i] + subpath + path[i + 2:]
                break

    return Sentence(*[s for s in path if not isinstance(s, State)])
示例#25
0
def remove_epsilon(G: Grammar):
    """
    Removes e-productions from G.
    """
    prods = G.Productions

    # Find non terminals that derives in epsilon
    nullables = []
    changed = True
    while changed:
        changed = False
        for prod in prods:
            for symbol in prod.Right:
                if symbol in nullables:
                    continue
                elif not symbol.IsEpsilon:
                    break
            else:
                if prod.Left not in nullables:
                    nullables.append(prod.Left)
                    changed = True

    # Decomposing of productions removing one or multiple nullables non terminals

    # Removing old productions
    G.Productions = []
    for nt in G.nonTerminals:
        nt.productions = []

    # Adding new productions
    for prod in prods:
        prod_nullables = {
            index: symbol for index, symbol in zip(range(len(prod.Right)), prod.Right) \
            if symbol in nullables
        }
        for i in range(1, len(prod_nullables) + 1):  # Size iter
            for subset in it.combinations(prod_nullables, i):  # Subset iter
                right_part = []
                for j in range(len(prod.Right)):
                    if j not in subset:
                        right_part.append(prod.Right[j])
                if len(right_part) > 0:
                    new_prod = Production(prod.Left, Sentence(*right_part))
                else:
                    new_prod = Production(prod.Left, G.Epsilon)
                if new_prod not in G.Productions:
                    G.Add_Production(new_prod)

    # Adding old productions
    for prod in prods:
        G.Add_Production(prod)

    prods = G.Productions
    G.Productions = []
    useless_symbols = [
        symbol for symbol in nullables
        if all(prod.IsEpsilon for prod in symbol.productions)
    ]
    # Removing productions that contains non terminals that derive in epsilon
    for prod in prods:
        if prod.IsEpsilon or any(symbol in useless_symbols
                                 for symbol in prod.Right):
            continue
        else:
            G.Add_Production(prod)

    # Removing non terminals symbols with no productions
    for s in useless_symbols:
        G.nonTerminals.remove(s)
        G.symbDict.pop(s.Name)
示例#26
0
def unit_testing():
    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, lambda h,s: s[2], None, lambda h,s: s[1]                    
    
    X %= plus + T + X, lambda h,s: s[3], None, None, lambda h,s: s[2] + h[0]
    X %= minus + T + X, lambda h,s: s[3], None, None, lambda h,s: h[0] - s[2] 
    X %= G.Epsilon, lambda h,s: h[0]                                                    
    
    T %= F + Y, lambda h,s: s[2], None, lambda h,s: s[1]                                            
    
    Y %= star + F + Y, lambda h,s: s[3], None, None, lambda h,s: h[0] * s[2]                               
    Y %= div + F + Y, lambda h,s: s[3], None, None, lambda h,s: h[0]/s[2]                                
    Y %= G.Epsilon, lambda h,s: h[0]                                                    
    
    F %= num, lambda h,s: float(s[1]), None                                                    
    F %= opar + E + cpar, lambda h,s: s[2], None, None, None     
    
    xcool = BasicXCool(G)
    tokens = [num, star, num, star, num, plus, num, star, num, plus, num, plus, num, G.EOF]

    M = _build_parsing_table(G,xcool.firsts,xcool.follows)
    assert M == xcool.table ,"Test Error in  build_parsing_table"

    print(" - buider table ;) ")

####################################################################
    parser = _buid_parsing_func(G,M)
    left_parse,error = parser(tokens)
    assert error == []
    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)),
       Production(F, Sentence(num)),
       Production(Y, G.Epsilon),
       Production(X, Sentence(plus, T, X)),
       Production(T, Sentence(F, Y)),
       Production(F, Sentence(num)),
       Production(Y, Sentence(star, F, Y)),
       Production(F, Sentence(num)),
       Production(Y, G.Epsilon),
       Production(X, Sentence(plus, T, X)),
       Production(T, Sentence(F, Y)),
       Production(F, Sentence(num)),
       Production(Y, G.Epsilon),
       Production(X, Sentence(plus, T, X)),
       Production(T, Sentence(F, Y)),
       Production(F, Sentence(num)),
       Production(Y, G.Epsilon),
       Production(X, G.Epsilon),
    ] ,"Test Error in  parser_library.LL1.parser"

    print(" - buider func  ;) ")

###################################################################
    fixed_tokens = {
    '+'  :   Token( '+', plus  ),
    '-'  :   Token( '-', minus ),
    '*'  :   Token( '*', star  ),
    '/'  :   Token( '/', div   ),
    '('  :   Token( '(', opar  ),
    ')'  :   Token( ')', cpar  ),
    }

    def tokenize_text(text):
        tokens = []

        for item in text.split():
            try:
                float(item)
                token = Token(item, num)
            except ValueError:
                try:
                    token = fixed_tokens[item]
                except:
                    raise Exception('Undefined token')
            tokens.append(token)

        eof = Token('$', G.EOF)
        tokens.append(eof)

        return tokens


    text = '5.9 + 4'
    tokens = [ Token('5.9', num), Token('+', plus), Token('4', num), Token('$', G.EOF) ]
    left_parse,error = parser(tokens)
    assert len(left_parse) == 9 and len(error) == 0,"Test Error in  parser func"
    result = _evaluate_parse(left_parse, tokens)
    assert result == 9.9,"Test Error in  eval parser"

    text = '1 - 1 - 1'
    tokens = tokenize_text(text)
    left_parse,error = parser(tokens)
    assert len(left_parse) == 13 and len(error) == 0,"Test Error in  parser func"
    result = _evaluate_parse(left_parse, tokens)
    assert result == -1,"Test Error in  eval parser"

    text = '1 - ( 1 - 1 )'
    tokens = tokenize_text(text)
    left_parse,error = parser(tokens)
    assert len(left_parse) == 18 and len(error) == 0,"Test Error in  parser func"
    result = _evaluate_parse(left_parse, tokens)
    assert result == 1,"Test Error in  eval parser"

    print(" - method eval  ;) ")

#############################################################
    return "LL1"
示例#27
0
 def __action_table(self):
     G = self.G
     return {
         (0, G["ε"]): ("SHIFT", 27),
         (0, G["("]): ("SHIFT", 1),
         (0, G["["]): ("SHIFT", 28),
         (0, G["symbol"]): ("SHIFT", 26),
         (1, G["["]): ("SHIFT", 5),
         (1, G["symbol"]): ("SHIFT", 3),
         (1, G["ε"]): ("SHIFT", 4),
         (1, G["("]): ("SHIFT", 2),
         (2, G["["]): ("SHIFT", 5),
         (2, G["symbol"]): ("SHIFT", 3),
         (2, G["ε"]): ("SHIFT", 4),
         (2, G["("]): ("SHIFT", 2),
         (3, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G[")"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (3, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (4, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G[")"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["symbol"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (4, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (5, G["symbol"]): ("SHIFT", 6),
         (6, G["]"]): ("REDUCE", AttributeProduction(G["L"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (6, G["-"]): ("SHIFT", 7),
         (6, G["symbol"]): ("SHIFT", 6),
         (7, G["symbol"]): ("SHIFT", 8),
         (8, G["]"]): ("REDUCE", AttributeProduction(G["L"], Sentence(G["symbol"], G["-"], G["symbol"]),
                                                     [lambda s: RangeNode(SymbolNode(s[1]), SymbolNode(s[3]))])),
         (8, G["symbol"]): ("SHIFT", 6),
         (9, G["]"]): ("REDUCE", AttributeProduction(G["L"], Sentence(G["symbol"], G["-"], G["symbol"], G["L"]), [
             lambda s: UnionNode(RangeNode(SymbolNode(s[1]), SymbolNode(s[3])), s[4])])),
         (10, G["]"]): ("REDUCE", AttributeProduction(G["L"], Sentence(G["symbol"], G["L"]),
                                                      [lambda s: UnionNode(SymbolNode(s[1]), s[2])])),
         (11, G["]"]): ("SHIFT", 12),
         (12, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G[")"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (12, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (13, G["|"]): ("SHIFT", 14),
         (13, G[")"]): ("SHIFT", 22),
         (14, G["["]): ("SHIFT", 5),
         (14, G["symbol"]): ("SHIFT", 3),
         (14, G["ε"]): ("SHIFT", 4),
         (14, G["("]): ("SHIFT", 2),
         (15, G["["]): ("SHIFT", 5),
         (15, G["symbol"]): ("SHIFT", 3),
         (15, G["ε"]): ("SHIFT", 4),
         (15, G["|"]): (
             "REDUCE",
             AttributeProduction(G["E"], Sentence(G["E"], G["|"], G["T"]), [lambda s: UnionNode(s[1], s[3])])),
         (15, G[")"]): (
             "REDUCE",
             AttributeProduction(G["E"], Sentence(G["E"], G["|"], G["T"]), [lambda s: UnionNode(s[1], s[3])])),
         (15, G["("]): ("SHIFT", 2),
         (16, G["|"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (16, G["("]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (16, G[")"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (16, G["symbol"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (16, G["ε"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (16, G["["]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (17, G["*"]): ("SHIFT", 18),
         (17, G["|"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G["("]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G[")"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G["symbol"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G["ε"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G["["]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (17, G["+"]): ("SHIFT", 19),
         (17, G["?"]): ("SHIFT", 20),
         (18, G["|"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (18, G["("]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (18, G[")"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (18, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (18, G["ε"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (18, G["["]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (19, G["|"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (19, G["("]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (19, G[")"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (19, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (19, G["ε"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (19, G["["]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (20, G["|"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (20, G["("]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (20, G[")"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (20, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (20, G["ε"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (20, G["["]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (21, G["|"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (21, G["("]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (21, G[")"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (21, G["symbol"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (21, G["ε"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (21, G["["]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (22, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G[")"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (22, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (23, G["["]): ("SHIFT", 5),
         (23, G["symbol"]): ("SHIFT", 3),
         (23, G["|"]): ("REDUCE", AttributeProduction(G["E"], Sentence(G["T"]), [lambda s: s[1]])),
         (23, G[")"]): ("REDUCE", AttributeProduction(G["E"], Sentence(G["T"]), [lambda s: s[1]])),
         (23, G["ε"]): ("SHIFT", 4),
         (23, G["("]): ("SHIFT", 2),
         (24, G["|"]): ("SHIFT", 14),
         (24, G[")"]): ("SHIFT", 25),
         (25, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["$"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (25, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["("], G["E"], G[")"]), [lambda s: s[2]])),
         (26, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["$"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (26, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["symbol"]), [lambda s: SymbolNode(s[1])])),
         (27, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["symbol"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["$"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (27, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["ε"]), [lambda s: EpsilonNode(s[1])])),
         (28, G["symbol"]): ("SHIFT", 6),
         (29, G["]"]): ("SHIFT", 30),
         (30, G["|"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["+"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["?"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["*"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["("]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["symbol"]): (
             "REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["ε"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["$"]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (30, G["["]): ("REDUCE", AttributeProduction(G["A"], Sentence(G["["], G["L"], G["]"]), [lambda s: s[2]])),
         (31, G["|"]): ("SHIFT", 32),
         (31, G["$"]): ("OK", None),
         (32, G["ε"]): ("SHIFT", 27),
         (32, G["("]): ("SHIFT", 1),
         (32, G["["]): ("SHIFT", 28),
         (32, G["symbol"]): ("SHIFT", 26),
         (33, G["ε"]): ("SHIFT", 27),
         (33, G["("]): ("SHIFT", 1),
         (33, G["["]): ("SHIFT", 28),
         (33, G["|"]): (
             "REDUCE",
             AttributeProduction(G["E"], Sentence(G["E"], G["|"], G["T"]), [lambda s: UnionNode(s[1], s[3])])),
         (33, G["$"]): (
             "REDUCE",
             AttributeProduction(G["E"], Sentence(G["E"], G["|"], G["T"]), [lambda s: UnionNode(s[1], s[3])])),
         (33, G["symbol"]): ("SHIFT", 26),
         (34, G["|"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (34, G["("]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (34, G["symbol"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (34, G["ε"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (34, G["$"]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (34, G["["]): (
             "REDUCE", AttributeProduction(G["T"], Sentence(G["T"], G["F"]), [lambda s: ConcatNode(s[1], s[2])])),
         (35, G["*"]): ("SHIFT", 36),
         (35, G["|"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["("]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["symbol"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["ε"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["$"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["["]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"]), [lambda s: s[1]])),
         (35, G["+"]): ("SHIFT", 37),
         (35, G["?"]): ("SHIFT", 38),
         (36, G["|"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (36, G["("]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (36, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (36, G["ε"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (36, G["$"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (36, G["["]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["*"]), [lambda s: ClosureNode(s[1])])),
         (37, G["|"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (37, G["("]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (37, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (37, G["ε"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (37, G["$"]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (37, G["["]): ("REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["+"]), [lambda s: PlusNode(s[1])])),
         (38, G["|"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (38, G["("]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (38, G["symbol"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (38, G["$"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (38, G["ε"]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (38, G["["]): (
             "REDUCE", AttributeProduction(G["F"], Sentence(G["A"], G["?"]), [lambda s: QuestionNode(s[1])])),
         (39, G["|"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (39, G["("]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (39, G["symbol"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (39, G["$"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (39, G["ε"]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (39, G["["]): ("REDUCE", AttributeProduction(G["T"], Sentence(G["F"]), [lambda s: s[1]])),
         (40, G["ε"]): ("SHIFT", 27),
         (40, G["("]): ("SHIFT", 1),
         (40, G["|"]): ("REDUCE", AttributeProduction(G["E"], Sentence(G["T"]), [lambda s: s[1]])),
         (40, G["$"]): ("REDUCE", AttributeProduction(G["E"], Sentence(G["T"]), [lambda s: s[1]])),
         (40, G["["]): ("SHIFT", 28),
         (40, G["symbol"]): ("SHIFT", 26),
     }
示例#28
0
 def table(self):
     G = self.G
     return {
         (
             G['E'],
             G['num'],
         ): [
             Production(G['E'], Sentence(G['T'], G['X'])),
         ],
         (
             G['E'],
             G['('],
         ): [
             Production(G['E'], Sentence(G['T'], G['X'])),
         ],
         (
             G['X'],
             G['+'],
         ): [
             Production(G['X'], Sentence(G['+'], G['T'], G['X'])),
         ],
         (
             G['X'],
             G['-'],
         ): [
             Production(G['X'], Sentence(G['-'], G['T'], G['X'])),
         ],
         (
             G['X'],
             G[')'],
         ): [
             Production(G['X'], G.Epsilon),
         ],
         (
             G['X'],
             G.EOF,
         ): [
             Production(G['X'], G.Epsilon),
         ],
         (
             G['T'],
             G['num'],
         ): [
             Production(G['T'], Sentence(G['F'], G['Y'])),
         ],
         (
             G['T'],
             G['('],
         ): [
             Production(G['T'], Sentence(G['F'], G['Y'])),
         ],
         (
             G['Y'],
             G['*'],
         ): [
             Production(G['Y'], Sentence(G['*'], G['F'], G['Y'])),
         ],
         (
             G['Y'],
             G['/'],
         ): [
             Production(G['Y'], Sentence(G['/'], G['F'], G['Y'])),
         ],
         (
             G['Y'],
             G[')'],
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['Y'],
             G['-'],
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['Y'],
             G.EOF,
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['Y'],
             G['+'],
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['F'],
             G['num'],
         ): [
             Production(G['F'], Sentence(G['num'])),
         ],
         (
             G['F'],
             G['('],
         ): [
             Production(G['F'], Sentence(G['('], G['E'], G[')'])),
         ]
     }
示例#29
0
 def table(self):
     G = self.G
     return {
         (
             G['E'],
             G['symbol'],
         ): [
             Production(G['E'], Sentence(G['T'], G['X'])),
         ],
         (
             G['E'],
             G['ε'],
         ): [
             Production(G['E'], Sentence(G['T'], G['X'])),
         ],
         (
             G['E'],
             G['('],
         ): [
             Production(G['E'], Sentence(G['T'], G['X'])),
         ],
         (
             G['X'],
             G['|'],
         ): [
             Production(G['X'], Sentence(G['|'], G['E'])),
         ],
         (
             G['X'],
             G[')'],
         ): [
             Production(G['X'], G.Epsilon),
         ],
         (
             G['X'],
             G.EOF,
         ): [
             Production(G['X'], G.Epsilon),
         ],
         (
             G['T'],
             G['symbol'],
         ): [
             Production(G['T'], Sentence(G['F'], G['Y'])),
         ],
         (
             G['T'],
             G['ε'],
         ): [
             Production(G['T'], Sentence(G['F'], G['Y'])),
         ],
         (
             G['T'],
             G['('],
         ): [
             Production(G['T'], Sentence(G['F'], G['Y'])),
         ],
         (
             G['Y'],
             G['symbol'],
         ): [
             Production(G['Y'], Sentence(G['T'])),
         ],
         (
             G['Y'],
             G['ε'],
         ): [
             Production(G['Y'], Sentence(G['T'])),
         ],
         (
             G['Y'],
             G['('],
         ): [
             Production(G['Y'], Sentence(G['T'])),
         ],
         (
             G['Y'],
             G[')'],
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['Y'],
             G.EOF,
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['Y'],
             G['|'],
         ): [
             Production(G['Y'], G.Epsilon),
         ],
         (
             G['F'],
             G['symbol'],
         ): [
             Production(G['F'], Sentence(G['A'], G['Z'])),
         ],
         (
             G['F'],
             G['ε'],
         ): [
             Production(G['F'], Sentence(G['A'], G['Z'])),
         ],
         (
             G['F'],
             G['('],
         ): [
             Production(G['F'], Sentence(G['A'], G['Z'])),
         ],
         (
             G['Z'],
             G['*'],
         ): [
             Production(G['Z'], Sentence(G['*'])),
         ],
         (
             G['Z'],
             G.EOF,
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['Z'],
             G['|'],
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['Z'],
             G['('],
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['Z'],
             G[')'],
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['Z'],
             G['symbol'],
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['Z'],
             G['ε'],
         ): [
             Production(G['Z'], G.Epsilon),
         ],
         (
             G['A'],
             G['symbol'],
         ): [
             Production(G['A'], Sentence(G['symbol'])),
         ],
         (
             G['A'],
             G['ε'],
         ): [
             Production(G['A'], Sentence(G['ε'])),
         ],
         (
             G['A'],
             G['('],
         ): [
             Production(G['A'], Sentence(G['('], G['E'], G[')'])),
         ]
     }