Exemplo n.º 1
0
 def verificar_fatoravel(self, gramatica, n):
     if gramatica.existe_recursao_esq():
         raise OperacaoError(" a gramática possui derivações à esquerda")
     if n > 0:
         return gramatica.eh_fatoravel_em_n_passos(n)
     else:
         raise OperacaoError(" n deve ser um inteiro maior que zero")
Exemplo n.º 2
0
 def remover_simples(self, gramatica):
     if not gramatica.existe_producoes_simples():
         raise OperacaoError(" a gramática não possui produções simples")
     elif not gramatica.eh_epsilon_livre():
         raise OperacaoError(" a gramática deve ser epsilon-livre")
     else:
         nova_gramatica, na = gramatica.remove_simples()
         return nova_gramatica, na
	def remove_recursao_esq(self):
		if self.existe_recursao_esq():
			raise OperacaoError(" a gramática não possui recursão à esquerda")
		elif not self.eh_propria():
			raise OperacaoError(" a gramática não é própria")
		else:
			print()
			pass
Exemplo n.º 4
0
    def transformar_em_propria(self, gramatica):
        if gramatica.eh_propria():
            raise OperacaoError(" a gramática já é própria")
        else:
            resultantes = []
            conjuntos = []

            try:
                epsilon_livre, ne = self.transformar_epsilon_livre(gramatica)
                resultantes.append(epsilon_livre)
                conjuntos.append(ne)
            except OperacaoError as e:
                epsilon_livre = gramatica
                conjuntos.append(epsilon_livre.obtem_ne())

            try:
                sem_simples, na = self.remover_simples(epsilon_livre)
                resultantes.append(sem_simples)
                conjuntos.append(na)
            except OperacaoError as e:
                sem_simples = epsilon_livre
                conjuntos.append(sem_simples.obtem_na())

            try:
                sem_inuteis, nf_vi = self.remover_inuteis(sem_simples)
                resultantes.extend(sem_inuteis)
                conjuntos.extend(nf_vi)
            except OperacaoError as e:
                sem_inuteis = [sem_simples]
                conjuntos.extend([sem_simples.obtem_nf(), sem_simples.obtem_vi()])

            propria = sem_inuteis[-1]
            propria.set_nome(gramatica.get_nome() + " (própria)")

            return resultantes, conjuntos
Exemplo n.º 5
0
    def remover_inuteis(self, gramatica):
        if not gramatica.existem_inuteis():
            raise OperacaoError(" a gramática não possui produções inúteis")
        else:
            resultantes = []
            conjuntos = []

            try:
                sem_infertil, nf = self.remover_inferteis(gramatica)
                resultantes.append(sem_infertil)
                conjuntos.append(nf)
            except OperacaoError as e:
                sem_infertil = gramatica
                conjuntos.append(sem_infertil.obtem_nf())

            try:
                sem_inalcancavel, vi = self.remover_inalcancaveis(sem_infertil)
                conjuntos.append(vi)
            except OperacaoError as e:
                sem_inalcancavel = sem_infertil
                conjuntos.append(sem_inalcancavel.obtem_vi())

            sem_inalcancavel.set_nome(gramatica.get_nome() + " (sem inúteis)")
            resultantes.append(sem_inalcancavel)

            return resultantes, conjuntos
	def remove_inferteis(self):
		if not self.existe_inferteis():
			raise OperacaoError(" a gramática não possui nenhuma produção infértil")
		else:
			sem_inferteis = GLCEditavel(self)
			nf = self.obtem_nf()  # Símbolos férteis

			if self._vn_inicial not in nf:
				raise OperacaoError(" a gramática representa uma linguagem vazia")

			inferteis = self._nao_terminais.difference(nf)
			for simbolo in inferteis:
				sem_inferteis.remove_vn(simbolo)

			glc = sem_inferteis.obter_glc_padrao(self.get_nome() + " (sem inférteis)")
			return glc, inferteis
	def remove_simples(self):
		if not self.existe_producoes_simples():
			raise OperacaoError(" a gramática não possui nenhuma produção simples")
		else:
			na = self.obtem_na()

			sem_simples = GLCEditavel(self)
			# Remove produções simples
			for A in sem_simples._conjunto_producoes:
				producoes = list(sem_simples._conjunto_producoes[A])
				for derivacao in producoes:
					if derivacao.eh_simples():
						sem_simples.remove_producao(A, derivacao)

			# Adiciona produções
			for A in sem_simples._conjunto_producoes:
				for B in set(na[A]) - set([A]):
					for prod in sem_simples._conjunto_producoes[B]:
						sem_simples.adiciona_producao(A, Producao(A, list(prod.get_derivacao())))

			# Atualiza produções
			houve_mudança = True
			while houve_mudança:
				houve_mudança = False
				for A in sem_simples._conjunto_producoes:
					for B in set(na[A]) - set([A]):
						diff = set(sem_simples._conjunto_producoes[B]) - set(sem_simples._conjunto_producoes[A])
						if len(diff) > 0:
							for prod in diff:
								sem_simples.adiciona_producao(A, Producao(A, list(prod.get_derivacao())))
								houve_mudança = True

			glc = sem_simples.obter_glc_padrao(self.get_nome() + " (sem prod. simples)")
			return glc, na
	def transforma_epsilon_livre(self):
		if self.eh_epsilon_livre():
			raise OperacaoError(" a gramática já é epsilon-livre")
		else:
			sem_epsilon = GLCEditavel(self)
			ne = self.obtem_ne()  # Símbolos que derivam &

			for A in self._nao_terminais:
				producoes = self._conjunto_producoes[A]
				for x in producoes:
					indices = []
					prod = x.get_derivacao()
					if prod.eh_epsilon():
						sem_epsilon.remove_producao(A, x)
					else:
						for y in prod:
							if y in ne:
								indices.append(prod.index(y))
						if len(prod) > 1 and len(indices) > 0:
							powerset = list(self.__powerset(indices))
							powerset.pop(0)  # Remove conjunto vazio
							for item in powerset:
								nova_prod = list(prod)
								index = ''.join(str(s) for s in list(item))
								index = int(index)
								nova_prod.pop(index)
								sem_epsilon.adiciona_producao(A, Producao(A, nova_prod))

		if self._vn_inicial in ne:
			prod = Producao(self._vn_inicial, [Vt(epsilon)])
			sem_epsilon.adiciona_producao(self._vn_inicial, prod)

		glc = sem_epsilon.obter_glc_padrao(self.get_nome() + " (& livre)")
		return glc, ne
	def remove_inalcancaveis(self):
		if not self.existe_inalcancavel():
			raise OperacaoError(" a gramática não possui nenhuma produção inalcançável")
		else:
			sem_inalc = GLCEditavel(self)
			vi = self.obtem_vi() # Símbolos alcançáveis
			inalcancaveis = self._nao_terminais.difference(vi)
			for simbolo in inalcancaveis:
				sem_inalc.remove_vn(simbolo)

			glc = sem_inalc.obter_glc_padrao(self.get_nome() + " (sem inalcançáveis)")
			return glc, inalcancaveis
Exemplo n.º 10
0
    def remover_recursao(self, gramatica):
        if not gramatica.existe_recursao_esq():
            raise OperacaoError(" a gramática não possui nenhuma recursão à esquerda")
        else:
            resultantes = []

            try:
                propria, conjuntos = self.transformar_em_propria(gramatica)
                resultantes.extend(propria)
            except OperacaoError as e:
                propria = [gramatica]

            sem_recursao, recursoes = propria[-1].remove_recursao_esq()
            resultantes.append(sem_recursao)

            return resultantes, recursoes
Exemplo n.º 11
0
 def remover_inalcancaveis(self, gramatica):
     if not gramatica.existe_inalcancavel():
         raise OperacaoError(" a gramática não possui produções inalcançáveis")
     else:
         nova_gramatica, vi = gramatica.remove_inalcancaveis()
         return nova_gramatica, vi
Exemplo n.º 12
0
 def remover_inferteis(self, gramatica):
     if not gramatica.existe_inferteis():
         raise OperacaoError(" a gramática não possui produções inférteis")
     else:
         nova_gramatica, nf = gramatica.remove_inferteis()
         return nova_gramatica, nf
Exemplo n.º 13
0
 def transformar_epsilon_livre(self, gramatica):
     if gramatica.eh_epsilon_livre():
         raise OperacaoError(" a gramática já é epsilon-livre")
     else:
         nova_gramatica, ne = gramatica.transforma_epsilon_livre()
         return nova_gramatica, ne
	def eh_fatoravel_em_n_passos(self, n):
		if self.esta_fatorada():
			raise OperacaoError(" a gramática já está fatorada")
		else:
			i = 0
			fatorada = GLCEditavel(self)
			nao_terminais = []
			nao_terminais.extend(self._nao_terminais)
			while nao_terminais:
				nt = nao_terminais[0]
				if not fatorada.__nt_esta_fatorado(fatorada, nt):
					if i < n:
						producoes = list(fatorada._conjunto_producoes[nt])
						j = 0
						firsts = []
						while j < len(producoes)-1:
							k = j + 1
							producao = producoes[j]
							first_prod = fatorada.first_producao(producao)
							if not(first_prod in firsts):  # Se esse first já não foi analizado
								outras_prod = []
								while k < len(producoes):
									prod = producoes[k]
									first_outra_prod = fatorada.first_producao(prod)
									if first_outra_prod not in firsts:
										intersec = first_prod.intersection(first_outra_prod)
										if intersec:
											firsts.extend(intersec)
											outras_prod.append(prod)
									k += 1
								if outras_prod:
									todas_producoes = list(set(outras_prod).union(set([producao])))
									novas_prod = []
									for x in todas_producoes:
										if len(x.get_derivacao()) > 0:
											simb = x.get_derivacao()[0]
											novas_prod.append(x)
											if not isinstance(simb, Vt):  # ND indireto
												prox_deriv = []
												prox_deriv.append(simb)
												while prox_deriv:
													outro_simb = prox_deriv[0]
													derivacao = fatorada._conjunto_producoes[outro_simb]

													indexes = []  # indices das produções com o nao terminal
													for y in novas_prod:
														if y.get_derivacao()[0] == outro_simb:
															indexes.append(novas_prod.index(y))

													for d in derivacao:
														for index in indexes:
															di = list(novas_prod[index].get_derivacao())
															di.pop(0)
															if di is None:
																di = []
															nova_deriv = []
															if not d.eh_epsilon() or di == list():
																nova_deriv = list(d.get_derivacao())
															nova_deriv.extend(di)
															novas_prod.append(Producao(novas_prod[index].get_gerador(), nova_deriv))
															if isinstance(nova_deriv[0], Vn):
																prox_deriv.append(nova_deriv[0])
													v = 0
													for index in indexes:
														if index-v < 0:
															novas_prod.pop(0)
														else:
															novas_prod.pop(index-v)
														v += 1
													prox_deriv.remove(outro_simb)

									# Commom substring
									a = 0
									b = 1
									commom_subtrings = set()
									removidos = set()
									while a < len(novas_prod):
										sa = str(novas_prod[a])
										b = a + 1
										while b < len(novas_prod):
											if a != b:
												start = self.__common_start(sa, str(novas_prod[b]))
												if start != '' and start != ' ':
													strings = set(commom_subtrings)
													if strings:
														for c in strings:
															com_sub = self.__common_start(c, start)
															if com_sub != '' and com_sub != ' ':
																commom_subtrings.add(com_sub)
																removidos.add(c)
															else:
																commom_subtrings.add(start)
													else:
														commom_subtrings.add(start)
											b += 1
										a += 1
									for r in removidos:
										commom_subtrings.remove(r)

									adicionar = list(novas_prod)
									for common_s in commom_subtrings:
										# Fatora
										simbolos = []
										common_s = common_s.replace(" ", "")
										for s in common_s:
											if s.islower():
												simbolos.append(Vt(s))
											else:
												simbolos.append(Vn(s))
										novo_nt = fatorada.novo_simbolo(str(nt)[0])
										novo_nt = Vn(novo_nt)
										simbolos.append(novo_nt)
										nao_terminais.append(novo_nt)
										fatorada.adiciona_nao_terminal(novo_nt)
										fatorada.adiciona_producao(nt, Producao(nt, simbolos))

										# Produções do novo não terminal
										fim_commom = len(common_s)
										for p in novas_prod:
											if p.get_derivacao()[0] == simbolos[0]:
												resto_prod = p.get_derivacao()[fim_commom:]
												if len(resto_prod) == 0:
													resto_prod = [Vt("&")]
												fatorada.adiciona_producao(novo_nt, Producao(novo_nt, resto_prod))
												adicionar.remove(p)

									for a in adicionar:
										fatorada.adiciona_producao(nt, Producao(nt, a.get_derivacao()))

									# Remover producoes não fatoradas anteriores
									for p in todas_producoes:
										fatorada.remove_producao(nt, p)

									i += 1  # Um passo feito
							j += 1
					else:
						return False, None
				nao_terminais.remove(nt)

			glc = fatorada.obter_glc_padrao(self.get_nome() + "(fatorada)")
			return True, glc