Divisão Silábica Automática do Português Europeu

Transcrição

Divisão Silábica Automática do Português Europeu
Heitor Hugo Guedes Amorim
Messias Manuel Rocha Fernandes
Divisão Silábica Automática do Português Europeu
Engenharia Informática
Setembro 2008
-
Divisão Silábica Automática do Português Europeu
Relatório da Disciplina de Projecto
Engenharia Informática
Escola Superior de Tecnologia e de Gestão
Heitor Amorim, Messias Fernandes
12 de Setembro de 2008
-
A Escola Superior de Tecnologia e Gestão não se responsabiliza pelas opiniões expressas
neste relatório.
- iii -
Certifico que li este relatório e que na minha opinião, é adequado no seu
conteúdo e forma como demonstrador do trabalho desenvolvido no
âmbito da disciplina de Projecto.
___________________________________________
Paulo Gouveia Orientador
Certifico que li este relatório e que na minha opinião, é adequado no seu
conteúdo e forma como demonstrador do trabalho desenvolvido no
âmbito da disciplina de Projecto.
___________________________________________
Co-Orientador
Certifico que li este relatório e que na minha opinião, é adequado no seu
conteúdo e forma como demonstrador do trabalho desenvolvido no
âmbito da disciplina de Projecto.
___________________________________________
Arguente
Aceite para avaliação da disciplina de Projecto
- iv -
Introdução
Este trabalho insere-se na disciplina de Projecto, tendo como objectivo principal o
desenvolvimento de um algoritmo que efectue a divisão silábica do português europeu. Note-se
que o projecto não respeita o novo acordo ortográfico da língua portuguesa, pois quando se
iniciou ainda não tinha sido aprovado pelas entidades competentes.
Durante a realização deste projecto foram diversas as dificuldades encontradas, neste relatório
estão descritas as soluções encontradas e as regras que estiveram na base da separação
silábica.
De seguida apresentamos uma breve descrição dos capítulos que se seguem no relatório.
No capítulo 1 deste relatório começamos por apresentar os conceitos relacionados com a
gramática portuguesa que foram necessários para a elaboração do projecto. de salientar que a
principal referência utilizada para o efeito foi o livro “Nova Gramática do Português
Contemporâneo”, de Celso Cunha e Lindley Cintra [CC 02].
No capítulo 2 são apresentadas as regras que estiveram na base do desenvolvimento do
algoritmo. Após a devida pesquisa efectuada foi possível definir correctamente as regras de
separação dos grafemas.
No capítulo 3 é efectuada uma explicação detalhada de todos os ficheiros utilizados para a
implementação, como também algumas particularidades. Explica, por exemplo, de que modo
foi feita a criação das variáveis inseparáveis e a sua respectiva associação ao código ASCII.
O capítulo 4 apresenta uma descrição dos ficheiros de texto que estão associados ao código
fonte. Tanto aquele que serve de entrada como os dois ficheiros auxiliares e ainda o ficheiro
de output que são gerados.
Por fim, no capítulo 5 são apresentadas as conclusões, as análises aos resultados obtidos e os
trabalhos que podem ser desenvolvidos futuramente a partir do projecto.
-v-
Agradecimentos
Este espaço é dedicado àqueles que deram a sua contribuição para que este trabalho fosse
realizado. A todos eles deixamos aqui os nossos sinceros agradecimentos.
Em primeiro lugar agradecemos ao Prof. Paulo Gouveia a forma como orientou o nosso
projecto. As notas dominantes da sua orientação foram, a utilidade das suas recomendações e
a cordialidade com que sempre nos recebeu. Estamos igualmente, gratos por ambas e também
pela liberdade de acção que nos permitiu, que foi decisiva para que este trabalho contribuísse
para o nosso desenvolvimento pessoal.
Estamos igualmente agradecidos aos nossos familiares que sempre nos apoiaram e
acreditaram nas nossas capacidades em conseguir ultrapassar, com sucesso, as dificuldades
que iam surgindo.
Agradecemos também, o apoio e a motivação que as nossas respectivas namoradas nos
transmitiram nos momentos mais complicados durante a realização deste projecto.
Deixamos ainda uma palavra de agradecimento aos professores de programação, mais
concretamente ao Prof. José Exposto e ao Prof. Paulo Matos, pela forma como leccionaram as
cadeiras e por nos terem transmitido o interesse por estas matérias.
- vi -
Conteúdo
1 Regras e conceitos gramaticais do Português Europeu ................................................. 1 1.1 Letra .............................................................................................................................. 1 1.2 Alfabeto......................................................................................................................... 1 1.3 Sílaba............................................................................................................................. 2 1.4 Vogal ............................................................................................................................. 2 1.5 Semivogal ..................................................................................................................... 3 1.6 Consoante ...................................................................................................................... 3 1.7 Encontros vocálicos ...................................................................................................... 4 1.7.1 Ditongos ................................................................................................................. 4 1.7.1.1 Ditongos decrescentes e crescentes ................................................................. 4 1.7.1.2 Ditongos orais e nasais .................................................................................... 4 1.7.2 Tritongos ................................................................................................................ 5 1.7.3 Hiatos ..................................................................................................................... 5 1.8 Encontros Consonantais ................................................................................................ 6 1.9 Dígrafos......................................................................................................................... 7 1.10 Translineação ............................................................................................................. 7 2 Regras usadas na construção do algoritmo ..................................................................... 8 2.1 Grupos de grafemas indivisíveis ................................................................................... 8 2.2 Grupos de grafemas que implicam separação............................................................... 9 3 Implementação ................................................................................................................. 10 3.1 Ficheiro main.cpp ....................................................................................................... 10 3.2 Ficheiro Constantes.h.................................................................................................. 11 3.2.1 Consoantes inseparáveis ....................................................................................... 11 3.2.2 Vogais inseparáveis .............................................................................................. 12 3.2.3 Vogais acentuadas e c com cedilha ...................................................................... 13 3.2.4 Representantes de maiúsculas .............................................................................. 13 3.2.5 Símbolo de separação silábica.............................................................................. 14 - vii -
3.3 Ficheiro Funcoes.h ...................................................................................................... 15 3.4 Ficheiro Funcoes.cpp .................................................................................................. 15 3.4.1 void preProc(FILE *fin) ....................................................................................... 15 3.4.1.1 Primeira operação .......................................................................................... 15 3.4.1.2 Segunda operação .......................................................................................... 16 3.4.2 void proc() ............................................................................................................ 16 3.4.3 void posProc() ...................................................................................................... 16 3.4.4 void criaSilabas(int palIn[]) ................................................................................. 17 3.4.5 void constroiPal(int palOrig[], int palIn[], FILE *fout) ....................................... 17 3.4.6 bool letra(int ch) ................................................................................................... 17 3.4.7 bool vogal(int ch) ................................................................................................. 18 3.4.8 bool semivogal(int ch1, int ch2, int ch3) .............................................................. 18 3.4.9 bool ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3, int i)...................... 18 3.4.10 bool tritongo(int ch1, int ch2, int ch3, int ch4) ................................................. 19 3.4.11 bool sinalMaiuscula(int ch)............................................................................... 19 4 Ficheiros gerados nas várias fases de processamento .................................................. 21 4.1 Ficheiro de entrada ...................................................................................................... 21 4.2 Ficheiro PreProcessamento.txt ................................................................................... 21 4.3 Ficheiro PosProcessamento.txt ................................................................................... 21 4.4 Ficheiro Final.txt......................................................................................................... 22 5 Conclusões ........................................................................................................................ 23 5.1 Teste e análise de resultados ....................................................................................... 23 5.2 Trabalho a desenvolver futuramente ........................................................................... 23 Bibliografia ............................................................................................................................. 24 A Código Fonte .................................................................................................................... 25 A.1 Ficheiro main.cpp ....................................................................................................... 25 A.2 Ficheiro Constantes.h ................................................................................................. 26 A.3 Ficheiro Funcoes.h...................................................................................................... 28 A.4 Ficheiro Funcoes.cpp .................................................................................................. 29 B Tabela de símbolos usada................................................................................................ 38 - viii -
Lista de Tabelas
Tabela 1 - Ditongos orais decrescentes. ..................................................................................... 4 Tabela 2 - Ditongos nasais decrescentes. ................................................................................... 5 Tabela 3 - Tritongos orais. ......................................................................................................... 5 Tabela 4 - Tritongos nasais. ....................................................................................................... 5 Tabela 5 - Encontros consonantais frequentes. .......................................................................... 6 Tabela 6 - Encontros consonantais pouco frequentes. ............................................................... 6 Tabela 7 - Digrafos. .................................................................................................................... 7 Tabela 8 - Símbolos ASCII que representam as consoantes inseparáveis. .............................. 11 Tabela 9 - Símbolos ASCII que representam as vogais inseparáveis. ..................................... 12 Tabela 10 - Vogais acentuadas e c com cedilha ....................................................................... 13 Tabela 11 - Representantes de maiúsculas. .............................................................................. 14 - ix -
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
Capítulo 1
1 Regras e conceitos gramaticais do Português
Europeu
Para a realização deste projecto foi necessário efectuar uma pesquisa aprofundada sobre a
gramática portuguesa, para que se pudesse efectuar a implementação correcta do algoritmo,
respeitando assim as diversas regras da divisão silábica.
Vamos apresentar de seguida algumas regras, definições e conceitos importantes para efectuar
a separação silábica, para melhor compreender algumas decisões e a complexidade que está
inerente a esta tarefa.
1.1 Letra
“Para reproduzirmos na escrita as palavras da nossa língua empregamos um certo número
de sinais gráficos chamados LETRAS.” [CC 02, p. 63]
1.2 Alfabeto
“O conjunto ordenado das letras de que nos servimos para transcrever os sons da linguagem
falada denomina-se ALFABETO.
O alfabeto da linguagem portuguesa consta fundamentalmente das seguintes letras:
abcdefghijlmnopqrstuvxz
Além dessas, há as letras k, w e y (...) ” [CC 02, p. 63]
-1-
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
1.3 Sílaba
Como o projecto se destina à divisão silábica, vamos definir o que é uma sílaba no Português
Europeu.
“A palavra sílaba deriva do latim syllăba e esta por sua vez deriva do grego συλλαβή, que
quer dizer unido.
•
A sílaba é uma vogal ou a reunião de consoantes com vogais que se pronunciam num
único som.
•
Em Linguística na fala humana, significa um grupo de sons pronunciados juntos, numa
única expiração.” [R 08]
“Sílaba é o conjunto de um ou mais fonemas pronunciados numa única emissão de voz. Na
língua portuguesa, o núcleo da sílaba é sempre uma vogal: não existe sílaba sem vogal e
nunca há mais do que uma única vogal em cada sílaba. Atenção com as letras i e u (e mais
raramente com as letras e e o), pois elas podem representar semivogais, que não são nunca
núcleos de sílaba em português”. [K 08]
“Quando pronunciamos lentamente uma palavra, sentimos que não o fazemos separando um
som de outro, mas dividindo a palavra em pequenos segmentos fónicos que serão tantos
quantos forem as vogais, assim uma palavra como alegrou, não será por nós emitida a-l-e-gr-o-u, mas sim a-le-grou.
A cada vogal ou grupo de sons pronunciados numa só expiração damos o nome de sílaba.
A sílaba pode ser formada:
o Por uma vogal, um ditongo ou um tritongo:
é
eu
uai!
o Por uma vogal, um ditongo ou um tritongo acompanhado de constantes:
a-plau-dir
trans-por
U-ru-guai” [CC 02, pp. 53-54]
1.4 Vogal
“Vogal ou medial é todo fonema em cuja emissão o ar passa livremente pela boca (ou
também pelo nariz), sem obstrução.
Também é como se denominam as letras que representam os sons vocálicos. Na língua
portuguesa são cinco as letras usadas para representar vogais: a, e, i, o, u.” [S 08]
“Do ponto de vista articulatório, as vogais podem ser consideradas sons formados pela
vibração das cordas e modificados segundo a forma das actividades supralaríngeas, que
devem estar sempre abertas ou entreabertas à passagem de ar.” [CC 02, p. 32]
-2-
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
1.5 Semivogal
“Há duas semivogais em português, representadas pelos símbolos /j/ e /w/ e produzidas de
forma semelhante às vogais altas /i/ e /u/. A diferença fundamental entre as vogais e as
semivogais está no fato de que estas últimas não desempenham o papel de núcleo silábico.
Em outras palavras, as semivogais necessariamente acompanham alguma vogal, com a qual
formam sílaba.
As letras utilizadas para representar as semivogais em português são utilizadas também para
representar vogais, o que cria muitas dúvidas. A única forma de diferenciá-las efetivamente é
falar e ouvir as palavras em que surgem: país - pais, baú - mau. Em país e baú, as letras i e u
representam respectivamente as vogais /i/ e /u/. Já em pais e mau, essas letras representam as
semivogais /j/ e /w/. Isso pode ser facilmente percebido ao se observar como a articulação
desses sons é diferente em cada caso; além disso, observe que país e baú têm ambas duas
sílabas, enquanto pais e mau têm ambas uma única sílaba. Em algumas palavras,
encontramos as letras e e o representando as semivogais: mãe (/mãj/), pão(/pãw/).” [w 07]
“Entre as vogais e as consoantes situam-se as semivogais, que são os fonemas /i/ e /u/
quando, juntos a uma vogal, com ela formam sílaba. Foneticamente estas vogais assilabicas
transcrevem-se [j] e [w].
Exemplificando:
Em dito [‘ditu] e viu [‘viw] o /i/ é vogal, mas em pai [‘paj] e vário [‘varju] é semivogal.
Também é vogal o /u/ em muro [‘muru] e lua [‘lua], mas semivogal em meu [‘mew] e quatro
[‘kwatro].” [CC 02, pp. 32-33]
1.6 Consoante
“Em fonética, consoante é qualquer fonema caracterizado por alguma obstrução ou
constrição em um ou mais pontos do tracto vocal.
O termo consoante também é usado para classificar as letras do alfabeto, por causa do som
que elas representam. No alfabeto português, são chamadas de consoantes: B, C, D, F, G, H,
J, K, L, M, N, P, Q, R, S, T, V, W, X, Z.” [B 08]
“Na pronúncia das consoantes há sempre na cavidade bucal obstáculo à passagem da corrente
expiratória.” [CC 02, p. 32]
-3-
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
1.7 Encontros vocálicos
1.7.1 Ditongos
Ao encontro de uma VOGAL + uma SEMIVOGAL, ou de uma SEMIVOGAL + uma
VOGAL dá-se o nome de ditongo.
Os ditongos podem ser:
o Decrescentes e crescentes;
o Orais e nasais.
1.7.1.1 Ditongos decrescentes e crescentes
o Quando a vogal vem primeiro que a semivogal, o ditongo é decrescente. Assim:
Pai
céu
muito
o Quando a semivogal antecede a vogal, o ditongo diz-se crescente. Assim:
Qual
linguiça
frequente
Em português apenas os decrescentes são ditongos estáveis. Os ditongos crescentes aparecem
com frequência no verso. Mas na linguagem do colóquio normal só apresentam estabilidade
aqueles que têm a semivogal oral [w] (u ou o quando se lê u) precedida de [k] (letra q) ou de
um [g] (letra g). Assim:
Quase
igual
quando
enxaguando
Equestre
goela
lingueta
quinquénio
Quota
quiproquó
tranquilo
saguiguaçu
1.7.1.2 Ditongos orais e nasais
Os ditongos podem ser orais e nasais, segundo a natureza oral ou nasal dos seus elementos.
o Ditongos orais decrescentes (Tabela 1):
Tabela 1 - Ditongos orais decrescentes.
Grafias
ai
ei
au
éi
eu
éu
iu
oi
ói
ui
Exemplos
pai
sei
mau
papéis
meu
céu
viu
boi
herói
azuis
-4-
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
o Ditongos nasais decrescentes (Tabela 2):
Tabela 2 - Ditongos nasais decrescentes.
Grafias
ãe
ãi
em (na posição final da palavra)
en (no interior de palavras derivadas)
ão
am
õe
ui
Exemplos
mãe
cãibra
vem
benzinho
mão
vejam
Põe
sermões
muito
1.7.2 Tritongos
Denomina-se de tritongo o encontro formado de SEMIVOGAL + VOGAL + SEMIVOGAL.
De acordo com a natureza (oral ou nasal) dos seus componentes classificam-se também os
tritongos em orais e nasais.
o São tritongos orais (Tabela 3):
Tabela 3 - Tritongos orais.
Grafias
uai
uei
uiu
Exemplos
Uruguai
enxaguei
delinquiu
o São tritongos nasais (Tabela 4):
Tabela 4 - Tritongos nasais.
Grafias
uão
uam
uem
uõe
Exemplos
saguão
delinquem
saguões
1.7.3 Hiatos
Dá-se o nome de hiato ao encontro de duas vogais. Assim, comparando-se as palavras pais
(plural de pai) e país (região), verificamos que:
o na primeira, o encontro ai soa numa só sílaba;
o na segunda, o a pertence a uma sílaba e o i pertence a outra.
De salientar ainda que, quando átonos finais, os encontros escritos ia, ie, io, oa, ua, ue e uo
são normalmente ditongos crescentes: gló-ria, cá-rie, vá-rio, má-goa, á-gua, té-nue, ár-duo.
Podem, no entanto, ser emitidos com a separação dos dois elementos, formando assim um
Hiato: gló-ri-a, cá-ri-e, vá-ri-o, má-go-a, á-gu-a, té-nu-e, ár-du-o. Ressalte-se, porém, que na
escrita, em hipótese alguma, os elementos desses encontros vocálicos se separam no fim da
linha.
-5-
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
1.8 Encontros Consonantais
Dá-se o nome de encontro consonantal ao agrupamento de consoantes num vocábulo, este
agrupamento nunca pode ser separado, daí se designar encontro consonantal.
Entre os encontros consonantais merecem realce, pela frequência com que se apresentam,
aqueles cuja segunda consoante é l ou r, temos assim os seguintes encontros (Tabela 5):
Tabela 5 - Encontros consonantais frequentes.
Encontro
consonantal
Exemplos
Encontro
consonantal
Exemplos
bl
bloco, abluir
gl
glutão, aglutinar
br
branco, rubro
gr
grande, regra
cl
claro, reclama
pl
plano, triplo
cr
cravo, acre
pr
prato, sopro
dr
dragão, vidro
tl
tlim, atlas
fl
flor, ruflar
tr
tribo, atrás
fr
francês, refrão
vr
------, palavra
Encontros conosonantais como gn, mn, pn, ps, pt e tm não aparecem com muita frequência,
mas têm as seguintes particularidades.
o Quando iniciais, são naturalmente inseparáveis, ver a tabela (Tabela 6).
o Quando mediais podem ser articulados numa só sílaba, ou em sílabas distintas, quer com
isto dizer-se que pode efectuar-se a divisão silábica de duas formas distintas ver a tabela
(Tabela 6).
Tabela 6 - Encontros consonantais pouco frequentes.
Encontros
consonantais
Exemplos
(quando iniciais)
gn
gno-mo
mn
mne-mó-ni-co
pn
pneu-má-ti-co
ps
psi-co-lo-go
pt
pti-a-li-na
tm
tme-se
-6-
Encontros
consonantais
Exemplos
(quando mediais)
pt
a-pto ou ap-to
gn
di-gno ou dig-no
tm
ti-tmo ou rit-mo
CAPÍTULO 1. Regras e conceitos gramaticais do Português Europeu
1.9 Dígrafos
Nas palavras carro, pêssego, chave, malho e canhoto não há encontro consonantal, pois as
letras rr, ss, ch, lh e nh representam uma só consoante (são emitidas num só som).
Também não se pode afirmar que exista encontro consonantal em palavras como campo e
ponto, pois, nestes casos, o m e o n funcionam essencialmente como sinal de nasalidade da
vogal anterior, equivalendo, no caso, a um til (cãpo, põto).
A esses grupos de letras que simbolizam apenas um som dá-se o nome de dígrafos.
Consideram-se os digrafos da tabela (Tabela 7):
Tabela 7 - Digrafos.
Digrafos
Exemplos
Digrafos
Exemplos
Ch
ficha
gu, qu
(antes de e e i)
guerra, seguir,
querer, quilo
lh,
nh
velho,
tenho
sc, sç, xc
(entre vogais)
florescer, desça,
exceder
rr,
prorrogar,
ss
assim
am, an, em,
en, im, in,
om, on,
um, un
tampo, tanto, tempo,
tento, limbo, lindo,
pombo, tonto,
comum, mundo
1.10 Translineação
A translineação é a quebra de uma palavra no final de linha com a inclusão do hífen (-) na
mesma (por exemplo pala-/vra).
Para efectuar a translineação é necessário, em geral, que esta respeite a construção silábica.
Porém, a translineação introduz algumas alterações pontuais às regras de separação silábica.
Em hipótese alguma a separação silábica deve ser efectuada de forma a que uma letra fique
sozinha na linha seguinte a essa separação, devendo, se tal acontecer, essa letra juntar-se à
sílaba anterior.
Exemplo: a palavra Glória deve dividir-se em Gló-ria e não Gló-ri-a.
Outra alteração às regras da separação silábica diz respeito ao encontro de duas letras iguais,
sejam elas vogais ou consoantes, devendo estas pertencer a sílabas distintas.
Exemplo: ni-i-lis-mo, car-ro ou pas-se-ar.
Observação: É norma facultativa a repetição do hífen quando a translineação ocorre no local
onde se encontra o hífen que divide palavras compostas, prefixadas ou algumas formas
verbais.
Exemplo: a quebra de linha no hífen da palavra terça-feira deve fazer-se terça-/-feira.
-7-
CAPÍTULO 2. Regras usadas na construção do algoritmo
Capítulo 2
2 Regras usadas na construção do algoritmo
De seguida é apresentada uma lista das regras que vão ser respeitadas no algoritmo criado
para a correcta divisão silábica de um texto, as regras usadas resumem-se apenas em saber se
uma letra é ou não separada da letra anterior.
Nota: As palavras que contenham hífen no meio são interpretadas pelo algoritmo como duas
palavras distintas, procedendo à sua normal separação silábica e mantendo o hífen no seu
lugar original.
Exemplos: guar·da-chu·va, sex·ta-fei·ra, cou·ve-flor, su·per-ho·mem
2.1 Grupos de grafemas indivisíveis
Não se separam:
o os elementos dos encontros consonantais que iniciam uma sílaba, nem os dígrafos
(excepto se estes últimos forem formados pela mesma consoante, ex. carro).
Exemplos: a-blu-ção, a-bra-sar, a-che-gar, fi-lho, ma-nhã, con-tri-bu-ir, a-fri-ca-no, aplai-nar, en-gra-ça-do, re-fle-tir, su-bli-me...
o os encontros consonantais pouco frequentes mesmo quando mediais (a-pto). Neste último
caso poder-se-ia optar por separar as consoantes destes encontros, pois as duas formas
estão correctas, optamos neste caso em não efectuar a separação.
“ (…) Quando mediais, em pronúncia tensa, podem ser articulados numa só sílaba, ou em
sílabas distintas:
a-pto
di-gno
ri-tmo
ap-to
dig-no
rit-mo” [CC 02, p. 52]
o o s dos prefixos bis, cis, des, dis, trans e o x do prefixo ex não se separam quando a sílaba
seguinte começar por consoante. Todavia, se iniciar por vogal, formam sílaba com esta e
separam-se do prefixo.
-8-
CAPÍTULO 2. Regras usadas na construção do algoritmo
Exemplos: bis-ne-to, cis-pla-ti-no, des-li-gar, dis-tra-ção, trans-por-tar, ex-tra-ir, bi-sa-vó,
ci-san-di-no, de-ses-pe-rar, di-sen-te-ri-a, tran-sa-tlân-ti-co, e-xér-ci-to.
o As vogais dos ditongos decrescentes e crescentes nem as dos tritongos.
Exemplos: ai-ro-so, a-ni-mais, au-ro-ra, a-ve-ri-guei, ca-iu, cru-éis, re-jei-tar, fo-ga-réu,
gló-ria, i-guais, ó-dio, sa-guão, põe, cães, cãi-bra, não...
Observação: Não se separa do "u", precedido de "g" ou "q", a vogal que o segue,
acompanhada ou não de consoante. Exemplos: am-bí-guo, u-bí-quo, lín-gua, Gua-te-mala, de-lin-quen-te.
o A última vogal de uma palavra quando esta ficar sozinha caso se efectue a separação. Pois
uma vogal, mesmo formando uma sílaba, nunca deve ficar sozinha quando se efectua uma
translineação.
Exemplo: a palavra caía deve separar-se ca-ía e não ca-í-a.
o Os grupos ia, ie, io, oa, ua, ue, uo, que, quando átonos finais, soam normalmente numa
sílaba, mas podem ser pronunciados em duas.
Exemplo: má-goa, té-nue, ré-gua.
2.2 Grupos de grafemas que implicam separação
Separam-se:
o Os dígrafos cc, cç, sc, rr, ss e as vogais idênticas.
Exemplos: oc-cip-tal, te-lec-ção, pror-ro-gar, res-sur-gir, a-do-les-cen-te, con-va-les-cer,
des-cer, pres-cin-dir, res-ci-são, co-or-de-nar, ge-e-na.
o As vogais de hiatos, mesmo que diferentes uma da outra.
Exemplos: a-ta-ú-de, ca-í-eis, do-er, du-e-lo, fi-el, flu-iu, gra-ú-na, je-su-í-ta, le-al, mi-údo, po-ei-ra, ra-i-nha.
o Além das regras vistas anteriormente, a consoante que não vem seguida de vogal fica na
sílaba anterior.
Exemplos: sub-me-ter, sub-por, ab-so-lu-to, ad-vo-ga-do, ad-no-mi-nal, ad-vir, af-ta,
mag-ma, cog-no-me, al-fai-a-te, nos-tal-gi-a, e-gíp-cio, re-cep-ção, ap-to, ar-far, ex-su-dar,
ex-ce-ção, tungs-tê-nio, pers-pi-cá-cia, sols-tí-cio, ab-di-car, ac-ne, drac-ma, Daf-ne, ét-nico, nup-ci-al, abs-tra-ir, ins-pe-tor, ins-tru-ir, in-ters-tí-cio.
Observação: Ainda observando o caso acima mencionado, se a consoante for inicial, ela
não se separa. Exemplos: Pto-lo-meu, psi-co-se, pneu-má-ti-co, gno-mo, mne-mô-ni-ca.
-9-
CAPÍTULO 3. Implementação
Capítulo 3
3 Implementação
A implementação do projecto foi efectuada na linguagem de programação C com o auxílio da
ferramenta Visual Studio 2005 da Microsoft, sendo o código compilado usando o compilador
da mesma ferramenta.
A implementação deste código encontra-se dividida por 4 ficheiros distintos, são eles:
o O ficheiro main.cpp, contém a função principal do programa, função void main(), a qual
invoca as principais funções declaradas no ficheiro Funcoes.h e definidas no ficheiro
Funcoes.cpp.
o O ficheiro Constantes.h contém a declaração de constantes usadas no programa.
o O ficheiro Funcoes.h contém os cabeçalhos das funções implementadas no ficheiro
Funcoes.cpp.
o O ficheiro Funcoes.cpp contém a implementação de todas as funções referentes ao
programa.
3.1 Ficheiro main.cpp
O ficheiro main.cpp contém a principal função do projecto (void main()), que, para além de
possuir um pequeno menu que permite ao utilizador a inserção do nome do ficheiro a tratar,
ela invoca três funções do ficheiro Funcoes.h. Estas três funções representam as três
diferentes etapas por onde o tratamento de um texto passa. São elas:
o O pré-processamento (primeira etapa), representado pela função void preProc(FILE
*fin);
o O processamento (segunda etapa), representado pela função void proc();
o O pós-processamento (terceira etapa), representado pela função void posProc().
- 10 -
CAPÍTULO 3. Implementação
3.2 Ficheiro Constantes.h
Este ficheiro foi criado apenas para definir as constantes a usar no projecto.
Para evitar qualquer confusão com os caracteres gráficos do texto original, foram usados os
caracteres da tabela ASCII estendida (caracteres entre o código 128 e o 255) para as
constantes que passam a representar os encontros consonantais referenciados e os outros
grupos de grafemas que a seguir se descrevem.
As constantes aqui existentes podem repartir-se em cinco grupos:
o Consoantes inseparáveis;
o Vogais inseparáveis;
o Vogais acentuadas e c com cedilha (ç e Ç);
o Representantes de maiúsculas;
o Símbolo que representa a separação silábica ( · ).
3.2.1 Consoantes inseparáveis
Deste grupo fazem parte os encontros consonantais sendo que cada um dos encontros é
representado por um carácter específico da tabela ASCII, observar a tabela (Tabela 8).
Tabela 8 - Símbolos ASCII que representam as consoantes inseparáveis.
Encontros
consonantais
Carácter
ASCII
Símbolo
ASCII
Encontros
consonantais
Carácter
ASCII
Símbolo
ASCII
BL
BR
CH
CL
CR
DR
FL
FR
GL
GR
LH
NH1
130
131
132
133
134
135
136
137
138
139
140
141
‚
ƒ
„
…
†
‡
ˆ
‰
Š
‹
Œ
PL
PR 1
TL1
TR
VR
GN
MN
PN
PS
PT
TM
142
143
144
145
146
147
148
149
150
151
152
Ž
1
‘
’
“
”
•
–
–
˜
O símbolo ASCII em branco significa que não existe uma representação visual para o referido carácter ASCII.
- 11 -
CAPÍTULO 3. Implementação
Este grupo de constantes foi criado com a finalidade de simplificar o tratamento das palavras,
pois, como estes grupos de consoantes nunca podem ser separados quando se efectua a
separação silábica, podemos considerá-los como sendo uma única consoante. Desta forma,
por exemplo, a palavra Brasil será tratada como ƒasil 2 .
3.2.2 Vogais inseparáveis
Tal como nas consoantes inseparáveis, este grupo de constantes, que representam as vogais
inseparáveis, foi criado para simplificar o tratamento de palavras. Este grupo é mais reduzido
que o anterior, pois, ao contrário desse, no grupo de vogais inseparáveis não é possível dizerse quais as vogais que nunca poderão ser separadas. Assim temos apenas as vogais
inseparáveis da tabela (Tabela 9).
Tabela 9 - Símbolos ASCII que representam as vogais inseparáveis.
Vogais
inseparáveis
Carácter
ASCII
Símbolo
ASCII
Vogais
inseparáveis
Carácter
ASCII
Símbolo
ASCII
AE (ãe)
153
™
AO (ão)
155
›
AI (ãi)
154
š
OE (õe)
156
œ
Neste grupo é fácil verificar porque foram criadas estas constantes, pois, nunca fará sentido
separar, por exemplo nas vogais ão, o ã do o. Desta forma, por exemplo, a palavra cão será
tratada como c› 3 .
2
O ‘ƒ’ da palavra ƒasil representa o código 131 da tabela ASCII, o código deste símbolo não é o mesmo da letra
f que tem o código ASCII 112, ver tabela (Tabela 8).
3
O ‘›’ da palavra c› representa o código 155 da tabela ASCII, ver tabela (Tabela 9).
- 12 -
CAPÍTULO 3. Implementação
3.2.3 Vogais acentuadas e c com cedilha
Este grupo de constantes foi criado para melhor identificar este tipo de letras, veja-se a tabela
(Tabela 10).
Tabela 10 - Vogais acentuadas e c com cedilha
Constantes Significado Carácter Símbolo Constantes Significado Carácter Símbolo
ASCII
ASCII
ASCII
ASCII
A_g
A_a
A_c
A_t
À
Á
Â
Ã
192
193
194
195
À
Á
Â
Ã
a_g
a_a
a_c
a_t
à
á
â
ã
224
225
226
227
à
á
â
ã
C_ced
Ç
199
Ç
c_ced
ç
231
ç
E_g
E_a
E_c
È
É
Ê
200
201
202
È
É
Ê
e_g
e_a
e_c
è
é
ê
232
233
234
è
é
ê
I_g
I_a
I_c
Ì
Í
Î
204
205
206
Ì
Í
Î
i_g
i_a
i_c
ì
í
î
236
237
238
ì
í
î
O_g
O_a
O_c
O_t
Ò
Ó
Ô
Õ
210
211
212
213
Ò
Ó
Ô
Õ
o_g
o_a
o_c
o_t
ò
ó
ô
õ
242
243
244
245
ò
ó
ô
õ
U_g
U_a
U_c
Ù
Ú
Û
217
218
219
Ù
Ú
Û
u_g
u_a
u_c
ù
ú
û
249
250
251
ù
ú
û
3.2.4 Representantes de maiúsculas
O texto ao qual se pretende efectuar a separação silábica poderá estar escrito com maiúsculas
e minúsculas, logo poderemos ter muitas formas de escrever a mesma palavra, por exemplo a
palavra Ana, poderá surgir escrita de 8 formas distintas, ana, Ana, aNa, anA, ANa, AnA, aNA
e ANA, de salientar que esta palavra tem apenas 3 letras.
Então para resolver esta ambiguidade foi criado este grupo de constantes, que permite marcar
quais as letras de uma palavra que estão escritas em maiúsculas, podendo com isto substituirse essa letra pela sua correspondente minúscula, eliminando desta forma a ambiguidade acima
referida. Para efectuar a marcação coloca-se uma destas constantes imediatamente antes à
letra, ou grupo de letras (consoantes inseparáveis ou vogais inseparáveis) que está escrita em
maiúscula, veja-se a tabela (Tabela 11) que mostra quais as constantes que fazem parte deste
grupo e exemplifica a utilização das mesmas.
- 13 -
CAPÍTULO 3. Implementação
Tabela 11 - Representantes de maiúsculas.
Representação
Carácter ASCII
Símbolo ASCII
Exemplo
4
157
xX
158
Ž
bRasil Æ xXbrasil Æ xXƒasil
XX
159
Ÿ
BRasil Æ XXbrasil Æ XXƒasil
Xx
Brasil Æ Xxbrasil Æ Xxƒasil
braSiL Æ braXxsiXxl Æ ƒaXxsiXxl
Como podemos verificar na tabela (Tabela 11) existem 3 constantes neste grupo.
A constante Xx é usada para letras individuais ou para grupos de letras. Para letras
individuais, indica que a próxima letra é maiúscula (ex: Xxescuro Æ Escuro), para grupos de
letras, indica que das duas letras que constituem o grupo apenas a primeira é maiúscula (ex:
Xx„uva 5 Æ Xxchuva Æ Chuva).
As constantes xX e XX são usadas apenas para grupos de letras. xX serve para indicar que
apenas a segunda letra do próximo grupo é maiúscula (ex: nexX um 6 Æ nexXnhum Æ
nenHum). XX serve para indicar que as duas letras que constituem o grupo são maiúsculas
(ex: neXX um6 Æ neXXnhum Æ neNHum).
3.2.5 Símbolo de separação silábica
Esta é a última constante declarada no ficheiro Constantes.h, tem como finalidade representar
a separação silábica das palavras, esta constante é representada pelo nome Separador, sendo
esta o carácter ASCII 183 e tendo como símbolo “·”.
Exemplo de uma palavra separada, amanhã Æ a·ma·nhã.
4
O símbolo ASCII em branco significa que não existe uma representação visual para o referido carácter ASCII..
5
O ‘„’ da palavra Xx„uva representa o código 132 da tabela ASCII, ver tabela (Tabela 8).
6
O símbolo ASCII em branco da palavra nexX um representa o código 141 da tabela ASCII, ver tabela (Tabela
8).
- 14 -
CAPÍTULO 3. Implementação
3.3 Ficheiro Funcoes.h
Este ficheiro contém a declaração das funções implementadas no ficheiro Ficheiro
Funcoes.cpp. As funções declaradas são as seguintes:
o
o
o
o
o
o
o
o
o
o
o
void
void
void
void
void
bool
bool
bool
bool
bool
bool
preProc(FILE *fin);
proc();
posProc();
criaSilabas(int palIn[]);
constroiPal(int palOrig[], int palIn[], FILE *fout) ;
letra(int ch);
sinalMaiuscula(int ch);
vogal(int ch);
semivogal(int ch1, int ch2, int ch3);
ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3, int i);
tritongo(int ch1, int ch2, int ch3, int ch4).
As funções preProc(…), proc() e posProc() são invocadas pela função main() do ficheiro
main.cpp.
Todas as outras funções aqui referidas são invocadas pelas funções implementadas no ficheiro
Funcoes.cpp.
3.4 Ficheiro Funcoes.cpp
Este ficheiro efectua a implementação das funções declaradas no ficheiro Funcoes.h. De
seguida iremos explicar detalhadamente a tarefa de cada uma destas funções e a forma como
elas realizam essas tarefas.
3.4.1 void preProc(FILE *fin)
O nome dado à função preProc(File *fin) significa pré-processamento, isto porque na
realidade esta função efectua um pré-processamento ao texto original (passado como
parâmetro da função) ao qual se pretende efectuar a separação silábica.
O resultado deste tratamento vai ser guardado no ficheiro PosProcessamento.txt, desta forma
garantimos que o ficheiro original nunca é alterado.
Pretende-se com este processamento facilitar a divisão silábica, permitindo com isto diminuir
o número de casos a tratar e facilitando o tratamento das palavras, neste processo efectuam-se
duas operações:
3.4.1.1 Primeira operação
Efectua a substituição de grupos de consoantes ou de vogais inseparáveis pelas constantes
(existentes no ficheiro Constantes.h) que representam cada um destes encontros.
- 15 -
CAPÍTULO 3. Implementação
3.4.1.2 Segunda operação
Efectua a substituição dos caracteres maiúsculos por minúsculos e efectua a sua marcação
com os representantes de maiúsculas onde é efectuada essa substituição.
3.4.2 void proc()
O nome dado a esta função significa processamento, porque é com a invocação desta função
que se efectua a separação silábica do texto previamente tratado no ponto anterior (processo
ao qual a realização deste projecto se destina).
Para efectuar a separação silábica é usado como entrada o ficheiro PreProcessamento.txt
(texto a tratar), sendo o resultado deste processo registado no ficheiro PosProcessamento.txt
(texto tratado).
Esta função efectua uma análise ao ficheiro PreProcessamento.txt, retirando deste as palavras
a tratar, para a identificação das palavras a função proc() usa as funções letra(…) e
sinalMaiuscula(…). Estas palavras são guardadas em dois arrays diferentes palOrig[120]
e palIn[120], estes arrays guardam a próxima palavra a tratar.
O primeiro array inclui, para além da palavra, as constantes representantes de maiúsculas (ex:
Xxteste) e o segundo não inclui essas constantes (ex: teste), ou seja contém a palavra
conforme está escrita no ficheiro original mas, com todas as letras escritas em minúsculas.
A existência destes dois arrays deve-se ao facto de tornar mais fácil a separação silábica, pois
o array palIn[…] possui apenas letras para tratar e ao facto de permitir reconstruir a palavra
tal como estava no ficheiro original usando o array palOrig[…].
Para a realização da tarefa a que esta função se destina (proc()) ela é auxiliada pelas funções
criaSilabas(int palIn[]) e constroiPal(int palOrig[],int palIn[],FILE *fout).
O array palIn[120] é passado como parâmetro para a função criaSilabas(int palIn[]),
sendo este alterado nesta função de forma a possuir a divisão silábica.
Depois deste processo o array é passado, juntamente com o array palOrig[…] e com o
ficheiro PosProcessamento.txt para a função constroiPal(…).
Este processo é repetido para todas as palavras existentes no ficheiro PosProcessamento.txt.
3.4.3 void posProc()
O nome dado a esta função significa pós-processamento, isto porque esta função efectua um
pós-processamento ao texto do ficheiro PosProcessamento.txt.
Esta função tem como finalidade efectuar o processamento inverso realizado pela função
preProc(FILE *fin) e gravar no ficheiro Final.txt todas as alterações efectuadas. Ou seja,
esta função vai converter as constantes do ficheiro Constantes.h pelos grupos de consoantes
ou de vogais inseparáveis, vai efectuar a substituição das letras minúsculas em maiúsculas nos
locais onde se encontrem as representantes de maiúsculas e vai gravar no ficheiro Final.txt as
palavras silabicamente divididas e com as maiúsculas nos devidos lugares.
- 16 -
CAPÍTULO 3. Implementação
3.4.4 void criaSilabas(int palIn[])
Esta função é invocada pela função proc() e efectua a separação silábica da palavra passada
como parâmetro (palIn[]). Por exemplo, entra a palavra caminhar e sai a palavra ca·mi·nhar.
Para melhor compreender a forma como a separação silábica é efectuada veja-se o fluxograma
(Figura 1).
Para a realização da tarefa a que esta função se destina ela serve-se das seguintes funções:
o
o
o
o
bool
bool
bool
bool
vogal(int ch)
semivogal(int ch1, int ch2, int ch3)
ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3, int i)
tritongo(int ch1, int ch2, int ch3, int ch4) 3.4.5 void constroiPal(int palOrig[], int palIn[], FILE *fout)
Esta função é invocada pela função proc(), foi criada para fazer a junção entre os dois arrais
que recebe como parâmetros, gravando o resultado no ficheiro que também recebe como
parâmetro.
Esta tarefa é necessária pois anteriormente, na função proc(), é efectuada uma separação dos
caracteres da palavra a tratar, permitindo isto que a função criaSilabas(…) apenas tenha
para tratar os caracteres que representam letras e as próprias letras, e não os representantes de
maiúsculas, sendo por isto necessário que a nova palavra (já com a separação silábica
efectuada) volte a ser constituída também pelos representantes de maiúsculas.
Então esta função tem como finalidade juntar ao array palIn[] os representantes de
maiúsculas que estão no array palOrig[] e guardar no ficheiro PosProcessamento.txt o
resultado dessa junção.
Exemplo: Ao processar a palavra Caminhar esta função irá receber os arrays Xxcami ar 7 e
ca·mi· ar irá então escrever no ficheiro de saida Xxca·mi· ar.
3.4.6 bool letra(int ch)
Esta função tem como finalidade verificar se o carácter que recebe como parâmetro é uma
letra do alfabeto ou um carácter que representa consoantes inseparáveis, vogais inseparáveis,
vogais acentuadas ou um c com cedilha, devolvendo verdadeiro (true) caso seja um destes
caracteres ou falso (false) caso contrário.
7
Xx representa o carácter ASCII 157 (ver a Tabela 11). O símbolo ASCII em branco representa as consoantes
inseparáveis NH representadas pelo carácter ASCII 141 (ver a Tabela 8)
- 17 -
CAPÍTULO 3. Implementação
3.4.7 bool vogal(int ch)
Esta função serve para verificar se o carácter que receber como parâmetro é uma vogal, uma
vogal acentuada ou um grupo de vogais inseparáveis, ela devolve verdadeiro (true) caso seja
um destes caracteres ou falso (false) caso contrário.
3.4.8 bool semivogal(int ch1, int ch2, int ch3)
Esta função verifica se o carácter ch1 passado como parâmetro é uma semivogal, devolvendo
verdadeiro (true) caso seja ou falso (false) caso contrário. Para se verificar que ch1 é uma
semivogal esta função necessita de receber mais dois parâmetros (ch2 e ch3).
Em primeiro lugar, para ch1 ser uma semivogal é necessário que este seja a vogal i ou u. Caso
isto se verifique então ch1 e ch2 não podem ser iguais (niilismo) nem ch2 pode ser u (viu),
nem n, nem uma representante de maiúscula e ch2 não pode ser r nem l caso estes sejam a
última letra da palavra (cair) ou a primeira de duas ou mais consoantes (cairmos).
3.4.9 bool ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3, int i)
Esta função verifica se os caracteres chAnt e ch1, passados como parametros da função,
formam um ditongo. Ela devolve verdadeiro (true) caso formem ou falso (false) caso
contrário. Para efectuar esta verificação, para além destes dois parâmetros, a função recebe
ainda os caracteres chAnt2, ch2, ch3 e o valor i.
O valor i apenas serve para nos indicar qual a posição, na palavra que estamos a processar,
onde se encontra o carácter ch1.
Para que os caracteres chAnt e ch1 formem um ditongo é necessário que não sejam iguais
(compreender) e que se verifique um dos seguintes pontos:
o se chAnt2 for q ou g e se chAnt for u ch1 tem de ser uma vogal (quero);
o se chAnt for uma vogal, mas não semivogal ch1 tem de ser uma semivogal (ainda);
o se ch1 for e e ch2 for m, ch2 tem de ser a última letra da palavra (bem);
o se ch1 for e e ch2 for n, ch2 não pode ser a última letra da palavra (benzinho);
o se chAnt não for uma vogal, se ch1 for a e se ch2 for m ch2 tem de ser a última letra da
palavra (levam);
o se chAnt for o ch1 tem de ser u (outro);
o se chAnt for u ch1 tem de ser i (muito);
o se chAnt for a ch1 tem de ser o (caos).
- 18 -
CAPÍTULO 3. Implementação
3.4.10 bool tritongo(int ch1, int ch2, int ch3, int ch4)
Esta função verifica se os caracteres ch1, ch2 e ch3, passados como parametros da função,
formam um tritongo, ela devolve verdadeiro (true) caso formem ou falso (false) caso
contrário. Para efectuar esta verificação, para além destes três parâmetros, a função recebe
ainda os caracteres chAnt e ch4.
Para que a existência de um tritongo se verifique é necessário que ch1 seja u e que se
verifique um dos seguintes casos:
o ch2 tem de ser um dos conjuntos de vogais inseparáveis (saguão);
o ch2 tem de ser a e ch3 tem de ser i ou m (Uruguai);
o ch2 tem de ser e e ch3 tem de ser i ou m desde que, neste último caso, ch3 seja a última
letra da palavra (enxaguei, quem);
o chAnt tem de ser q ou g, ch2 tem de ser i e ch3 tem de ser u (conseguiu, delinquiu).
3.4.11 bool sinalMaiuscula(int ch)
Esta função verifica se o caracter ch, passado como parametro da função, é um representante
de maiúscula devolvendo verdadeiro (true) caso seja ou falso (false) caso contrário.
- 19 -
CAPÍTULO 3. Implementação
Figura 1 - Fluxograma da função criaSilabas(…) (adaptado de [GTF 00])
- 20 -
Capítulo 4
4 Ficheiros gerados nas várias fases de
processamento
4.1 Ficheiro de entrada
O ficheiro de entrada é aquele que o utilizador introduzir no menu do início do programa,
sendo que este deve ser sempre um ficheiro de texto (.txt) de forma a evitar erros de
tratamento.
Este é o ficheiro ao qual se irá efectuar a separação silábica. De forma a nunca o danificar,
nem o alterar, decidimos que todas as alterações, processamentos e resultados finais, seriam
gravados em ficheiros de texto auxiliares, preservando desta forma o ficheiro original.
4.2 Ficheiro PreProcessamento.txt
O ficheiro PreProcessamento.txt serve como auxiliar para melhor compreensão da
transformação que está a ocorrer. Pode assim constatar-se a substituição de algumas palavras
por símbolos que definimos no algoritmo. Encontros como as consoantes inseparáveis, as
vogais inseparáveis, as vogais acentuadas e o c de cedilha vão sendo substituídos pelos
respectivos símbolos da tabela ASCII. Também é dado um tratamento semelhante às letras
maiúsculas.
4.3 Ficheiro PosProcessamento.txt
O ficheiro PosProcessamento.txt tem uma finalidade análoga à do ficheiro
PreProcessamento.txt. A única diferença é que este já apresenta a separação silábica
efectuada, no entanto contém ainda os símbolos que anteriormente tinham sido inseridos.
- 21 -
4.4 Ficheiro Final.txt
O ficheiro Final.txt é o último ficheiro criado durante a execução do algoritmo. Contém o
output da aplicação, é apresentado conforme o ficheiro original mas contendo também a
divisão silábica efectuada.
- 22 -
Capítulo 5
5 Conclusões
5.1 Teste e análise de resultados
A aplicação do algoritmo desenvolvido foi testada com um texto composto por 11450
palavras que nos foi facultado pelo orientador do projecto. No entanto depois de retiradas as
palavras repetidas, o texto ficou com um total de 3113 palavras. A divisão silábica foi
previamente feita de modo manual, servindo depois para comparação com os resultados
obtidos pelo algoritmo. Ocorrendo apenas um erro (na palavra cairemos) chegou-se a uma
taxa de acerto de 99,968%.
O erro encontrado na palavra cairemos ficou dividido da seguinte forma: cai-re-mos. Mas
deveria ter ficado ca-i-re-mos, este erro é um caso muito difícil de tratar, pois existe uma
confusão entre hiato (deve dividir-se) e ditongo crescente (não se pode dividir).
Após a realização deste trabalho, é possível concluir que os resultados obtidos excederam as
nossas expectativa. Ainda assim, a excelente taxa de acerto que se conseguiu para o texto de
teste não é suficiente para podermos afirmar que o algoritmo tenha sempre este grau de
infalibilidade, pois esse texto é uma pequena amostra da totalidade das palavras do português
europeu.
5.2 Trabalho a desenvolver futuramente
Este projecto pode ser considerado uma etapa inicial de um trabalho que posteriormente pode
ser ainda mais aprofundado. A sua utilização no aperfeiçoamento de sintetizadores de fala ou
mesmo como uma ferramenta auxiliar de divisão silábica automática para estudantes do
ensino básico, são dois bons exemplos da utilidade e da importância que o trabalho pode ter.
Mas a aplicação mais imediata que antevemos para o trabalho que aqui apresentamos passa
pela sua integração num processador de texto (LaTex ou OpenOffice, por exemplo) como
ferramenta de translineação.
- 23 -
Bibliografia
[S 08]
Sousa, M. Vogal. http://pt.wikipedia.org/wiki/Vogal – 20 de Agosto de 2008.
[B 08]
BOT-Superzerocool. Consoante. http://pt.wikipedia.org/wiki/Consoante – 17 de Agosto de
2008.
[K 08]
Kwjbot. Sílaba. http://pt.wikipedia.org/wiki/S%C3%ADlaba – 30 de Julho de 2008.
[R 08]
RobotGMwikt. sílaba. http://pt.wiktionary.org/wiki/s%C3%ADlaba – 6 de Junho de 2008.
[W 07]
Wikia. Semivogal. http://pt.conlang.wikia.com/wiki/Vogal#Semivogais – 17 de Abril 2007.
[M 04]
Marque de Sá, J. P. Fundamentos de Programação usando C. FCA – Editora de Informática,
LDA – Setembro de 2004.
[CC 02]
Cunha, C., Cintra, L. Nova Gramática do Português Contemporâneo. Edições João Sá da
Costa, LDA – 17ª edição, 2002.
[GTF 00]
Gouveia, P., Teixeira, J., Freitas, D. Actas do V PROPOR – Processamento Computacional da
Língua Portuguesa Escrita e Falada. S. Paulo Brasil pp. 65 – 2000.
[P 00]
Paes, E. F. Divisão Silábica http://intervox.nce.ufrj.br/~edpaes/divisao.htm – Outubro de 2000.
[D 99]
Damas, L. Linguagem C. FCA – Editora de Informática, LDA – Janeiro de 1999.
- 24 -
Apêndice A
A Código Fonte
A.1 Ficheiro main.cpp
#pragma once
#include <iostream>
#include <stdio.h>
#include "Funcoes.h"
void main()
{
FILE *fin;
char s[100];
puts("Insira o nome do ficheiro de entrada (original)!\n");
gets(s);
fopen_s(&fin,s,"r");
if(fin==NULL)
printf("Impossivel abrir\n");
else{
preProc(fin);
proc();
posProc();
fclose(fin);
}
}
A.2 Ficheiro Constantes.h
/* Atribuições de Constantes */
// Consuantes inseparáveis
#define BL 130
#define BR 131
#define CH 132
#define CL 133
#define CR 134
#define DR 135
#define FL 136
#define FR 137
#define GL 138
#define GR 139
#define LH 140
#define NH 141
#define PL 142
#define PR 143
#define TL 144
#define TR 145
#define VR 146
#define
#define
#define
#define
#define
#define
GN
MN
PN
PS
PT
TM
147
148
149
150
151
152
// Vogais inseparáveis
#define AE 153
//
#define AI 154
//
#define AO 155
//
#define OE 156
//
ãe
ãi
ão
õe
// Simbulos usados para representar as letras maiusculas quando se
// encontram consuantes ou vogais inseparaveis
#define Xx 157 // letra maiuscula seguida de minuscula
#define xX 158 // letra minuscula seguida de maiuscula
#define XX 159 // letra maiuscula seguida de maiuscula
// símbolo que marca a separação das silabas
#define Separador 183
// Vogais acentuadas e c com cedilha ('ç' e 'Ç')
#define A_g 192 // À
#define A_a 193 // Á
#define A_c 194 // Â
#define A_t 195 // Ã
#define C_ced 199 // Ç
#define E_g 200 // È
#define E_a 201 // É
#define E_c 202 // Ê
#define I_g 204 // Ì
#define I_a 205 // Í
#define I_c 206 // Î
#define
#define
#define
#define
O_g
O_a
O_c
O_t
210
211
212
213
//
//
//
//
Ò
Ó
Ô
Õ
#define U_g 217 // Ù
#define U_a 218 // Ú
#define U_c 219 // Û
#define
#define
#define
#define
a_g
a_a
a_c
a_t
224
225
226
227
//
//
//
//
à
á
â
ã
#define c_ced 231 // ç
#define e_g 232 // è
#define e_a 233 // é
#define e_c 234 // ê
#define i_g 236 // ì
#define i_a 237 // í
#define i_c 238 // î
#define
#define
#define
#define
o_g
o_a
o_c
o_t
242
243
244
245
//
//
//
//
ò
ó
ô
õ
#define u_g 249 // ù
#define u_a 250 // ú
#define u_c 251 // û
A.3 Ficheiro Funcoes.h
#pragma once
#include <iostream>
#include "constantes.h"
void
bool
bool
bool
bool
bool
bool
void
void
void
void
preProc(FILE *fin);
letra(int ch);
vogal(int ch);
sinalMaiuscula(int ch);
semivogal(int ch1, int ch2, int ch3);
ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3);
tritongo(int ch1, int ch2, int ch3, int ch4);
criaSilabas(int palIn[]);
constroiPal(int palOrig[], int palIn[], FILE *fout);
proc();
posProc();
A.4 Ficheiro Funcoes.cpp
#include "Funcoes.h"
int num=0; // esta variável faz a contagem das palavras divididas
silábicamente
//esta função efectua uma um processamento ao texto original, convertendo
os caracteres maiusculos em minusculos
// (assinalando essa alteração com os simbolos xX, Xx, e XX), e também
conver te as vogais e consuantes
// inseparaveis em simbolos auxiliares
void preProc(FILE *fin){
// ch1
1º caracter lido
// ch2
2º caracter lido
// aux
guarda o simbolo a escrever caso, abaixo, se
encontre uma das combinções ch1 e ch2
// i ao encontrar uma das seguintes combinações de ch1 e ch2 o
'i' verifical se são maiusculas
int ch1, ch2=0, aux;
int i;
FILE *fout;
fopen_s(&fout,"PreProcessamento.txt", "w");
while((ch1=fgetc(fin))!=EOF){
i=0;
aux=0;
if(ch2!=0){
switch (ch2){
case A_t:
case a_t:
switch (ch1){
case 'E':
case 'e':
case 'O':
case 'o':
case 'I':
case 'i':
}break;
case O_t:
case o_t:
switch (ch1){
case 'E':
case 'e':
}break;
case 'B':
case 'b':
switch (ch1){
case 'L':
case 'l':
case 'R':
case 'r':
}break;
case 'C':
case 'c':
switch (ch1){
case 'H':
aux = AE; break;
aux = AO; break;
aux = AI; break;
aux = OE; break;
aux = BL; break;
aux = BR; break;
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case 'h':
case 'L':
case 'l':
case 'R':
case 'r':
}break;
'D':
'd':
switch (ch1){
case 'R':
case 'r':
}break;
'F':
'f':
switch (ch1){
case 'L':
case 'l':
case 'R':
case 'r':
}break;
'G':
'g':
switch (ch1){
case 'L':
case 'l':
case 'R':
case 'r':
case 'N':
case 'n':
}break;
'L':
'l':
switch (ch1){
case 'H':
case 'h':
}break;
'M':
'm':
switch (ch1){
case 'N':
case 'n':
}break;
'N':
'n':
switch (ch1){
case 'H':
case 'h':
}break;
'P':
'p':
switch (ch1){
case 'L':
case 'l':
case 'R':
case 'r':
case 'N':
case 'n':
case 'S':
case 's':
case 'T':
case 't':
aux = CH; break;
aux = CL; break;
aux = CR; break;
aux =DR; break;
aux = FL; break;
aux = FR; break;
aux = GL; break;
aux = GR; break;
aux = GN; break;
aux = LH; break;
aux = MN; break;
aux = NH; break;
aux = PL; break;
aux = PR; break;
aux = PN; break;
aux = PS; break;
aux = PT; break;
}break;
case 'T':
case 't':
switch (ch1){
case 'L':
case 'l':
case 'R':
case 'r':
case 'M':
case 'm':
}break;
case 'V':
case 'v':
switch (ch1){
case 'R':
case 'r':
}break;
aux = TL; break;
aux = TR; break;
aux = TM; break;
aux = VR; break;
}
if((ch2>='A' && ch2<='Z') || (ch2>=A_g && ch2<=U_c))
i++;
if(aux!=0){
if(((ch1>='A' && ch1<='Z') || (ch1>=A_g &&
ch1<=U_c))&& ch2>=0)
i = i+2;
switch (i){
case 0: break;
case 1: fputc(Xx,fout); break;
case 2: fputc(xX,fout); break;
case 3: fputc(XX,fout); break;
}
fputc(aux,fout);
ch1=0;
}
else{
if(i){
fputc(Xx,fout);
fputc(ch2+32,fout);
}
else
fputc(ch2,fout);
}
}
ch2=ch1;
}
if(ch2)
fputc(ch2,fout);
fclose(fout);
}
//verifica se o 'ch' é uma letra ou uma vogal, ou consuante inseparável
bool letra(int ch){
if((ch>='a' && ch<='z')||(ch>='A' && ch<='Z')||(ch>=BL &&
ch<=OE)||(ch>=A_g && ch<=A_t)||(ch>=C_ced && ch<=E_c)
||(ch>=I_g && ch<=I_c)||(ch>=O_g && ch<=O_t)||(ch>=U_g &&
ch<=U_c)||(ch>=a_g && ch<=a_t)||(ch>=c_ced && ch<=e_c)
||(ch>=i_g && ch<=i_c)||(ch>=o_g && ch<=o_t)||(ch>=u_g &&
ch<=u_c) )
return(true);
else
return(false);
}
//verifica se 'ch' é uma vogal, ou uma vogal inseparável
bool vogal(int ch){
if(ch=='a' || ch=='A' || ch=='e' || ch=='E' || ch=='i' || ch=='I' ||
ch=='o' || ch=='O' || ch=='u' || ch=='U' ||
(ch>=a_g && ch<=a_t) || (ch>=A_g && ch<=A_t) || (ch>=e_g &&
ch<=e_c) || (ch>=E_g && ch<=E_c) ||
(ch>=i_g && ch<=i_c) || (ch>=I_g && ch<=I_c) || (ch>=o_g &&
ch<=o_t) || (ch>=O_g && ch<=O_t) ||
(ch>=u_g && ch<=u_c) || (ch>=U_g && ch<=U_c) || (ch>=AE &&
ch<=OE))
return(true);
else
return(false);
}
//verifica se 'ch' é o simbulo 'Xx', 'xX' ou 'XX'
bool sinalMaiuscula(int ch){
if(ch>=Xx && ch<=XX)
return(true);
else
return(false);
}
//verifica se 'ch1' é uma semivogal
bool semivogal(int ch1, int ch2, int ch3){
bool res = false;
if(ch1 =='i' || ch1=='u'){
if((ch1==ch2) || (ch2=='u') || (ch2=='n') || (ch2>=BL &&
ch2<=TM) || ((ch2=='r' || ch2=='l') && (ch3=='\0' || (letra(ch3) &&
!vogal(ch3)))))
res = false;
else
res = true;
}
return res;
}
//verifica se 'ch1' forma um ditongo
bool ditongo(int chAnt2, int chAnt, int ch1, int ch2, int ch3,int i){
bool res = false;
if((chAnt2=='q' || chAnt2=='g') && chAnt=='u' && vogal(ch1))
res = true;
if(vogal(chAnt) && !semivogal(chAnt, ch1, ch2)){
if(semivogal(ch1, ch2, ch3))
res = true;
}
if(
(ch1=='e' && ch2=='m' && ch3=='\0')
// "em" no final de uma palavra (bem)
|| (ch1=='e' && ch2=='n' && ch3!='\0' && !vogal(chAnt))
// "en" no meio de uma palavra (ben-zi-nho)
||
"am" no fim de
||
//
||
"ui" (mui-to)
||
//
||
(ch1=='a' && ch2=='m' && ch3=='\0' && !vogal(chAnt))
uma palavra (le-vam)
(chAnt=='o' && ch1=='u')
(ou-tro)
(chAnt=='u' && ch1=='i' && (i<=2 || ch2=='\0'))
//
//
(chAnt=='a' && ch1=='o')
"ao" (caos)
(chAnt=='a' && ch1=='u'))
res = true;
if((chAnt=='e' && ch1=='i') || ch1==ch2)
res=true;
if(chAnt == ch1)
res = false;
return res;
}
//verifica se 'ch1' forma uma tritongo
bool tritongo(int chAnt, int ch1, int ch2, int ch3, int ch4){
// sv+v+sv
(U-ru-guai)
bool res = false;
if(ch1=='u')
if(ch2>=AE && ch2<=OE) // (sa-guão, sa-guões)
res = true;
else
if(ch2=='a' && (ch3=='i' || ch3=='m' && ch4=='\0')) //
(U-ru-guai)
res = true;
else
if(ch2 =='e' && (ch3=='i' || (ch3=='m' &&
ch4=='\0')))
// (en-xa-guei, quem)
res = true;
else
if(ch2=='i' && ch3=='u' && (chAnt=='q' ||
chAnt=='g'))
// (con-se-guiu, de-lin-quiu)
res = true;
return res;
}
// esta é a função principal, é aquela que efectua a separação silabica das
palavras
void criaSilabas(int palIn[]){
int i=0, j=0;
bool fim=false;
int pal[120];
for(i=0; palIn[i]!='\0'; i++){
pal[i] = palIn[i];
}
pal[i]='\0';
i=0;
palIn[j++]=pal[i];
/*1*/if(vogal(pal[i]));
else{
i++;
/*2*/ if(pal[i]=='\0'){
fim = true;
}
else{
palIn[j++]=pal[i];
/*3*/
if(vogal(pal[i]));
else{
i++;
palIn[j++]=pal[i];
}
}
}
while(!fim){
/*4*/ if(pal[i]=='\0'){
break;
}
i++;
/*5*/ if(pal[i]=='\0'){
break;
}
else
/*6*/ if(pal[i+1]=='\0' && !(pal[i]>=AE && pal[i]<=OE))
{palIn[j++]=pal[i]; i++;}
else{
/*7*/
if(vogal(pal[i])){
/*8*/
if(tritongo(((i>1)?pal[i-2]:0),pal[i-1], pal[i],
pal[i+1], pal[i+2])){
/*9*/
if(!(pal[i-1]>=AE && pal[i-1]<=OE)){
palIn[j++]=pal[i];
i++;
}
palIn[j++]=pal[i];
}
else{
/*10*/
if(ditongo(((i>1)?pal[i-2]:0),pal[i-1],
pal[i], pal[i+1], pal[i+2],i)){
palIn[j++]=pal[i];
}
else{
palIn[j++]=Separador;
palIn[j++]=pal[i];
}
}
}
else{
i++;
/*11*/
if(pal[i]=='\0'){
palIn[j++]=pal[i-1];
break;
}
else{
/*12*/
if(vogal(pal[i])){
palIn[j++]=Separador;
palIn[j++]=pal[i-1];
palIn[j++]=pal[i];
}
else{
/*13*/
if(vogal(pal[i+1])){
palIn[j++]=pal[i-1];
palIn[j++]=Separador;
}
else{
if(vogal(pal[i+2])){
if(pal[i]=='s'){
palIn[j++]=pal[i-1];
palIn[j++]=pal[i];
palIn[j++]=Separador;
i++;
}
else{
palIn[j++]=pal[i-1];
palIn[j++]=Separador;
palIn[j++]=pal[i];
i++;
}
}
else{
palIn[j++]=pal[i-1];
palIn[j++]=pal[i];
if(pal[i+1]!='\0'){
palIn[j++]=Separador;
i++;
palIn[j++]=pal[i];
i++;
if(pal[i]=='\0')
break;
}
else
break;
}
}
palIn[j++]=pal[i];
i++;
palIn[j++]=pal[i];
/*14*/
/*15*/
/*16*/
/*17*/
}
}
}
}
}
palIn[j]='\0';
}
//esta função tem com finalidade guardar num ficheiro auxiliar a palavra
com a separação silabica efectuada
// e os simbulos que representam as letras maiusculas
void constroiPal(int palOrig[], int palIn[], FILE *fout){
int posPO, posPI;
for(posPO=0, posPI=0; palOrig[posPO]!='\0'; posPI++, posPO++){
if(palIn[posPI]==Separador)
fputc(palIn[posPI++], fout);
if(sinalMaiuscula(palOrig[posPO]))
fputc(palOrig[posPO++], fout);
fputc(palIn[posPI],fout);
}
num++;
}
//esta função faz a leitura de palavras a tratar pela função
'criaSilabas(...)'
void proc(){
int ch, pos=0, posPO=0;
int palIn[120], palOrig[120];
FILE *fin, *fout;
fopen_s(&fin,"PreProcessamento.txt", "r");
fopen_s(&fout,"PosProcessamento.txt", "w");
while((ch=fgetc(fin))!=EOF){
if(sinalMaiuscula(ch)){
palOrig[posPO++] = ch;
ch=fgetc(fin);
}
if(letra(ch)){
palOrig[posPO++] = ch;
palIn[pos++] = ch;
}
else{
if(pos){
palIn[pos]='\0';
palOrig[posPO] = '\0';
criaSilabas(palIn);
constroiPal(palOrig, palIn, fout);
pos=0;
posPO=0;
}
fputc(ch,fout);
}
}
fclose(fin);
fclose(fout);
}
//esta função grava no ficheiro final as palavras já divididas com o
aspecto que tinha no texto inicial
// efectua também a conversão dos caracteres especiais nos originais
void posProc(){
int ch1, ch2=0, maiuscula=0;
FILE *fin, *fout;
fopen_s(&fin,"PosProcessamento.txt", "r");
fopen_s(&fout,"Final.txt", "w");
while((ch1=fgetc(fin))!=EOF){
if(ch1>=Xx && ch1<=XX){
maiuscula=ch1;
ch1=fgetc(fin);
}
if((ch1>=BL && ch1<=OE)){
switch(ch1){
case BL: ch1='b';
case BR: ch1='b';
case CH: ch1='c';
case CL: ch1='c';
case CR: ch1='c';
case DR: ch1='d';
case FL: ch1='f';
case FR: ch1='f';
ch2='l';
ch2='r';
ch2='h';
ch2='l';
ch2='r';
ch2='r';
ch2='l';
ch2='r';
break;
break;
break;
break;
break;
break;
break;
break;
case
case
case
case
case
case
case
case
case
GL:
GR:
LH:
NH:
PL:
PR:
TL:
TR:
VR:
ch1='g';
ch1='g';
ch1='l';
ch1='n';
ch1='p';
ch1='p';
ch1='t';
ch1='t';
ch1='v';
ch2='l';
ch2='r';
ch2='h';
ch2='h';
ch2='l';
ch2='r';
ch2='l';
ch2='r';
ch2='r';
break;
break;
break;
break;
break;
break;
break;
break;
break;
case
case
case
case
case
case
GN:
MN:
PN:
PS:
PT:
TM:
ch1='g';
ch1='m';
ch1='p';
ch1='p';
ch1='p';
ch1='t';
ch2='n';
ch2='n';
ch2='n';
ch2='s';
ch2='t';
ch2='m';
break;
break;
break;
break;
break;
break;
case
case
case
case
AE:
AI:
AO:
OE:
ch1=a_t;
ch1=a_t;
ch1=a_t;
ch1=o_t;
ch2='e';
ch2='i';
ch2='o';
ch2='e';
break;
break;
break;
break;
}
}
if(maiuscula){
if(maiuscula == Xx)
ch1 -= 32;
if(maiuscula == xX)
ch2 -= 32;
if(maiuscula == XX){
ch1 -= 32;
ch2 -= 32;
}
maiuscula = 0;
}
fputc(ch1,fout);
if(ch2){
fputc(ch2,fout);
ch2 = 0;
}
}
fprintf_s(fout, "\n\n\n\"A separação silábica foi aplicada em: %d
palavra(s)\" ", num);
fclose(fin);
fclose(fout);
}
B Tabela de símbolos usada
Nota:
Foram usados os símbolos da tabela ascii estendida a partir do número 128 ao 255, para a
atribuição de constantes na realização do algoritmo.

Documentos relacionados