/* -------------------------------------------------------- LIA_PHON : Un systeme complet de phonetisation de textes -------------------------------------------------------- Copyright (C) 2001 FREDERIC BECHET .................................................................. This file is part of LIA_PHON LIA_PHON is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA .................................................................. For any publication related to scientific work using LIA_PHON, the following reference paper must be mentioned in the bibliography: Bechet F., 2001, "LIA_PHON - Un systeme complet de phonetisation de textes", revue Traitement Automatique des Langues (T.A.L.) volume 42, numero 1/2001, edition Hermes .................................................................. Contact : FREDERIC BECHET - LIA - UNIVERSITE D'AVIGNON AGROPARC BP1228 84911 AVIGNON CEDEX 09 FRANCE frederic.bechet@lia.univ-avignon.fr .................................................................. */ /* Decoupe un texte tokenise par DecoupeMots en phrases en accord avec un certain nombre d'heuristiques Les separateurs de phrases sont : : debut de phrase : fin de phrase Entree : stdin Sortie : stdout */ /* FRED 0199 */ #include #include #include #include #include #define TailleLigne 8000 /* Gestion de la liste de mots necessitant de ne pas considere le '.' comme separateur */ char CharSeparateur; char TablSeparateur[]= { '.', '!', '?', /* separateur 'classique' de fin de phrase */ '\0' }; int SiSeparateur(c) char c; { static int n; for(n=0;TablSeparateur[n];n++) if (c==TablSeparateur[n]) return 1; return 0; } int MotSeparateur(ch) char *ch; { if ((ch[1]=='\0')&&(SiSeparateur(ch[0]))) return 1; if (!strcmp(ch,"...")) return 1; return 0; } #define SiMajuscule(a) ((((a)>='A')&&((a)<='Z'))?1:0) #define SiChiffre(a) ((((a)>='0')&&((a)<='9'))?1:0) #define SiUnite(a) ((((a)=='%')||((a)=='$')||((a)=='F')||((a)==',')||((a)=='.'))?1:0) #define SiDebutBloc(a) ((((a)=='[')||((a)=='(')||((a)=='"'))?1:0) #define SiFinBloc(a) ((((a)==']')||((a)==')')||((a)=='"'))?1:0) int DebutParagraphe(c) char c; { if ((c=='-')||(c=='*')||(c=='(')||(c=='[')) return 1; return 0; } /* Definition de la fenetre d'examen */ /* On regarde 5 mots avant et 5 mots apres */ #define TailleFenetre 11 #define SpotFenetre 5 #define TailleMot 200 char *Fenetre[TailleFenetre]; char Phrase[TailleFenetre][TailleMot]; /* Heuristiques sur la fin de phrase */ int CaraDebutPossible(ch) char *ch; { /* un cara est un debut possible s'il commence : * par une majuscule * par un chiffre * par un caractere debut_paragraphe */ if (SiMajuscule(*ch)) return 1; if (SiChiffre(*ch)) return 1; if (DebutParagraphe(*ch)) return 1; return 0; } int JustDigit(ch) char *ch; { int n; for(n=0;ch[n];n++) if (!SiChiffre(ch[n])) return 0; return 1; } int MotDebutPossible(ch) char *ch; { /* un mot est un debut possible s'il est compose : * une majuscule suivie de minuscule * un nombre * par un caractere debut_paragraphe */ int n; if (SiMajuscule(*ch)) { for(n=1;(ch[n])&&(!(SiMajuscule(ch[n])));n++); if (ch[n]=='\0') return 1; } if (SiChiffre(*ch)) { for(n=1;(ch[n])&&(SiChiffre(ch[n])||(SiUnite(ch[n])));n++); if (ch[n]=='\0') return 1; } if (DebutParagraphe(*ch)) return 1; return 0; } int TraiteFinPhrase() { /* si on a [. \n \n ou plus] alors fin_phrase */ if ((Fenetre[SpotFenetre+1][0]=='\n') && (Fenetre[SpotFenetre+1][1]>=2)) strcat(Fenetre[SpotFenetre],"\n\n\n"); /* si on a [. \n cara_debu_possible] alors fin_phrase */ if ((Fenetre[SpotFenetre+1][0]=='\n') && (CaraDebutPossible(Fenetre[SpotFenetre+2]))) strcat(Fenetre[SpotFenetre],"\n\n\n"); /* si on a [chif . chif quantificateur alors pas de fin de phrase */ if ((JustDigit(Fenetre[SpotFenetre-1]))&&(JustDigit(Fenetre[SpotFenetre+1])) && (JustPresent(Fenetre[SpotFenetre+2]))) return 0; /* si on a [. mot_debut_possible] alors fin_phrase */ if (MotDebutPossible(Fenetre[SpotFenetre+1])) strcat(Fenetre[SpotFenetre],"\n\n\n"); /* si on a [. fin_bloc \n cara_debu_possible] alors fin_phrase */ if ((SiFinBloc(Fenetre[SpotFenetre+1][0])) && (Fenetre[SpotFenetre+2][0]=='\n') && (CaraDebutPossible(Fenetre[SpotFenetre+3]))) strcat(Fenetre[SpotFenetre+1],"\n\n\n"); /* si on a [. fin_bloc/debut_bloc mot_debut_possible] alors fin_phrase */ if (((SiDebutBloc(Fenetre[SpotFenetre+1][0]))||(SiFinBloc(Fenetre[SpotFenetre+1][0]))) && (MotDebutPossible(Fenetre[SpotFenetre+2]))) strcat(Fenetre[SpotFenetre+1],"\n\n\n"); /* si on a [. \n debut_bloc cara_debu_possible] alors fin_phrase */ if ((SiDebutBloc(Fenetre[SpotFenetre+2][0])) && (Fenetre[SpotFenetre+1][0]=='\n') && (CaraDebutPossible(Fenetre[SpotFenetre+3]))) strcat(Fenetre[SpotFenetre],"\n\n\n"); return 1; } void TraiteLigne(ch) char *ch; { static int i_phrase=TailleFenetre,taille=0,last_saut=-1,just_open=1; int i,n,l; char *pt; for(pt=strtok(ch," \t");pt;pt=strtok(NULL," \t")) { i_phrase=i_phrase%TailleFenetre; for(i=0;i0) { Phrase[i_phrase][n]='\0'; last_saut=-1; } else { if (last_saut==-1) { Phrase[i_phrase][0]='\n'; Phrase[i_phrase][1]='\1'; Phrase[i_phrase][2]='\0'; last_saut=i_phrase; /*fprintf(stderr,"premier saut\n");*/ } else /* on incremente le compteur */ { Phrase[last_saut][1]++; Phrase[i_phrase][0]='\0'; /*fprintf(stderr,"\t saut num : %d\n",Phrase[last_saut][1]);*/ } } else { Phrase[i_phrase][n]='\0'; last_saut=-1; } i_phrase++; if (MotSeparateur(Fenetre[SpotFenetre])) TraiteFinPhrase(); if ((Fenetre[SpotFenetre][0])&&(Fenetre[SpotFenetre][0]!='\n')) { printf("%s",Fenetre[SpotFenetre]); l=strlen(Fenetre[SpotFenetre]); /* si les 4 derniers caracteres affiche sont : \n alors, just_open=1, pour eviter les lignes vides */ if (!strncmp(&(Fenetre[SpotFenetre][l-4]),"\n",4)) just_open=1; else just_open=0; if (Fenetre[SpotFenetre][l-1]=='\n') taille=0; else { taille+=l; if (taille>54) { printf("\n"); taille=0; } else printf("%c",CharSeparateur); } } else if (Fenetre[SpotFenetre][0]=='\n') { /*fprintf(stderr,"saut de lignes consecutifs = %d\n",Fenetre[SpotFenetre][1]);*/ if ((just_open==0) && (Fenetre[SpotFenetre][1]>=3)) /* on insere une fin de phrase si on ne vient pas d'ouvrir une ligne */ printf("\n\n\n"); } } } int main(argc,argv) int argc; char **argv; { char ch[TailleLigne]; int i; CharSeparateur=' '; /* par defaut, phrase formatees en paragraphe ATTENTION : si on utilise lia_nett_capital il FAUT que les phrases soient codees en paragraphe et non pas 1 mot par ligne !!!! */ if (argc>1) { if (!strcmp(argv[1],"-h")) { fprintf(stderr,"Syntaxe : %s [-h] [-l] < stdin > stdout\n\ \t Decoupe un texte en phrases tokenise (par exemple par la\n\ \t commande 'lia_token') en accord avec un certain nombre\n\ \t d'heuristiques codes dans la fonction 'TraiteFinPhrase'.\n\ \t Les separateurs de phrases sont : '' = debut de phrase\n\ \t et '' = fin de phrase.\n\ \t Le fichier contient un lexique\n\ \t compile avec la commande 'lia_compile_lexitree'. Ce lexique contient\n\ \t tous les mots 'M' tel que, une expression de la forme :\n\ \t ' . M' ne sera pas decoupee en phrase \n\ \t L'option -l permet d'obtenir un mot par ligne, sinon les phrases\n\ \t sont formatees en paragraphes - ATTENTION : lia_nett_capital n'accepte\n\ \t que les phrases structurees en paragraphe, donc SANS l'option -l\n\ \t Merci de votre comprehension !!!!\n",argv[0]); exit(0); } if ((argc>2)&&(!strcmp(argv[2],"-l"))) CharSeparateur='\n'; } else { fprintf(stderr,"Syntaxe : %s [-h] [-l] < stdin > stdout\n",argv[0]); exit(0); } ChargeLexiqueCompile(argv[1]); /* Initialisation de la phrase */ for(i=0;i\n"); while(fgets(ch,TailleLigne,stdin)) TraiteLigne(ch); /* On vide la phrase */ strcpy(ch,"\n"); for(i=0;i<=SpotFenetre;i++) TraiteLigne(ch); /* dernier tag de fin de phrase */ printf("\n"); exit(0); }