Commit 361e9a92c0e63ceb6a968b59ea25c36fcad2f624
1 parent
f56fda5a
Exists in
master
and in
1 other branch
Corrige aplicação de regras sintáticas
Showing
1 changed file
with
247 additions
and
208 deletions
Show diff stats
src/new/AplicaRegras.py
| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | #LAViD - Laboratório de Aplicações de Vídeo Digital |
| 8 | 8 | |
| 9 | 9 | import platform |
| 10 | +import re | |
| 10 | 11 | import xml.etree.ElementTree as ET |
| 11 | 12 | from os.path import expanduser |
| 12 | 13 | from collections import deque |
| ... | ... | @@ -19,114 +20,110 @@ from nltk import ParentedTree, Tree, draw |
| 19 | 20 | |
| 20 | 21 | class AplicaRegras(object): |
| 21 | 22 | |
| 22 | - # inicializa todos as variaveis | |
| 23 | 23 | def __init__(self): |
| 24 | 24 | self.__root = self.get_root() |
| 25 | 25 | self.dicionarios = LerDicionarios() |
| 26 | + # Dicionário de funcões do campo specific do arquivo de regras | |
| 26 | 27 | self.__especificos = {"advt":self.verificar_adv_tempo, "v":self.verificar_vb_infinitivo, "x":self.verificar_preposicao, |
| 27 | 28 | "c":self.verificar_subst_genero, "a":self.verificar_artigo, "l":self.verificar_vb_ligacao, |
| 28 | 29 | "i":self.verificar_adv_intensidade, "vbi":"zero", "n":self.verificar_vb_muda_negacao, "abmn":"zero", |
| 29 | 30 | "adji":"zero","adjn":"zero", "advi":"zero"} |
| 30 | 31 | |
| 32 | + self.__acoes = {"change_vb":self.get_vb_infinitivo, "concate_intens":self.get_token_intensidade} | |
| 33 | + | |
| 34 | + # Gera arvore a partir do arquivos regras.xml | |
| 31 | 35 | def get_root(self): |
| 32 | 36 | if platform.system() == 'Windows': |
| 33 | 37 | return ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml').getroot() |
| 34 | 38 | return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() |
| 35 | 39 | |
| 40 | + # Aplica regras morfológicas apartir do arquivo regras.xml | |
| 36 | 41 | def aplicar_regras_morfo(self, lista, sint=False): |
| 37 | - self.lista = list(lista) | |
| 38 | - self.quantidade_iter_pular = 0 | |
| 39 | - self.lista_corrigida = [] | |
| 42 | + self.lista = list(lista) # Nova cópia da lista morfológica | |
| 43 | + self.lista_corrigida =[] # Lista morfológica após a aplicação das regras | |
| 40 | 44 | |
| 41 | 45 | it = Iterator() |
| 42 | 46 | it.load(self.lista) |
| 43 | 47 | |
| 44 | - while(it.has_next()): | |
| 48 | + while(it.has_next()): | |
| 45 | 49 | for morpho in self.__root.findall('morphological'): |
| 46 | - self.has_rule = False | |
| 47 | - for rule in morpho.findall('rule'): # procura a tag rule | |
| 50 | + self.has_rule = False # Boolean caso encontre encontre regra compativel | |
| 51 | + for rule in morpho.findall('rule'): | |
| 52 | + # Verifica se a regra está ativa e se o nome da regra, ou o ínicio, é igual a tag de classificação do token atual | |
| 48 | 53 | if rule.find('active').text == "true" and rule.get('name').split("_")[0] == it.get_ticket(): |
| 49 | 54 | count = int(rule.find('count').text) |
| 50 | - self.lista_iteracoes = [] | |
| 51 | - if count == 1: | |
| 52 | - self.lista_iteracoes = [it.get_token()] | |
| 53 | - else: | |
| 54 | - try: | |
| 55 | - self.lista_iteracoes = it.get_interval(count) | |
| 56 | - it.skip(count-1) | |
| 57 | - except: | |
| 58 | - continue | |
| 55 | + self.lista_iteracoes = [] # Lista que conterá todas tuplas referentes a quantidade de classes da regra | |
| 56 | + | |
| 57 | + # Obtém o intervalo de tuplas de acordo com o número de classes da regra | |
| 58 | + try: | |
| 59 | + self.lista_iteracoes = it.get_interval(count) | |
| 60 | + print '# LISTA DA ITERAÇÂO: ' | |
| 61 | + print self.lista_iteracoes | |
| 62 | + except: | |
| 63 | + continue | |
| 59 | 64 | |
| 65 | + # Gera o nome da regra do intervalo de tuplas e verifica se é igual ao nome da regra em si | |
| 60 | 66 | self.nome_regra = self.gerar_nome_regra(self.lista_iteracoes) |
| 61 | - if rule.get('name') == self.nome_regra: # verifica se a regra é aplicavel e a mesma esta ativa | |
| 67 | + if rule.get('name') == self.nome_regra: | |
| 62 | 68 | self.has_rule = True |
| 63 | - self.lista_iteracao_regra = count * [None] | |
| 64 | 69 | self.count_iteracao_regra = -1 |
| 65 | 70 | |
| 66 | - print "REGRA MORFOLÓGICA: " + rule.get('name') | |
| 71 | + print "REGRA MORFOLÓGICA ENCONTRADA: " + rule.get('name') | |
| 67 | 72 | |
| 73 | + self.lista_iteracao_regra = [] # Lista temporária | Insere tokens após a aplicação das regras | |
| 74 | + | |
| 68 | 75 | for classe in rule.iter('class'): # for nas tags class |
| 69 | - | |
| 70 | - title = classe.find('title') | |
| 71 | - newpos = classe.find('newpos') | |
| 76 | + action = classe.find('action') | |
| 72 | 77 | newprop = classe.find('newprop') |
| 73 | 78 | newtoken = classe.find('newtoken') |
| 74 | 79 | newtokenpos = classe.find('newtokenpos') |
| 75 | - self.specific = classe.find('specific') | |
| 80 | + specific = classe.find('specific') | |
| 76 | 81 | |
| 77 | 82 | self.count_iteracao_regra += 1 |
| 78 | 83 | tupla = self.lista_iteracoes[self.count_iteracao_regra] |
| 79 | 84 | |
| 80 | - if self.specific is not None: | |
| 81 | - self.specific = self.__especificos[self.specific.text](tupla[0]) | |
| 82 | - if self.specific == False: | |
| 85 | + if specific is not None: | |
| 86 | + result_specific = self.__especificos[specific.text](tupla[0]) | |
| 87 | + if result_specific is False: | |
| 88 | + print "REGRA MORFOLÓGICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
| 83 | 89 | self.has_rule = False |
| 84 | - self.quantidade_iter_pular = 0 | |
| 85 | 90 | break |
| 86 | 91 | |
| 87 | - if newprop is not None and newtoken is not None: | |
| 88 | - if newtokenpos is not None and newtokenpos.text == "0": | |
| 89 | - self.lista_iteracao_regra[self.count_iteracao_regra] = (newtoken.text + "_" + self.specific, newprop.text) | |
| 90 | - else: | |
| 91 | - self.lista_iteracao_regra[self.count_iteracao_regra] = (self.specific + "_" + newtoken.text, newprop.text) | |
| 92 | - continue | |
| 93 | - | |
| 94 | - elif newprop is not None: | |
| 95 | - self.lista_iteracao_regra.append([self.specific,newprop.text]) | |
| 96 | - | |
| 97 | - if newtoken is not None and newpos is not None: | |
| 98 | - if newtokenpos is not None: | |
| 99 | - lista_merge = count * [None] | |
| 100 | - lista_merge[int(newpos.text)] = tupla[0] | |
| 101 | - lista_merge[int(newtokenpos.text)] = newtoken.text | |
| 102 | - merge_tokens = "_".join(lista_merge) | |
| 103 | - self.lista_iteracao_regra.append([merge_tokens, title.text]) | |
| 104 | - else: | |
| 105 | - self.lista_iteracao_regra.append([tupla[0] + "_" + newtoken.text, title.text]) | |
| 106 | - | |
| 107 | - elif newpos is not None: | |
| 108 | - if newpos.text == "-1": | |
| 109 | - self.lista_corrigida.append(None) | |
| 92 | + if action is not None: | |
| 93 | + action_text = action.text | |
| 94 | + if action_text == "remove": | |
| 95 | + self.lista_iteracao_regra.append(None) | |
| 110 | 96 | continue |
| 111 | - else: | |
| 112 | - self.lista_iteracao_regra[int(newpos.text)] = tupla | |
| 113 | - | |
| 114 | - elif newtoken is not None: | |
| 115 | - token_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][0] | |
| 116 | - ticket_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][1] | |
| 117 | - if newtokenpos is not None and newtokenpos.text == "0": | |
| 118 | - self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + "_" + token_anterior, ticket_anterior] | |
| 119 | - else: | |
| 120 | - self.lista_iteracao_regra[self.count_iteracao_regra] = [token_anterior + "_" + newtoken.text, ticket_anterior] | |
| 121 | - | |
| 122 | - if self.has_rule: | |
| 123 | - self.lista_corrigida.append(filter(None, self.lista_iteracao_regra)[0]) | |
| 124 | - break | |
| 125 | - | |
| 126 | - if (self.has_rule == False): | |
| 97 | + elif action_text == "invert": | |
| 98 | + self.lista_iteracao_regra.reverse() | |
| 99 | + elif self.__acoes.has_key(action_text): | |
| 100 | + result_action = self.__acoes[action_text](tupla[0]).lower() | |
| 101 | + self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
| 102 | + else: | |
| 103 | + self.lista_iteracao_regra.append(tupla) | |
| 104 | + | |
| 105 | + if newprop is not None: | |
| 106 | + self.lista_iteracao_regra[self.count_iteracao_regra][1] = newprop.text | |
| 107 | + | |
| 108 | + if newtoken is not None: | |
| 109 | + if newtokenpos.text == "next": | |
| 110 | + self.lista_iteracao_regra.append([newtoken.text.lower(), "NTK"]) | |
| 111 | + elif newtokenpos.text == "previous": | |
| 112 | + self.lista_iteracao_regra.append(self.lista_iteracao_regra[-1]) | |
| 113 | + self.lista_iteracao_regra[-2] = [newtoken.text.lower(), "NTK"] | |
| 114 | + elif newtokenpos.text == "end": | |
| 115 | + print "TODO" | |
| 116 | + | |
| 117 | + if self.has_rule: | |
| 118 | + it.skip(count-1) | |
| 119 | + self.lista_corrigida.extend(self.lista_iteracao_regra) | |
| 120 | + break | |
| 121 | + | |
| 122 | + if self.has_rule is False: | |
| 123 | + print 'NÃO ACHOU REGRA - ' + it.get_word().encode('utf-8') | |
| 127 | 124 | self.lista_corrigida.append(it.get_token()) #se nao achou regra, entao adiciona a tupla original |
| 128 | 125 | if sint: |
| 129 | - return self.lista_corrigida | |
| 126 | + return self.lista_corrigida | |
| 130 | 127 | return filter(None, self.lista_corrigida) |
| 131 | 128 | |
| 132 | 129 | |
| ... | ... | @@ -135,159 +132,185 @@ class AplicaRegras(object): |
| 135 | 132 | self.adaptar_regras_morfo_arvore(lista, p_arvore) |
| 136 | 133 | for morpho in self.__root.findall('syntactic'): |
| 137 | 134 | for rule in morpho.findall('rule'): # procura a tag rule |
| 138 | - nome_regra = self.corrigir_anotacao(rule.get('name')) | |
| 135 | + nome_regra = self.corrigir_nome_regra(rule.get('name')) | |
| 139 | 136 | regra = self.separar_regra(nome_regra) |
| 140 | 137 | node_pai = tgrep_nodes(p_arvore, regra[0], search_leaves=False) |
| 141 | - if node_pai: | |
| 142 | - node_regra = tgrep_nodes(node_pai[0], regra[1].replace('$', '>'), search_leaves=False) | |
| 138 | + if node_pai and rule.find('active').text == "true": | |
| 139 | + node_pai = node_pai[0] | |
| 140 | + node_regra = tgrep_nodes(node_pai, regra[1].replace('$', '..'), search_leaves=False) | |
| 143 | 141 | if node_regra: |
| 144 | - node_esq = tgrep_nodes(node_pai[0], regra[1], search_leaves=False) | |
| 145 | - node_esq_pos = tgrep_positions(node_pai[0], regra[1], search_leaves=False) | |
| 146 | - node_dir = tgrep_nodes(node_pai[0], regra[2], search_leaves=False) | |
| 147 | - node_dir_pos = tgrep_positions(node_pai[0], regra[2], search_leaves=False) | |
| 148 | - if node_esq and node_dir: | |
| 149 | - print "REGRA SINTÁTICA: " + rule.get('name') | |
| 150 | - subnodes = node_esq + node_dir | |
| 151 | - for subnode in subnodes: | |
| 152 | - self.has_rule = True | |
| 153 | - self.alteracoes_nao_implementadas = [None,None] | |
| 154 | - self.count_iteracao_regra = -1 | |
| 155 | - self.specific = None | |
| 156 | - | |
| 157 | - for classe in rule.findall('class'): | |
| 158 | - self.specific = classe.find('specific') | |
| 159 | - if self.specific is not None: | |
| 160 | - self.specific = self.__especificos[self.specific.text](subnode.leaves()[0]) | |
| 161 | - if self.specific is False: | |
| 162 | - self.has_rule = False | |
| 163 | - break | |
| 164 | - | |
| 165 | - # modelo: [['node_esq', ['token', 'ticket']],['node_dir', ['token', 'ticket']]] | |
| 166 | - for classe in rule.iter('class'): | |
| 167 | - title = classe.find('title') | |
| 168 | - if subnode.label() == title.text: | |
| 169 | - newpos = classe.find('newpos') | |
| 170 | - newprop = classe.find('newprop') | |
| 171 | - newtoken = classe.find('newtoken') | |
| 172 | - newtokenpos = classe.find('newtokenpos') | |
| 173 | - | |
| 174 | - | |
| 175 | - self.count_iteracao_regra += 1 | |
| 176 | - | |
| 177 | - if self.specific is not None: | |
| 178 | - self.specific = self.__especificos[self.specific.text](subnode.leaves()[0]) | |
| 179 | - if self.specific is False: | |
| 180 | - self.has_rule = False | |
| 181 | - break | |
| 182 | - | |
| 183 | - if newprop is not None and newtoken is not None: | |
| 184 | - if newtokenpos is not None and newtokenpos.text == "0": | |
| 185 | - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([newtoken.text + "_" + self.specific, newprop.text]) | |
| 186 | - else: | |
| 187 | - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([self.specific + "_" + newtoken.text, newprop.text]) | |
| 188 | - continue | |
| 189 | - | |
| 190 | - elif newprop is not None: | |
| 191 | - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([self.specific,newprop.text]) | |
| 192 | - | |
| 193 | - if newtoken is not None and newpos is not None: | |
| 194 | - if newtokenpos is not None: | |
| 195 | - lista_merge = count * [None] | |
| 196 | - lista_merge[int(newpos.text)] = subnode.leaves()[0] | |
| 197 | - lista_merge[int(newtokenpos.text)] = newtoken.text | |
| 198 | - merge_tokens = "_".join(lista_merge) | |
| 199 | - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([merge_tokens, title.text]) | |
| 200 | - else: | |
| 201 | - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([subnode.leaves()[0] + "_" + newtoken.text, title.text]) | |
| 142 | + node_esq_pos = tgrep_positions(node_pai, regra[1], search_leaves=False) | |
| 143 | + node_dir_pos = tgrep_positions(node_pai, regra[2], search_leaves=False) | |
| 144 | + if node_esq_pos and node_dir_pos: | |
| 145 | + print "REGRA SINTÁTICA ENCONTRADA: " + rule.get('name') | |
| 146 | + nodes_positions = node_esq_pos + node_dir_pos | |
| 147 | + self.count = -1 | |
| 148 | + self.has_rule = True | |
| 149 | + | |
| 150 | + count_temp = -1 | |
| 151 | + for classe in rule.findall('class'): | |
| 152 | + count_temp += 1 | |
| 153 | + leaves = node_pai[nodes_positions[count_temp]].leaves() | |
| 154 | + token = filter(None, leaves)[0] | |
| 155 | + specific = classe.find('specific') | |
| 156 | + if specific is not None: | |
| 157 | + result_specific = self.__especificos[specific.text](token) | |
| 158 | + if result_specific is False: | |
| 159 | + self.has_rule = False | |
| 160 | + | |
| 161 | + if self.has_rule is False: | |
| 162 | + print "REGRA SINTÁTICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
| 163 | + break | |
| 202 | 164 | |
| 203 | - elif newpos is not None: | |
| 204 | - if newpos.text == "-1": | |
| 205 | - alteracoes_nao_implementadas[self.count_iteracao_regra].append(None) | |
| 206 | - continue | |
| 207 | - else: | |
| 208 | - #TODO | |
| 209 | - if int(newpos.text) == 0: | |
| 210 | - self.alteracoes_nao_implementadas[int(newpos.text)] = subnode | |
| 211 | - | |
| 212 | - elif newtoken is not None: | |
| 213 | - token_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][0] | |
| 214 | - ticket_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][1] | |
| 215 | - if newtokenpos is not None and newtokenpos.text == "0": | |
| 216 | - self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + " " + token_anterior, ticket_anterior] | |
| 165 | + nodes_deleted = [] | |
| 166 | + | |
| 167 | + for classe in rule.iter('class'): | |
| 168 | + action = classe.find('action') | |
| 169 | + newprop = classe.find('newprop') | |
| 170 | + | |
| 171 | + self.count += 1 | |
| 172 | + | |
| 173 | + if action is not None: | |
| 174 | + action_text = action.text | |
| 175 | + | |
| 176 | + if action_text == "remove": | |
| 177 | + pos_del = nodes_positions[self.count] | |
| 178 | + nodes_deleted.append(node_pai[pos_del]) | |
| 179 | + node_pai[pos_del] = None | |
| 180 | + continue | |
| 181 | + | |
| 182 | + elif action_text == "invert": | |
| 183 | + aux1 = node_pai[nodes_positions[self.count]] | |
| 184 | + aux2 = node_pai[nodes_positions[self.count+1]] | |
| 185 | + node_pai[nodes_positions[self.count]] = None | |
| 186 | + node_pai[nodes_positions[self.count+1]] = None | |
| 187 | + node_pai[nodes_positions[self.count]] = aux2 | |
| 188 | + node_pai[nodes_positions[self.count+1]] = aux1 | |
| 189 | + | |
| 190 | + ''' | |
| 191 | + elif self.__acoes.has_key(action_text): | |
| 192 | + leaves = node_pai[nodes_positions[self.count]].leaves() | |
| 193 | + token = filter(None, leaves)[0] | |
| 194 | + result_action = self.__acoes[action_text](token) | |
| 195 | + | |
| 196 | + #self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
| 197 | + nodes_positions[self.count] = 'TODO' | |
| 198 | + | |
| 199 | + if action_text == "concate_intens": | |
| 200 | + leaves_prev = node_pai[nodes_positions[self.count-1]].leaves() | |
| 201 | + token_prev = filter(None, leaves_prev)[0] | |
| 202 | + title_text = classe.find('title').text | |
| 203 | + if title_text == "ADV-R": | |
| 204 | + node_prev = nodes_deleted.pop() | |
| 205 | + label_prev = node_prev[0][0].label() | |
| 206 | + token_prev = filter(None, node_pai[nodes_positions[count_temp-1]].leaves())[0] | |
| 207 | + token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
| 208 | + token_concate = token_prev + "_" + token | |
| 209 | + node_pai[nodes_positions[count_temp-1]][0][0][0] = token_concate | |
| 210 | + newprop = "" | |
| 211 | + if label_prev[:-2] == "VB": | |
| 212 | + newprop = "VBi" | |
| 213 | + elif label_prev[:-3] == "ADJ": | |
| 214 | + newprop = "ADJi" | |
| 215 | + | |
| 216 | + # TODO: Verifica qual newprop adicionada e remove o nó corrente | |
| 217 | + node_pai[nodes_positions[count_temp-1]][0][0].set_label(newprop) | |
| 218 | + pos_del = nodes_positions[self.count] | |
| 219 | + node_pai[pos_del] = None | |
| 220 | + | |
| 217 | 221 | else: |
| 218 | - self.lista_iteracao_regra[self.count_iteracao_regra] = [token_anterior + " " + newtoken.text, ticket_anterior] | |
| 222 | + token_prev = filter(None, nodes_deleted.pop().leaves())[0] | |
| 223 | + token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
| 224 | + token_concate = token + "_" + token_prev | |
| 225 | + node_pai[nodes_positions[count_temp]][0][0][0] = token_concate | |
| 219 | 226 | |
| 220 | - if self.has_rule: | |
| 221 | - print self.alteracoes_nao_implementadas[0] | |
| 222 | - self.lista_corrigida.append(filter(None, self.lista_iteracao_regra)[0]) | |
| 223 | - break | |
| 227 | + elif action_text == "concate_neg": | |
| 228 | + print "TODO" | |
| 229 | + ''' | |
| 224 | 230 | |
| 231 | + if newprop is not None: | |
| 232 | + node_pai[nodes_positions[self.count]].set_label(newprop.text) | |
| 233 | + | |
| 234 | + break | |
| 235 | + | |
| 225 | 236 | return self.converter_arv_para_lista(p_arvore) |
| 237 | + | |
| 226 | 238 | |
| 239 | + # Aplica regras morfológicas na árvore sintática | |
| 227 | 240 | def adaptar_regras_morfo_arvore(self, lista, arvore): |
| 228 | 241 | lista_pos_arv = [] |
| 242 | + # Pega as posições das classificações morfológicas dos tokens na arvore sintática | |
| 229 | 243 | for tupla in lista: |
| 230 | - string_grep = self.corrigir_anotacao(tupla[1]) + " < " + tupla[0].lower() | |
| 244 | + string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + tupla[0].lower() | |
| 231 | 245 | node = tgrep_positions(arvore, string_grep) |
| 246 | + if not node: | |
| 247 | + string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + self.remover_acento(tupla[0].lower()) | |
| 248 | + node = tgrep_positions(arvore, string_grep) | |
| 232 | 249 | if node[0] in lista_pos_arv: |
| 233 | 250 | node.reverse() |
| 234 | 251 | lista_pos_arv.append(node[0]) |
| 252 | + | |
| 253 | + # Aplica regras morfológicas na lista | |
| 235 | 254 | morfo = self.aplicar_regras_morfo(lista, sint=True) |
| 255 | + | |
| 256 | + # Corrige arvore de acordo com a lista após aplicar as regras morfológicas | |
| 236 | 257 | for i in range(0, len(morfo)): |
| 258 | + if morfo[i] is not None and morfo[i][1] == "NTK": | |
| 259 | + new_node = self.gerar_no(morfo[i]) | |
| 260 | + arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node) | |
| 261 | + try: | |
| 262 | + lista_pos_arv.insert(i,lista_pos_arv[i]) | |
| 263 | + except: | |
| 264 | + continue | |
| 265 | + | |
| 237 | 266 | arv_ticket = arvore[lista_pos_arv[i]].label() |
| 238 | 267 | arv_token = arvore[lista_pos_arv[i]][0] |
| 268 | + | |
| 239 | 269 | if morfo[i] is None: |
| 240 | - arvore[lista_pos_arv[i][:-1]] = None | |
| 270 | + arvore[lista_pos_arv[i]] = None | |
| 271 | + | |
| 241 | 272 | elif arv_token != morfo[i][0] and arv_ticket != morfo[i][1]: |
| 242 | 273 | arvore[lista_pos_arv[i]][0] = morfo[i][0] |
| 243 | - arvore[lista_pos_arv[i]].set_label(self.corrigir_anotacao(morfo[i][1])) | |
| 274 | + arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
| 275 | + | |
| 244 | 276 | elif arv_token != morfo[i][0]: |
| 245 | 277 | arvore[lista_pos_arv[i]][0] = morfo[i][0] |
| 278 | + | |
| 246 | 279 | elif arv_ticket != morfo[i][1]: |
| 247 | - arvore[lista_pos_arv[i]].set_label(self.corrigir_anotacao(morfo[i][1])) | |
| 248 | - else: | |
| 249 | - continue | |
| 250 | - | |
| 251 | - nodes_none = tgrep_positions(arvore, 'None') | |
| 252 | - for node in nodes_none: | |
| 253 | - arvore[node[:-1]].remove(None) | |
| 280 | + arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
| 254 | 281 | |
| 282 | + # Converte árvore sintática para uma lista de tuplas (igual a lista morfológica) | |
| 255 | 283 | def converter_arv_para_lista(self, arvore): |
| 256 | - folhas = arvore.leaves() | |
| 284 | + folhas = filter(None, arvore.leaves()) | |
| 257 | 285 | lista_nodes = [] |
| 258 | 286 | for folha in folhas: |
| 259 | 287 | pos = tgrep_positions(arvore, folha) |
| 260 | 288 | node = arvore[pos[0][:-1]] |
| 261 | 289 | #decode node[0] |
| 262 | - lista_nodes.append([node[0], self.corrigir_anotacao(node.label())]) | |
| 290 | + lista_nodes.append([node[0], self.corrigir_nome_regra(node.label())]) | |
| 263 | 291 | return lista_nodes |
| 264 | 292 | |
| 293 | + def remover_acento(self, texto): | |
| 294 | + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') | |
| 265 | 295 | |
| 266 | - def criar_ptree(self, s): | |
| 296 | + # Gera um ParentedTree do NLTK apartir da string recebida | |
| 297 | + def gerar_no(self, s): | |
| 267 | 298 | all_ptrees = [] |
| 268 | - ptree = ParentedTree.convert(Tree.fromstring(s)) | |
| 299 | + t_string = '('+s[1] + ' ' + s[0]+')' | |
| 300 | + ptree = ParentedTree.convert(Tree.fromstring(t_string)) | |
| 269 | 301 | all_ptrees.extend(t for t in ptree.subtrees() |
| 270 | 302 | if isinstance(t, Tree)) |
| 271 | 303 | return ptree |
| 272 | 304 | |
| 273 | - def separar_new_tokens(self, lista): | |
| 274 | - for index, tupla in enumerate(lista): | |
| 275 | - if '_' in tupla[0]: | |
| 276 | - if 'VB' in tupla[1]: | |
| 277 | - token_split = tupla[0].split('_') | |
| 278 | - tupla[0] = token_split[0] | |
| 279 | - lista.append([token_split[1],'NTK']) | |
| 280 | - else: | |
| 281 | - token_split = tupla[0].split('_') | |
| 282 | - tupla[0] = token_split[0] | |
| 283 | - lista.insert(index+1, [token_split[1],'NTK']) | |
| 284 | - | |
| 285 | - def corrigir_anotacao(self, anotacao): | |
| 305 | + # Corrige nome da regra descrita no arquivo de regras para como está na árvore sintática | |
| 306 | + def corrigir_nome_regra(self, anotacao): | |
| 286 | 307 | split = anotacao.split('_') |
| 287 | 308 | for i in range(0, len(split)): |
| 288 | - split[i] = split[i].replace('-','_') | |
| 309 | + split[i] = re.sub(r"[-+]","_", split[i]) | |
| 310 | + split[i] = re.sub(r"\$","_S",split[i]) | |
| 289 | 311 | return "-".join(split).encode('utf-8') |
| 290 | 312 | |
| 313 | + # Separa a regra por nó pai e seus filhos | |
| 291 | 314 | def separar_regra(self, regra): |
| 292 | 315 | split = regra.split("(") |
| 293 | 316 | split[1] = split[1].replace(")","").split("-") |
| ... | ... | @@ -298,22 +321,24 @@ class AplicaRegras(object): |
| 298 | 321 | split[2] = ' $ '.join(split[2]) |
| 299 | 322 | return split |
| 300 | 323 | |
| 324 | + # Gera nome de regra apartir de uma lista | |
| 301 | 325 | def gerar_nome_regra(self, lista): |
| 302 | - self.__nomeRegra = [] | |
| 326 | + nome_regra = [] | |
| 303 | 327 | for t in lista: |
| 304 | - self.__nomeRegra.append(t[1]) | |
| 305 | - return "_".join(self.__nomeRegra) | |
| 328 | + nome_regra.append(t[1]) | |
| 329 | + return "_".join(nome_regra) | |
| 306 | 330 | |
| 307 | 331 | def verificar_adv_tempo(self, token): |
| 308 | 332 | for tupla in self.lista: |
| 309 | 333 | if self.dicionarios.has_adverbio_tempo(tupla[0]): |
| 310 | - return self.verificar_vb_infinitivo(token) | |
| 334 | + return True | |
| 311 | 335 | return False |
| 312 | 336 | |
| 337 | + def verificar_excecao_plural(self, token): | |
| 338 | + return self.dicionarios.has_excecao_plural(token) | |
| 339 | + | |
| 313 | 340 | def verificar_vb_infinitivo(self, token): |
| 314 | - if self.dicionarios.has_verbo_infinitivo(token): | |
| 315 | - return self.dicionarios.get_verbo_infinitivo(token) | |
| 316 | - return False | |
| 341 | + return self.dicionarios.has_verbo_infinitivo(token) | |
| 317 | 342 | |
| 318 | 343 | def verificar_preposicao(self, token): |
| 319 | 344 | return self.dicionarios.has_preposicao(token) |
| ... | ... | @@ -331,29 +356,38 @@ class AplicaRegras(object): |
| 331 | 356 | return self.dicionarios.has_adverbio_intensidade(token) |
| 332 | 357 | |
| 333 | 358 | def verificar_vb_muda_negacao(self, token): |
| 334 | - if self.dicionarios.has_verbo_muda_negacao(token): | |
| 335 | - return self.dicionarios.get_verbo_muda_negacao(token) | |
| 336 | - return False | |
| 359 | + return self.dicionarios.has_verbo_muda_negacao(token) | |
| 360 | + | |
| 361 | + def get_vb_infinitivo(self, token): | |
| 362 | + if self.dicionarios.has_verbo_infinitivo(token): | |
| 363 | + return self.dicionarios.get_verbo_infinitivo(token) | |
| 364 | + return token | |
| 365 | + | |
| 366 | + def get_token_intensidade(self, token): | |
| 367 | + print 'TODO' | |
| 368 | + | |
| 337 | 369 | |
| 370 | + # Simplifica a sentença para que possa evitar a ditalogia | |
| 338 | 371 | def simplificar_sentenca(self, lista): |
| 372 | + lista_simplificada = list(lista) | |
| 339 | 373 | it = Iterator() |
| 340 | - it.load(lista) | |
| 374 | + it.load(lista_simplificada) | |
| 341 | 375 | num = False |
| 342 | - nova_lista = [] | |
| 343 | 376 | while(it.has_next()): |
| 344 | - token = it.get_word() | |
| 345 | 377 | tag = it.get_ticket() |
| 346 | 378 | |
| 347 | 379 | if tag == "NUM": |
| 348 | 380 | num = True |
| 349 | 381 | |
| 350 | - if tag[-2:] == "-P": | |
| 351 | - singular = self.analisar_plural(token) | |
| 352 | - lista[it.get_count()][0] = singular | |
| 382 | + if tag[-2:] == "-P" and self.verificar_excecao_plural(it.get_word()): | |
| 383 | + singular = self.analisar_plural(it.get_word()) | |
| 384 | + lista_simplificada[it.get_count()][0] = singular | |
| 353 | 385 | |
| 354 | - if num: return self.converter_extenso(nova_lista) | |
| 355 | - return nova_lista | |
| 386 | + if num: | |
| 387 | + return self.converter_extenso(lista_simplificada) | |
| 388 | + return lista_simplificada | |
| 356 | 389 | |
| 390 | + # Alterar uma palavra do plural para o singular | |
| 357 | 391 | def analisar_plural(self, token): |
| 358 | 392 | if(token[-3:] == "OES" or token[-2:] == "AES" or token[-2:] == "AOS"): |
| 359 | 393 | return token[0:-3]+"AO" |
| ... | ... | @@ -376,32 +410,37 @@ class AplicaRegras(object): |
| 376 | 410 | else: |
| 377 | 411 | return token |
| 378 | 412 | |
| 413 | + # Converter número por extenso para numeral | |
| 379 | 414 | def converter_extenso(self, lista): |
| 380 | - lista_aux = [] | |
| 381 | - index_deleted = [] | |
| 415 | + lista_extensos = [] | |
| 416 | + indices_deletar = [] | |
| 382 | 417 | count = 0 |
| 383 | - is_running = False | |
| 418 | + is_sequence = False | |
| 384 | 419 | |
| 385 | 420 | for i in range(0, len(lista)): |
| 386 | 421 | token = lista[i][0] |
| 387 | 422 | tag = lista[i][1] |
| 388 | 423 | if tag == "NUM": |
| 389 | - if (is_running is False and len(lista_aux) == count): | |
| 390 | - lista_aux.append([i,[token]]) | |
| 391 | - is_running = True | |
| 424 | + # Verifico se não há sequência de obtenção de extenso em andamento para começar a obter um nova sequência | |
| 425 | + if (is_sequence is False): # and len(lista_extensos) == count (???) | |
| 426 | + lista_extensos.append([i,[token]]) # i = Posição do primeiro extenso encontrado, token = número por extenso | |
| 427 | + is_sequence = True | |
| 392 | 428 | else: |
| 393 | - lista_aux[count][1].append(token) | |
| 394 | - index_deleted.append(i) | |
| 395 | - elif (is_running): | |
| 429 | + lista_extensos[count][1].append(token) # Pego número por extenso que está na sequência e adiciona na lista | |
| 430 | + indices_deletar.append(i) # Insiro indice na lista para ser removido depois | |
| 431 | + elif (is_sequence): | |
| 432 | + # Se o token anterior e o próximo foram classificados como número, e o token atual como conjunção, significa que podemos remove-lo | |
| 396 | 433 | if ((lista[i-1][1] == "NUM") and (lista[i+1][1] == "NUM") and (tag == "CONJ")): |
| 397 | - index_deleted.append(i) | |
| 434 | + indices_deletar.append(i) | |
| 398 | 435 | else: |
| 399 | - is_running = False | |
| 436 | + # A sequência foi quebrada, o que significa que selecionamos o extenso do número por completo | |
| 437 | + # Podemos agora procurar por outra sequencia de número por extenso na lista | |
| 438 | + is_sequence = False | |
| 400 | 439 | count += 1 |
| 401 | 440 | |
| 402 | - for i in lista_aux: | |
| 403 | - ext = extenso(' '.join(i[1])) | |
| 404 | - lista[i[0]] = [ext, "NUM"] | |
| 441 | + for extenso in lista_extensos: | |
| 442 | + ext = convert_extenso(' '.join(extenso[1])) | |
| 443 | + lista[extenso[0]] = [ext, "NUM"] | |
| 405 | 444 | |
| 406 | - deque((list.pop(lista, i) for i in sorted(index_deleted, reverse=True)), maxlen=0) | |
| 445 | + deque((list.pop(lista, i) for i in sorted(indices_deletar, reverse=True)), maxlen=0) | |
| 407 | 446 | return lista |
| 408 | 447 | \ No newline at end of file | ... | ... |