def compute_local_first(firsts, alpha): first_alpha = ContainerSet() try: alpha_is_epsilon = alpha.IsEpsilon except: alpha_is_epsilon = False ################################################### # alpha == epsilon ? First(alpha) = { epsilon } ################################################### # <CODE_HERE> # if alpha_is_epsilon: first_alpha.set_epsilon() return first_alpha ################################################### ################################################### # alpha = X1 ... XN # First(X1) subconjunto First(alpha) # epsilon pertenece a First(X1)...First(Xi) ? First(Xi+1) subconjunto de First(X) y First(alpha) # epsilon pertenece a First(X1)...First(XN) ? epsilon pertence a First(X) y al First(alpha) ################################################### # <CODE_HERE> # change = False for i in alpha: if not firsts[i].contains_epsilon: # epsilon pertenece a First(X1)...First(Xi) ? First(Xi+1) subconjunto de First(X) y First(alpha) change = True for j in firsts[i]: first_alpha.add(j) if change: break if not change: # epsilon pertenece a First(X1)...First(XN) ? epsilon pertence a First(X) y al First(alpha) first_alpha.set_epsilon() ################################################### # First(alpha) return first_alpha
def remove_useless_non_terminals(G: Grammar): usefull_non_terminals = ContainerSet() change = True while change: change = False for production in G.Productions: for symbol in production.Right: if symbol.IsNonTerminal: if symbol not in usefull_non_terminals: break else: change |= usefull_non_terminals.add(production.Left) # TODO se puede mejorar for production in G.Productions: if production.Left not in usefull_non_terminals: G.Productions.remove(production) else: for symbol in production.Right: if symbol.IsNonTerminal: if symbol not in usefull_non_terminals: G.Productions.remove(production)