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
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
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
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))
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) }
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
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]
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)))
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
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
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
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) }
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
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)
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
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)
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
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)),
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)])
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)
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"
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), }
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[')'])), ] }
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[')'])), ] }