Commit 30cb1371e39accf566d309905b7938fb4065b16c
Exists in
master
Merge branch 'devel'
Showing
10 changed files
with
290 additions
and
226 deletions
Show diff stats
data/preposicoes.csv
install/linux/install.sh
@@ -30,7 +30,7 @@ read -r -p "Deseja fazer o download das dependências? [Y/n] " response | @@ -30,7 +30,7 @@ read -r -p "Deseja fazer o download das dependências? [Y/n] " response | ||
30 | echo -e "# Instalando dependências...\n" | 30 | echo -e "# Instalando dependências...\n" |
31 | sudo apt-get update | 31 | sudo apt-get update |
32 | sudo apt-get install -y python-dev python-setuptools python-pip python-yaml python-numpy python-matplotlib | 32 | sudo apt-get install -y python-dev python-setuptools python-pip python-yaml python-numpy python-matplotlib |
33 | - sudo pip install nltk nltk_tgrep --upgrade | 33 | + sudo pip install nltk==3.0.5 nltk_tgrep --upgrade |
34 | 34 | ||
35 | fi | 35 | fi |
36 | 36 |
src/AplicaRegras.py
@@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
6 | 6 | ||
7 | #LAViD - Laboratório de Aplicações de Vídeo Digital | 7 | #LAViD - Laboratório de Aplicações de Vídeo Digital |
8 | 8 | ||
9 | -import platform | ||
10 | import re | 9 | import re |
11 | import xml.etree.ElementTree as ET | 10 | import xml.etree.ElementTree as ET |
12 | from os.path import expanduser | 11 | from os.path import expanduser |
@@ -38,12 +37,10 @@ class AplicaRegras(object): | @@ -38,12 +37,10 @@ class AplicaRegras(object): | ||
38 | # Gera arvore a partir do arquivos regras.xml | 37 | # Gera arvore a partir do arquivos regras.xml |
39 | def get_root(self): | 38 | def get_root(self): |
40 | '''Verifica qual o SO e gera o path de onde se encontra o diretório data. | 39 | '''Verifica qual o SO e gera o path de onde se encontra o diretório data. |
41 | - ''' | ||
42 | - if "TRANSLATE_DATA" in environ: | 40 | + ''' |
41 | + if "TRANSLATE_DATA" in environ: | ||
43 | arq_regras = path.join(environ.get("TRANSLATE_DATA"), "regras.xml") | 42 | arq_regras = path.join(environ.get("TRANSLATE_DATA"), "regras.xml") |
44 | return ET.parse(arq_regras).getroot() | 43 | return ET.parse(arq_regras).getroot() |
45 | - elif platform.system() == 'Windows': | ||
46 | - return ET.parse(environ.get("HOMEDRIVE")+'\\vlibras-libs\\vlibras-translate\data\\regras.xml').getroot() | ||
47 | return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() | 44 | return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() |
48 | 45 | ||
49 | # Aplica regras morfológicas apartir do arquivo regras.xml | 46 | # Aplica regras morfológicas apartir do arquivo regras.xml |
@@ -264,8 +261,15 @@ class AplicaRegras(object): | @@ -264,8 +261,15 @@ class AplicaRegras(object): | ||
264 | # EU FELIZ PASSADO -> EU FELIZ | 261 | # EU FELIZ PASSADO -> EU FELIZ |
265 | if morfo[i] is not None and morfo[i][1] == "NTK" and morfo[i][0]: | 262 | if morfo[i] is not None and morfo[i][1] == "NTK" and morfo[i][0]: |
266 | new_node = self.gerar_no(morfo[i]) | 263 | new_node = self.gerar_no(morfo[i]) |
267 | - arvore[lista_pos_arv[i-1][:-3]].insert(2, new_node) | ||
268 | - #arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node) | 264 | + |
265 | + #arvore[lista_pos_arv[i-1][:-3]].insert(2, new_node) | ||
266 | + #arvore[lista_pos_arv[i-1][:-3]].insert(2, new_node) | ||
267 | + | ||
268 | + if str(arvore[lista_pos_arv[i-1][:-3]]).count('(') > 7: | ||
269 | + arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node) | ||
270 | + else: | ||
271 | + arvore[lista_pos_arv[i-1][:-3]].insert(2, new_node) | ||
272 | + | ||
269 | try: | 273 | try: |
270 | lista_pos_arv.insert(i,lista_pos_arv[i]) | 274 | lista_pos_arv.insert(i,lista_pos_arv[i]) |
271 | except: | 275 | except: |
@@ -399,9 +403,14 @@ class AplicaRegras(object): | @@ -399,9 +403,14 @@ class AplicaRegras(object): | ||
399 | tag = it.get_ticket() | 403 | tag = it.get_ticket() |
400 | 404 | ||
401 | if tag == "NUM": | 405 | if tag == "NUM": |
406 | + try: | ||
407 | + num_romano = roman_to_int(it.get_word().encode('utf-8')) | ||
408 | + lista_simplificada[it.get_count()] = [num_romano.decode('utf-8'), 'NUM-R'] | ||
409 | + except: | ||
410 | + pass | ||
402 | num = True | 411 | num = True |
403 | 412 | ||
404 | - if tag[-2:] == "-P" and self.verificar_excecao_plural(it.get_word()): | 413 | + if tag != "NPR-P" and tag[-2:] == "-P" or tag[-2:] == "_P" and self.verificar_excecao_plural(it.get_word()): |
405 | singular = self.analisar_plural(it.get_word()) | 414 | singular = self.analisar_plural(it.get_word()) |
406 | lista_simplificada[it.get_count()][0] = singular | 415 | lista_simplificada[it.get_count()][0] = singular |
407 | 416 | ||
@@ -438,7 +447,7 @@ class AplicaRegras(object): | @@ -438,7 +447,7 @@ class AplicaRegras(object): | ||
438 | return token[:-2]+"l" | 447 | return token[:-2]+"l" |
439 | return token | 448 | return token |
440 | elif(token[-1] == "s"): | 449 | elif(token[-1] == "s"): |
441 | - #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tagênis, ônibus, etc | 450 | + #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tagênis, ônibus, etc |
442 | return token[:-1] | 451 | return token[:-1] |
443 | else: | 452 | else: |
444 | return token | 453 | return token |
src/AplicaSinonimos.py
@@ -27,26 +27,10 @@ class AplicaSinonimos(object): | @@ -27,26 +27,10 @@ class AplicaSinonimos(object): | ||
27 | '''Percorre a lista fazendo a substituição pelos sinonimos. | 27 | '''Percorre a lista fazendo a substituição pelos sinonimos. |
28 | ''' | 28 | ''' |
29 | lista_corrigida = [] | 29 | lista_corrigida = [] |
30 | - palavras_compostas = self.carregar_palavras_compostas() | ||
31 | for tupla in lista_anotada: | 30 | for tupla in lista_anotada: |
32 | sinonimo = self.verificar_sinonimo(tupla[0]) | 31 | sinonimo = self.verificar_sinonimo(tupla[0]) |
33 | - try: | ||
34 | - token_composto_2 = lista_corrigida[-1] + "_" + sinonimo | ||
35 | - token_composto_3 = lista_corrigida[-2] + "_" + lista_corrigida[-1] + "_" + sinonimo | ||
36 | - if token_composto_2.upper() in palavras_compostas: | ||
37 | - lista_corrigida[-1] = token_composto_2 | ||
38 | - elif token_composto_3.upper() in palavras_compostas: | ||
39 | - lista_corrigida.pop() | ||
40 | - lista_corrigida[-1] = token_composto_3 | ||
41 | - else: | ||
42 | - lista_corrigida.append(sinonimo) | ||
43 | - except IndexError: | ||
44 | - lista_corrigida.append(sinonimo) | ||
45 | - | ||
46 | - try: | ||
47 | - return " ".join(lista_corrigida) | ||
48 | - except: | ||
49 | - return " ".join([str(x[0]) for x in lista_anotada]) | 32 | + lista_corrigida.append(sinonimo) |
33 | + return self.verificar_palavra_composta(lista_corrigida) | ||
50 | 34 | ||
51 | # Verifica se há sinonimo do token | 35 | # Verifica se há sinonimo do token |
52 | def verificar_sinonimo(self, token): | 36 | def verificar_sinonimo(self, token): |
@@ -56,13 +40,23 @@ class AplicaSinonimos(object): | @@ -56,13 +40,23 @@ class AplicaSinonimos(object): | ||
56 | return self.dicionarios.get_sinonimo(token) | 40 | return self.dicionarios.get_sinonimo(token) |
57 | return token | 41 | return token |
58 | 42 | ||
43 | + def verificar_palavra_composta(self, lista): | ||
44 | + palavras_compostas = self.carregar_palavras_compostas() | ||
45 | + try: | ||
46 | + sentenca_corrigida = "_".join(lista).upper() | ||
47 | + except: | ||
48 | + sentenca_corrigida = "_".join([str(x[0]) for x in lista]).upper() | ||
49 | + | ||
50 | + for p in palavras_compostas: | ||
51 | + if p in sentenca_corrigida: | ||
52 | + sentenca_corrigida = sentenca_corrigida.replace(p, p.replace("_", "#*#")) | ||
53 | + return sentenca_corrigida.replace("_", " ").replace("#*#", "_") | ||
54 | + | ||
59 | def carregar_palavras_compostas(self): | 55 | def carregar_palavras_compostas(self): |
60 | path = self.localizar_arquivo_palavras_compostas() | 56 | path = self.localizar_arquivo_palavras_compostas() |
61 | return set(open(path).read().decode('utf-8').split()) | 57 | return set(open(path).read().decode('utf-8').split()) |
62 | 58 | ||
63 | def localizar_arquivo_palavras_compostas(self): | 59 | def localizar_arquivo_palavras_compostas(self): |
64 | - if platform.system() == 'Windows': | ||
65 | - return environ.get("HOMEDRIVE")+'\\vlibras-libs\\vlibras-translate\data\\palavras_compostas.csv' | ||
66 | - elif "TRANSLATE_DATA" in environ: | 60 | + if "TRANSLATE_DATA" in environ: |
67 | return path.join(environ.get("TRANSLATE_DATA"), "palavras_compostas.csv") | 61 | return path.join(environ.get("TRANSLATE_DATA"), "palavras_compostas.csv") |
68 | return expanduser("~")+'/vlibras-translate/data/palavras_compostas.csv' | 62 | return expanduser("~")+'/vlibras-translate/data/palavras_compostas.csv' |
69 | \ No newline at end of file | 63 | \ No newline at end of file |
@@ -0,0 +1,165 @@ | @@ -0,0 +1,165 @@ | ||
1 | +#! /usr/bin/env python2.6 | ||
2 | +# -*- coding: utf-8 -*- | ||
3 | + | ||
4 | +#--------------------------------- | ||
5 | + | ||
6 | +# Editado: | ||
7 | + | ||
8 | +#Autor: Erickson Silva | ||
9 | +#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | ||
10 | + | ||
11 | +#LAViD - Laboratório de Aplicações de Vídeo Digital | ||
12 | + | ||
13 | +#--------------------------------- | ||
14 | + | ||
15 | + | ||
16 | +# Donatus Brazilian Portuguese Parser | ||
17 | +# | ||
18 | +# Copyright (C) 2010-2013 Leonel F. de Alencar | ||
19 | +# | ||
20 | +# Author: Leonel F. de Alencar <leonel.de.alencar@ufc.br> | ||
21 | +# Homepage: <http://www.leonel.profusehost.net/> | ||
22 | +# | ||
23 | +# Project's URL: <http://sourceforge.net/projects/donatus/> | ||
24 | +# For license information, see LICENSE.TXT | ||
25 | +# | ||
26 | +# $Id: alexp.py $ | ||
27 | + | ||
28 | +"""Este módulo contém funções que permitem utilizar o Aelius para etiquetar uma sentença, construindo entradas lexicais com base nas etiquetas atribuídas às palavras da sentença. Essas entradas lexicais são integradas em uma gramática CFG dada, que é transformada em um parser, utilizado para gerar uma árvore de estrutura sintagmática da sentença. | ||
29 | +""" | ||
30 | +import re,nltk, time, random | ||
31 | +from os.path import expanduser | ||
32 | +from os import environ, path | ||
33 | +from Aelius.Extras import carrega | ||
34 | +from Aelius import AnotaCorpus, Toqueniza | ||
35 | +from unicodedata import normalize | ||
36 | + | ||
37 | + | ||
38 | +class ClassificaSentencas(object): | ||
39 | + | ||
40 | + def __init__(self): | ||
41 | + self.sentenca_anotada = "" | ||
42 | + self.sleep_times = [0.1,0.2] | ||
43 | + | ||
44 | + def toqueniza(self, s): | ||
45 | + """Decodifica string utilizando utf-8, retornando uma lista de tokens em unicode. | ||
46 | + """ | ||
47 | + regex = re.compile('[%s]' % re.escape('“”')) | ||
48 | + regex2 = re.compile('[%s]' % re.escape('«»')) | ||
49 | + try: | ||
50 | + decodificada = regex2.sub('',regex.sub('"',s.replace("–", "-").replace("—", "-"))).decode("utf-8") | ||
51 | + except: | ||
52 | + decodificada = s.decode("utf-8") | ||
53 | + return Toqueniza.TOK_PORT.tokenize(decodificada) | ||
54 | + | ||
55 | + def obter_classificacao_morfologica(self): | ||
56 | + return self.sentenca_anotada | ||
57 | + | ||
58 | + def etiqueta_sentenca(self, s): | ||
59 | + """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens. | ||
60 | + """ | ||
61 | + etiquetador = carrega("AeliusHunPos") | ||
62 | + anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | ||
63 | + while (anotada[0][1] is None): | ||
64 | + time.sleep(random.choice(sleep_times)) | ||
65 | + anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | ||
66 | + regex = re.compile('[%s]' % re.escape('!"#&\'()*+,-./:;<=>?@[\\]^_`{|}~')) | ||
67 | + tag_punctuation = [".",",","QT","("] | ||
68 | + anotada_corrigida = [] | ||
69 | + for x in anotada: | ||
70 | + if x[1] not in tag_punctuation: | ||
71 | + if x[1] == "NUM": | ||
72 | + try: | ||
73 | + float(x[0].replace(',', '.')) | ||
74 | + anotada_corrigida.append(x) | ||
75 | + continue | ||
76 | + except: | ||
77 | + pass | ||
78 | + | ||
79 | + tupla = [regex.sub('',x[0]).lower(),x[1]] | ||
80 | + if tupla[0] != "": anotada_corrigida.append(tupla) | ||
81 | + else: | ||
82 | + if x[0] == ".": | ||
83 | + anotada_corrigida.append(["[ponto]".decode("utf-8"),"SPT"]) | ||
84 | + elif x[0] == "?": | ||
85 | + anotada_corrigida.append(["[interrogacao]".decode("utf-8"),"SPT"]) | ||
86 | + elif x[0] == "!": | ||
87 | + anotada_corrigida.append(["[exclamacao]".decode("utf-8"),"SPT"]) | ||
88 | + return anotada_corrigida | ||
89 | + | ||
90 | + def gera_entradas_lexicais(self, lista): | ||
91 | + """Gera entradas lexicais no formato CFG do NLTK a partir de lista de pares constituídos de tokens e suas etiquetas. | ||
92 | + """ | ||
93 | + entradas=[] | ||
94 | + for e in lista: | ||
95 | + # é necessário substituir símbolos como "-" e "+" do CHPTB | ||
96 | + # que não são aceitos pelo NLTK como símbolos não terminais | ||
97 | + c=re.sub(r"[-+]","_",e[1]) | ||
98 | + c=re.sub(r"\$","_S",c) | ||
99 | + entradas.append("%s -> '%s'" % (c, self.remove_acento(e[0]))) | ||
100 | + return entradas | ||
101 | + | ||
102 | + def corrige_anotacao(self, lista): | ||
103 | + """Esta função deverá corrigir alguns dos erros de anotação mais comuns do Aelius. No momento, apenas é corrigida VB-AN depois de TR. | ||
104 | + """ | ||
105 | + i=1 | ||
106 | + while i < len(lista): | ||
107 | + if lista[i][1] == "VB-AN" and lista[i-1][1].startswith("TR"): | ||
108 | + lista[i]=(lista[i][0],"VB-PP") | ||
109 | + i+=1 | ||
110 | + | ||
111 | + def encontra_arquivo(self): | ||
112 | + """Encontra arquivo na pasta vlibras-translate. | ||
113 | + """ | ||
114 | + if "TRANSLATE_DATA" in environ: | ||
115 | + return path.join(environ.get("TRANSLATE_DATA"), "cfg.syn.nltk") | ||
116 | + return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk" | ||
117 | + | ||
118 | + def extrai_sintaxe(self): | ||
119 | + """Extrai gramática armazenada em arquivo cujo caminho é definido relativamente ao diretório nltk_data. | ||
120 | + """ | ||
121 | + arquivo = self.encontra_arquivo() | ||
122 | + if arquivo: | ||
123 | + f=open(arquivo,"rU") | ||
124 | + sintaxe=f.read() | ||
125 | + f.close() | ||
126 | + return sintaxe | ||
127 | + else: | ||
128 | + print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path)) | ||
129 | + | ||
130 | + def analisa_sentenca(self, sentenca): | ||
131 | + """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES. | ||
132 | + """ | ||
133 | + parser = self.constroi_analisador(sentenca) | ||
134 | + codificada=[] | ||
135 | + for t in self.sentenca_anotada: | ||
136 | + if t[1] != "SPT": | ||
137 | + codificada.append(self.remove_acento(t[0]).encode("utf-8")) | ||
138 | + trees=parser.parse_one(codificada) | ||
139 | + return trees | ||
140 | + | ||
141 | + def constroi_analisador(self, s): | ||
142 | + """Constrói analisador a partir de uma única sentença não anotada, dada como lista de tokens, e uma lista de regras sintáticas no formato CFG, armazenadas em arquivo. Esta função tem um bug, causado pela maneira como o Aelius etiqueta sentenças usando o módulo ProcessaNomesProprios: quando a sentença se inicia por paravra com inicial minúscula, essa palavra não é incorporada ao léxico, mas a versão com inicial maiúscula. | ||
143 | + """ | ||
144 | + self.sentenca_anotada = self.etiqueta_sentenca(s) | ||
145 | + self.corrige_anotacao(self.sentenca_anotada) | ||
146 | + entradas = self.gera_entradas_lexicais(self.sentenca_anotada) | ||
147 | + lexico="\n".join(entradas) | ||
148 | + gramatica="%s\n%s" % (self.extrai_sintaxe().strip(),lexico) | ||
149 | + cfg=nltk.CFG.fromstring(gramatica) | ||
150 | + return nltk.ChartParser(cfg) | ||
151 | + | ||
152 | + def remove_acento(self, texto): | ||
153 | + try: | ||
154 | + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ASCII', 'ignore') | ||
155 | + except: | ||
156 | + return normalize('NFKD', texto.encode('iso-8859-1').decode('iso-8859-1')).encode('ASCII','ignore') | ||
157 | + | ||
158 | + def exibe_arvores(self, arvores): | ||
159 | + """Função 'wrapper' para a função de exibição de árvores do NLTK""" | ||
160 | + nltk.draw.draw_trees(*arvores) | ||
161 | + | ||
162 | + def iniciar_classificacao(self, sentenca): | ||
163 | + tokens = self.toqueniza(sentenca) | ||
164 | + tree = self.analisa_sentenca(tokens) | ||
165 | + return tree | ||
0 | \ No newline at end of file | 166 | \ No newline at end of file |
src/ConverteExtenso.py
@@ -25,7 +25,45 @@ ext = [{"um":"1", "dois":"2", "tres":"3", "quatro":"4", "cinco":"5", "seis":"6", | @@ -25,7 +25,45 @@ ext = [{"um":"1", "dois":"2", "tres":"3", "quatro":"4", "cinco":"5", "seis":"6", | ||
25 | und = {"mil":1000, "milhao":1000000, "bilhao":1000000000, "trilhao":1000000000000} | 25 | und = {"mil":1000, "milhao":1000000, "bilhao":1000000000, "trilhao":1000000000000} |
26 | unds = {"mil":"000", "milhao":"000000","milhoes":"000000", "bilhao":"000000000","bilhoes":"000000000", "trilhao":"000000000000", "trilhoes":"000000000000"} | 26 | unds = {"mil":"000", "milhao":"000000","milhoes":"000000", "bilhao":"000000000","bilhoes":"000000000", "trilhao":"000000000000", "trilhoes":"000000000000"} |
27 | 27 | ||
28 | - | 28 | +def int_to_roman(input): |
29 | + if not isinstance(input, type(1)): | ||
30 | + raise TypeError, "expected integer, got %s" % type(input) | ||
31 | + if not 0 < input < 4000: | ||
32 | + raise ValueError, "Argument must be between 1 and 3999" | ||
33 | + ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1) | ||
34 | + nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I') | ||
35 | + result = [] | ||
36 | + | ||
37 | + for i in range(len(ints)): | ||
38 | + count = int(input / ints[i]) | ||
39 | + result.append(nums[i] * count) | ||
40 | + input -= ints[i] * count | ||
41 | + return ''.join(result) | ||
42 | + | ||
43 | +def roman_to_int(input): | ||
44 | + if not isinstance(input, type("")): | ||
45 | + raise TypeError, "expected string, got %s" % type(input) | ||
46 | + input = input.upper( ) | ||
47 | + nums = {'M':1000, | ||
48 | + 'D':500, | ||
49 | + 'C':100, | ||
50 | + 'L':50, | ||
51 | + 'X':10, | ||
52 | + 'V':5, | ||
53 | + 'I':1} | ||
54 | + sum = 0 | ||
55 | + for i in range(len(input)): | ||
56 | + try: | ||
57 | + value = nums[input[i]] | ||
58 | + if i+1 < len(input) and nums[input[i+1]] > value: | ||
59 | + sum -= value | ||
60 | + else: sum += value | ||
61 | + except KeyError: | ||
62 | + raise ValueError, 'input is not a valid Roman numeral: %s' % input | ||
63 | + | ||
64 | + if int_to_roman(sum) == input: return str(sum) | ||
65 | + else: | ||
66 | + raise ValueError, 'input is not a valid Roman numeral: %s' % input | ||
29 | 67 | ||
30 | def oneDigit(x): | 68 | def oneDigit(x): |
31 | return ext[0][x] | 69 | return ext[0][x] |
src/LerDicionarios.py
@@ -8,20 +8,20 @@ | @@ -8,20 +8,20 @@ | ||
8 | 8 | ||
9 | import os | 9 | import os |
10 | import csv | 10 | import csv |
11 | -import platform | ||
12 | 11 | ||
13 | -class Singleton(object): | 12 | +class Singleton(type): |
14 | ''' Permite a criação de apenas uma instância da classe | 13 | ''' Permite a criação de apenas uma instância da classe |
15 | ''' | 14 | ''' |
15 | + _instances = {} | ||
16 | + def __call__(cls, *args, **kwargs): | ||
17 | + if cls not in cls._instances: | ||
18 | + cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) | ||
19 | + return cls._instances[cls] | ||
16 | 20 | ||
17 | - def __new__(cls, *args, **kwargs): | ||
18 | - if '_inst' not in vars(cls): | ||
19 | - cls._inst = object.__new__(cls, *args, **kwargs) | ||
20 | - return cls._inst | ||
21 | - | ||
22 | -class LerDicionarios(Singleton): | 21 | +class LerDicionarios(object): |
23 | '''Carrega todos os arquivos (dicionários) necessários para auxiliar durante o processo de tradução. | 22 | '''Carrega todos os arquivos (dicionários) necessários para auxiliar durante o processo de tradução. |
24 | ''' | 23 | ''' |
24 | + __metaclass__ = Singleton | ||
25 | 25 | ||
26 | def __init__(self): | 26 | def __init__(self): |
27 | self.path = self.get_path() | 27 | self.path = self.get_path() |
@@ -37,31 +37,13 @@ class LerDicionarios(Singleton): | @@ -37,31 +37,13 @@ class LerDicionarios(Singleton): | ||
37 | self.set_vb_ligacao = [] | 37 | self.set_vb_ligacao = [] |
38 | self.dic_vb_muda_negacao = [] | 38 | self.dic_vb_muda_negacao = [] |
39 | self.file = '' | 39 | self.file = '' |
40 | - self.carregar_dicionarios() | ||
41 | 40 | ||
42 | def get_path(self): | 41 | def get_path(self): |
43 | '''Verifica qual o SO e gera o path de onde se encontra o diretório data. | 42 | '''Verifica qual o SO e gera o path de onde se encontra o diretório data. |
44 | ''' | 43 | ''' |
45 | if "TRANSLATE_DATA" in os.environ: | 44 | if "TRANSLATE_DATA" in os.environ: |
46 | return os.environ.get("TRANSLATE_DATA") | 45 | return os.environ.get("TRANSLATE_DATA") |
47 | - elif platform.system() == 'Windows': | ||
48 | - return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\\" | ||
49 | - return os.path.expanduser("~") + "/vlibras-translate/data" | ||
50 | - | ||
51 | - def carregar_dicionarios(self): | ||
52 | - '''Realiza a leitura dos arquivos e atribui à estruturas de dicionários e sets. | ||
53 | - ''' | ||
54 | - self.carregar_excecoes_plural() | ||
55 | - self.carregar_adverbios_intensidade() | ||
56 | - self.carregar_adverbios_tempo() | ||
57 | - self.carregar_artigos() | ||
58 | - self.carregar_preposicoes() | ||
59 | - self.carregar_sinonimos() | ||
60 | - self.carregar_subs_2_generos() | ||
61 | - self.carregar_pronomes_tratamento() | ||
62 | - self.carregar_verbos_infinitivo() | ||
63 | - self.carregar_verbos_ligacao() | ||
64 | - self.carregar_verbos_muda_negacao | 46 | + return os.path.expanduser("~") + "/vlibras-translate/data" |
65 | 47 | ||
66 | def montar_diretorio(self, arquivo): | 48 | def montar_diretorio(self, arquivo): |
67 | return os.path.join(self.path, arquivo) | 49 | return os.path.join(self.path, arquivo) |
@@ -225,74 +207,104 @@ class LerDicionarios(Singleton): | @@ -225,74 +207,104 @@ class LerDicionarios(Singleton): | ||
225 | def has_excecao_plural(self, token): | 207 | def has_excecao_plural(self, token): |
226 | '''Verifica se o token recebido consta no arquivo de exceções de plural. | 208 | '''Verifica se o token recebido consta no arquivo de exceções de plural. |
227 | ''' | 209 | ''' |
210 | + if not self.set_exc_plural: | ||
211 | + self.carregar_excecoes_plural() | ||
228 | return token not in self.set_exc_plural | 212 | return token not in self.set_exc_plural |
229 | 213 | ||
230 | def has_adverbio_intensidade(self, token): | 214 | def has_adverbio_intensidade(self, token): |
231 | '''Verifica se o token recebido consta no arquivo de advérbios de intensidade. | 215 | '''Verifica se o token recebido consta no arquivo de advérbios de intensidade. |
232 | ''' | 216 | ''' |
217 | + if not self.dic_adv_intensidade: | ||
218 | + self.carregar_adverbios_intensidade() | ||
233 | return self.dic_adv_intensidade.has_key(token) | 219 | return self.dic_adv_intensidade.has_key(token) |
234 | 220 | ||
235 | def has_adverbio_tempo(self, token): | 221 | def has_adverbio_tempo(self, token): |
236 | '''Verifica se o token recebido consta no arquivo de advérbios de tempo. | 222 | '''Verifica se o token recebido consta no arquivo de advérbios de tempo. |
237 | ''' | 223 | ''' |
224 | + if not self.set_adv_tempo: | ||
225 | + self.carregar_adverbios_tempo() | ||
238 | return token in self.set_adv_tempo | 226 | return token in self.set_adv_tempo |
239 | 227 | ||
240 | def has_artigo(self, token): | 228 | def has_artigo(self, token): |
241 | '''Verifica se o token recebido consta no arquivo de artigos a serem removidos. | 229 | '''Verifica se o token recebido consta no arquivo de artigos a serem removidos. |
242 | ''' | 230 | ''' |
231 | + if not self.set_art: | ||
232 | + self.carregar_artigos() | ||
243 | return token in self.set_art | 233 | return token in self.set_art |
244 | 234 | ||
245 | def has_preposicao(self, token): | 235 | def has_preposicao(self, token): |
246 | '''Verifica se o token recebido consta no arquivo de preposições a serem removidas. | 236 | '''Verifica se o token recebido consta no arquivo de preposições a serem removidas. |
247 | ''' | 237 | ''' |
238 | + if not self.set_prep: | ||
239 | + self.carregar_preposicoes() | ||
248 | return token in self.set_prep | 240 | return token in self.set_prep |
249 | 241 | ||
250 | def has_sinonimo(self, token): | 242 | def has_sinonimo(self, token): |
251 | '''Verifica se o token recebido consta no arquivo de sinonimos. | 243 | '''Verifica se o token recebido consta no arquivo de sinonimos. |
252 | ''' | 244 | ''' |
245 | + if not self.dic_sin: | ||
246 | + self.carregar_sinonimos() | ||
253 | return self.dic_sin.has_key(token) | 247 | return self.dic_sin.has_key(token) |
254 | 248 | ||
255 | def has_pron_tratam(self, token): | 249 | def has_pron_tratam(self, token): |
256 | '''Verifica se o token recebido consta no arquivo de pronomes de tratamento. | 250 | '''Verifica se o token recebido consta no arquivo de pronomes de tratamento. |
257 | ''' | 251 | ''' |
252 | + if not self.set_pron_trat: | ||
253 | + self.carregar_pronomes_tratamento() | ||
258 | return token in self.set_pron_trat | 254 | return token in self.set_pron_trat |
259 | 255 | ||
260 | def has_subst_2_generos (self, token): | 256 | def has_subst_2_generos (self, token): |
261 | '''Verifica se o token recebido consta no arquivo de substantivos comuns de 2 generos. | 257 | '''Verifica se o token recebido consta no arquivo de substantivos comuns de 2 generos. |
262 | ''' | 258 | ''' |
259 | + if not self.set_sb_2_gen: | ||
260 | + self.carregar_subs_2_generos() | ||
263 | return token in self.set_sb_2_gen | 261 | return token in self.set_sb_2_gen |
264 | 262 | ||
265 | def has_verbo_infinitivo(self, token): | 263 | def has_verbo_infinitivo(self, token): |
266 | '''Verifica se o token recebido consta no arquivo de verbos no infinitivo. | 264 | '''Verifica se o token recebido consta no arquivo de verbos no infinitivo. |
267 | ''' | 265 | ''' |
266 | + if not self.dic_vb_infinitivo: | ||
267 | + self.carregar_verbos_infinitivo() | ||
268 | return self.dic_vb_infinitivo.has_key(token) | 268 | return self.dic_vb_infinitivo.has_key(token) |
269 | 269 | ||
270 | def has_verbo_ligacao(self, token): | 270 | def has_verbo_ligacao(self, token): |
271 | '''Verifica se o token recebido consta no arquivo de verbos de ligação. | 271 | '''Verifica se o token recebido consta no arquivo de verbos de ligação. |
272 | ''' | 272 | ''' |
273 | + if not self.set_vb_ligacao: | ||
274 | + self.carregar_verbos_ligacao() | ||
273 | return token in self.set_vb_ligacao | 275 | return token in self.set_vb_ligacao |
274 | 276 | ||
275 | def has_verbo_muda_negacao(self, token): | 277 | def has_verbo_muda_negacao(self, token): |
276 | '''Verifica se o token recebido consta no arquivo de verbos que mudam de negação. | 278 | '''Verifica se o token recebido consta no arquivo de verbos que mudam de negação. |
277 | ''' | 279 | ''' |
280 | + if not self.dic_vb_muda_negacao: | ||
281 | + self.carregar_verbos_muda_negacao() | ||
278 | return self.dic_vb_muda_negacao.has_key(token) | 282 | return self.dic_vb_muda_negacao.has_key(token) |
279 | 283 | ||
280 | def get_adverbio_intensidade(self, token): | 284 | def get_adverbio_intensidade(self, token): |
281 | '''Verifica se o token recebido consta no arquivo de advérbios de intensidade. | 285 | '''Verifica se o token recebido consta no arquivo de advérbios de intensidade. |
282 | ''' | 286 | ''' |
287 | + if not self.dic_adv_intensidade: | ||
288 | + self.carregar_adverbios_intensidade() | ||
283 | return self.dic_adv_intensidade[token] | 289 | return self.dic_adv_intensidade[token] |
284 | 290 | ||
285 | def get_sinonimo(self, token): | 291 | def get_sinonimo(self, token): |
286 | '''Obtém o sinônimo do token. | 292 | '''Obtém o sinônimo do token. |
287 | ''' | 293 | ''' |
294 | + if not self.dic_sin: | ||
295 | + self.carregar_sinonimos() | ||
288 | return self.dic_sin[token] | 296 | return self.dic_sin[token] |
289 | 297 | ||
290 | def get_verbo_infinitivo(self, token): | 298 | def get_verbo_infinitivo(self, token): |
291 | '''Obtém o verbo no infinitivo do token. | 299 | '''Obtém o verbo no infinitivo do token. |
292 | ''' | 300 | ''' |
301 | + if not self.dic_vb_infinitivo: | ||
302 | + self.carregar_verbos_infinitivo() | ||
293 | return self.dic_vb_infinitivo[token] | 303 | return self.dic_vb_infinitivo[token] |
294 | 304 | ||
295 | def get_verbo_muda_negacao(self, token): | 305 | def get_verbo_muda_negacao(self, token): |
296 | '''Obtém o verbo que muda a negação do token. | 306 | '''Obtém o verbo que muda a negação do token. |
297 | ''' | 307 | ''' |
308 | + if not self.dic_vb_muda_negacao: | ||
309 | + self.carregar_verbos_muda_negacao() | ||
298 | return self.dic_vb_muda_negacao[token] | 310 | return self.dic_vb_muda_negacao[token] |
299 | \ No newline at end of file | 311 | \ No newline at end of file |
src/PortGlosa.py
@@ -11,22 +11,20 @@ from ThreadTradutor import * | @@ -11,22 +11,20 @@ from ThreadTradutor import * | ||
11 | from TraduzSentencas import * | 11 | from TraduzSentencas import * |
12 | from LerDicionarios import * | 12 | from LerDicionarios import * |
13 | 13 | ||
14 | - | ||
15 | tradutor = TraduzSentencas() | 14 | tradutor = TraduzSentencas() |
16 | -dicionario = LerDicionarios() | ||
17 | taxas = [] | 15 | taxas = [] |
18 | 16 | ||
19 | def traduzir(texto, log=None, threads=False, taxa_qualidade=False): | 17 | def traduzir(texto, log=None, threads=False, taxa_qualidade=False): |
20 | - tradutor.set_level(log) if log != None else tradutor.desativar_logging() | 18 | + #tradutor.set_level(log) if log != None else tradutor.desativar_logging() |
21 | if texto.isspace() or texto == "": | 19 | if texto.isspace() or texto == "": |
22 | #or not checar_idioma(texto): | 20 | #or not checar_idioma(texto): |
23 | return "ESCOLHER TEXTO CERTO" | 21 | return "ESCOLHER TEXTO CERTO" |
24 | 22 | ||
25 | - elif threads: | ||
26 | - return iniciar_com_threads(texto, taxa_qualidade) | 23 | + #elif threads: |
24 | + # return iniciar_com_threads(texto, taxa_qualidade) | ||
27 | 25 | ||
28 | - else: | ||
29 | - return iniciar_sem_threads(texto, taxa_qualidade) | 26 | + #else: |
27 | + return iniciar_sem_threads(texto, taxa_qualidade) | ||
30 | 28 | ||
31 | def iniciar_com_threads(texto, taxa_qualidade): | 29 | def iniciar_com_threads(texto, taxa_qualidade): |
32 | texto_quebrado = quebrar_texto(texto) | 30 | texto_quebrado = quebrar_texto(texto) |
@@ -64,6 +62,7 @@ def quebrar_texto(texto): | @@ -64,6 +62,7 @@ def quebrar_texto(texto): | ||
64 | if '.' not in texto: | 62 | if '.' not in texto: |
65 | return [texto] | 63 | return [texto] |
66 | 64 | ||
65 | + dicionario = LerDicionarios() | ||
67 | texto_quebrado = texto.split() | 66 | texto_quebrado = texto.split() |
68 | tamanho_texto_quebrado = len(texto_quebrado) | 67 | tamanho_texto_quebrado = len(texto_quebrado) |
69 | sentencas = [] | 68 | sentencas = [] |
src/TraduzSentencas.py
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | 6 | ||
7 | #LAViD - Laboratório de Aplicações de Vídeo Digital | 7 | #LAViD - Laboratório de Aplicações de Vídeo Digital |
8 | 8 | ||
9 | -import alexp | 9 | +from ClassificaSentencas import * |
10 | from AplicaRegras import * | 10 | from AplicaRegras import * |
11 | from AplicaSinonimos import * | 11 | from AplicaSinonimos import * |
12 | import logging | 12 | import logging |
@@ -24,6 +24,7 @@ class TraduzSentencas(object): | @@ -24,6 +24,7 @@ class TraduzSentencas(object): | ||
24 | def __init__(self): | 24 | def __init__(self): |
25 | '''Instancia os aplicadores de regras e sinônimos. | 25 | '''Instancia os aplicadores de regras e sinônimos. |
26 | ''' | 26 | ''' |
27 | + self.classificador = ClassificaSentencas() | ||
27 | self.aplic_regras = AplicaRegras() | 28 | self.aplic_regras = AplicaRegras() |
28 | self.aplic_sin = AplicaSinonimos() | 29 | self.aplic_sin = AplicaSinonimos() |
29 | self.check_level() | 30 | self.check_level() |
@@ -33,13 +34,13 @@ class TraduzSentencas(object): | @@ -33,13 +34,13 @@ class TraduzSentencas(object): | ||
33 | ''' | 34 | ''' |
34 | try: | 35 | try: |
35 | has_sintatica = True | 36 | has_sintatica = True |
36 | - analise_sintatica = alexp.run(sentenca) | 37 | + analise_sintatica = self.classificador.iniciar_classificacao(sentenca) |
37 | except Exception as ex: | 38 | except Exception as ex: |
38 | self.salvar_log(str(traceback.format_exc())) | 39 | self.salvar_log(str(traceback.format_exc())) |
39 | analise_sintatica = None | 40 | analise_sintatica = None |
40 | has_sintatica = False | 41 | has_sintatica = False |
41 | 42 | ||
42 | - analise_morfologica = alexp.getAnaliseMorfologica() | 43 | + analise_morfologica = self.classificador.obter_classificacao_morfologica() |
43 | 44 | ||
44 | if (isinstance(analise_sintatica,type(None))): | 45 | if (isinstance(analise_sintatica,type(None))): |
45 | regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica) | 46 | regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica) |
src/alexp.py
@@ -1,156 +0,0 @@ | @@ -1,156 +0,0 @@ | ||
1 | -#! /usr/bin/env python2.6 | ||
2 | -# -*- coding: utf-8 -*- | ||
3 | - | ||
4 | -#--------------------------------- | ||
5 | - | ||
6 | -# Editado: | ||
7 | - | ||
8 | -#Autor: Erickson Silva | ||
9 | -#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | ||
10 | - | ||
11 | -#LAViD - Laboratório de Aplicações de Vídeo Digital | ||
12 | - | ||
13 | -#--------------------------------- | ||
14 | - | ||
15 | - | ||
16 | -# Donatus Brazilian Portuguese Parser | ||
17 | -# | ||
18 | -# Copyright (C) 2010-2013 Leonel F. de Alencar | ||
19 | -# | ||
20 | -# Author: Leonel F. de Alencar <leonel.de.alencar@ufc.br> | ||
21 | -# Homepage: <http://www.leonel.profusehost.net/> | ||
22 | -# | ||
23 | -# Project's URL: <http://sourceforge.net/projects/donatus/> | ||
24 | -# For license information, see LICENSE.TXT | ||
25 | -# | ||
26 | -# $Id: alexp.py $ | ||
27 | - | ||
28 | -"""Este módulo contém funções que permitem utilizar o Aelius para etiquetar uma sentença, construindo entradas lexicais com base nas etiquetas atribuídas às palavras da sentença. Essas entradas lexicais são integradas em uma gramática CFG dada, que é transformada em um parser, utilizado para gerar uma árvore de estrutura sintagmática da sentença. | ||
29 | -""" | ||
30 | -import re,nltk,platform, time, random | ||
31 | -from os.path import expanduser | ||
32 | -from os import environ, path | ||
33 | -from Aelius.Extras import carrega | ||
34 | -from Aelius import AnotaCorpus | ||
35 | -from unicodedata import normalize | ||
36 | - | ||
37 | -sentenca_anotada="" | ||
38 | -sleep_times=[0.1,0.2] | ||
39 | - | ||
40 | -def toqueniza(s): | ||
41 | - """Decodifica string utilizando utf-8, retornando uma lista de tokens em unicode. | ||
42 | - """ | ||
43 | - regex = re.compile('[%s]' % re.escape('“”')) | ||
44 | - decodificada=regex.sub('"',s.replace("–", "-").replace("—", "-")).decode("utf-8") | ||
45 | - return AnotaCorpus.TOK_PORT.tokenize(decodificada) | ||
46 | - | ||
47 | -def getAnaliseMorfologica(): | ||
48 | - return sentenca_anotada | ||
49 | - | ||
50 | -def etiquetaSentenca(s): | ||
51 | - """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens. | ||
52 | - """ | ||
53 | - etiquetador = carrega("AeliusHunPos") | ||
54 | - anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | ||
55 | - while (anotada[0][1] is None): | ||
56 | - time.sleep(random.choice(sleep_times)) | ||
57 | - anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | ||
58 | - regex = re.compile('[%s]' % re.escape('!"#&\'()*+,-./:;<=>?@[\\]^_`{|}~')) | ||
59 | - tag_punctuation = [".",",","QT","("] | ||
60 | - anotada_corrigida = [] | ||
61 | - for x in anotada: | ||
62 | - if x[1] not in tag_punctuation: | ||
63 | - if x[1] == "NUM": | ||
64 | - anotada_corrigida.append(x) | ||
65 | - continue | ||
66 | - tupla = [regex.sub('',x[0]).lower(),x[1]] | ||
67 | - if tupla[0] != "": anotada_corrigida.append(tupla) | ||
68 | - else: | ||
69 | - if x[0] == ".": | ||
70 | - anotada_corrigida.append(["[ponto]".decode("utf-8"),"SPT"]) | ||
71 | - elif x[0] == "?": | ||
72 | - anotada_corrigida.append(["[interrogacao]".decode("utf-8"),"SPT"]) | ||
73 | - elif x[0] == "!": | ||
74 | - anotada_corrigida.append(["[exclamacao]".decode("utf-8"),"SPT"]) | ||
75 | - return anotada_corrigida | ||
76 | - | ||
77 | -def geraEntradasLexicais(lista): | ||
78 | - """Gera entradas lexicais no formato CFG do NLTK a partir de lista de pares constituídos de tokens e suas etiquetas. | ||
79 | - """ | ||
80 | - entradas=[] | ||
81 | - for e in lista: | ||
82 | - # é necessário substituir símbolos como "-" e "+" do CHPTB | ||
83 | - # que não são aceitos pelo NLTK como símbolos não terminais | ||
84 | - c=re.sub(r"[-+]","_",e[1]) | ||
85 | - c=re.sub(r"\$","_S",c) | ||
86 | - entradas.append("%s -> '%s'" % (c, removeAcento(e[0]))) | ||
87 | - return entradas | ||
88 | - | ||
89 | -def corrigeAnotacao(lista): | ||
90 | - """Esta função deverá corrigir alguns dos erros de anotação mais comuns do Aelius. No momento, apenas é corrigida VB-AN depois de TR. | ||
91 | - """ | ||
92 | - i=1 | ||
93 | - while i < len(lista): | ||
94 | - if lista[i][1] == "VB-AN" and lista[i-1][1].startswith("TR"): | ||
95 | - lista[i]=(lista[i][0],"VB-PP") | ||
96 | - i+=1 | ||
97 | - | ||
98 | -def encontraArquivo(): | ||
99 | - """Encontra arquivo na pasta vlibras-translate. | ||
100 | - """ | ||
101 | - so = platform.system() | ||
102 | - if "TRANSLATE_DATA" in environ: | ||
103 | - return path.join(environ.get("TRANSLATE_DATA"), "cfg.syn.nltk") | ||
104 | - elif so == 'Windows': | ||
105 | - return environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\cfg.syn.nltk" | ||
106 | - return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk" | ||
107 | - | ||
108 | -def extraiSintaxe(): | ||
109 | - """Extrai gramática armazenada em arquivo cujo caminho é definido relativamente ao diretório nltk_data. | ||
110 | - """ | ||
111 | - arquivo=encontraArquivo() | ||
112 | - if arquivo: | ||
113 | - f=open(arquivo,"rU") | ||
114 | - sintaxe=f.read() | ||
115 | - f.close() | ||
116 | - return sintaxe | ||
117 | - else: | ||
118 | - print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path)) | ||
119 | - | ||
120 | -def analisaSentenca(sentenca): | ||
121 | - """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES. | ||
122 | - """ | ||
123 | - parser=constroiAnalisador(sentenca) | ||
124 | - codificada=[] | ||
125 | - for t in sentenca_anotada: | ||
126 | - if t[1] != "SPT": | ||
127 | - codificada.append(removeAcento(t[0]).encode("utf-8")) | ||
128 | - trees=parser.parse_one(codificada) | ||
129 | - return trees | ||
130 | - | ||
131 | -def constroiAnalisador(s): | ||
132 | - """Constrói analisador a partir de uma única sentença não anotada, dada como lista de tokens, e uma lista de regras sintáticas no formato CFG, armazenadas em arquivo. Esta função tem um bug, causado pela maneira como o Aelius etiqueta sentenças usando o módulo ProcessaNomesProprios: quando a sentença se inicia por paravra com inicial minúscula, essa palavra não é incorporada ao léxico, mas a versão com inicial maiúscula. | ||
133 | - """ | ||
134 | - global sentenca_anotada | ||
135 | - sentenca_anotada=etiquetaSentenca(s) | ||
136 | - corrigeAnotacao(sentenca_anotada) | ||
137 | - entradas=geraEntradasLexicais(sentenca_anotada) | ||
138 | - lexico="\n".join(entradas) | ||
139 | - gramatica="%s\n%s" % (extraiSintaxe().strip(),lexico) | ||
140 | - cfg=nltk.CFG.fromstring(gramatica) | ||
141 | - return nltk.ChartParser(cfg) | ||
142 | - | ||
143 | -def removeAcento(texto): | ||
144 | - try: | ||
145 | - return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ASCII', 'ignore') | ||
146 | - except: | ||
147 | - return normalize('NFKD', texto.encode('iso-8859-1').decode('iso-8859-1')).encode('ASCII','ignore') | ||
148 | - | ||
149 | -def exibeArvores(arvores): | ||
150 | - """Função 'wrapper' para a função de exibição de árvores do NLTK""" | ||
151 | - nltk.draw.draw_trees(*arvores) | ||
152 | - | ||
153 | -def run(sentenca): | ||
154 | - tokens=toqueniza(sentenca) | ||
155 | - tree=analisaSentenca(tokens) | ||
156 | - return tree | ||
157 | \ No newline at end of file | 0 | \ No newline at end of file |