#########################################################################
#FLEMM-v2 -- French Lemmatizer : Lemmatisation du franais  partir de# 
#corpus tiquets - Version 2						#
#Copyright (C) 1999 (NAMER Fiammetta)					#
#########################################################################
# Module qui convertit l'entre en format interne,
# appelle le lemmatiseur et
# convertit le rsultat en format de TreeTagger


# $Id: entrees_sorties,v 2 1999/08/31 07:56:28 namer Exp $

use English;
use strict qw(vars refs subs);

# Pre-declaration de variables globales
use vars qw($directory);

require "$main::directory/lemmatizer";

package entrees_sortiesTT;

#use lib qw($ENV{BASE_LEM});


# ##########################################
# Mthodes de classe (utilises en externe)
############################################

sub new {
    my $type = shift;
    my ($path)=@_;
    
    my $self={};
    
    bless $self,$type;

    # Les objets de la classe entrees_sortiesTT contiennent un objet
    # de la classe lemmatizer. C'est precisment celui-l que 
    # l'on cre  l'instruction suivante.

    $self->{"lemmatizer"}=new lemmatizer($path);


    return $self;
}

sub identifie {
    my $self = shift;
    my($entree0, $filename) = @_;
    
    my($entree,$lex,$tag1,$tag, $lex_en_maj);

    my($debug0)=0;
    my($res)="";


    # Fichier rpertoriant les erreurs d'tiquetage

    if ($filename ne "") {
	open(OUT1,">>$filename.etiq") || die "$!";
	open(OUT2,">>$filename.seg") || die "$!";

	$debug0 = 1;
    }



    # Squence entre:
    $entree0 =~ /(.*)\/(.*)/;
    $lex=$1;
    $lex_en_maj=$1;
    $tag1=$2;


    # Transformation du mot en minuscules:
    $lex =~ tr/A-Z/a-z/;

    # 14 septembre : Suppression des signes de ponctuations 
    # en fin de mot, 

    if (($lex =~ /^([^\.\?!]+)(\.|!|\?|\(|,|\[|\|\|\-)+$/) && 
        ($tag1 !~ /ABR/) &&
        ($tag1 ne "NPR")) {
    	  $lex = $1;
    	  print OUT2 "$lex_en_maj  est rduit  $lex ($tag1) \n";
        }

    # et des virgules, parenthses, tirets au dbut
    if ($lex =~ /^[\*\),\?\-:;\\]+([^\*,\?\):;\\]+)$/) {
        $lex = $1;
        #print "Voici $lex\n";
    	  print OUT2 "$lex_en_maj  est rduit  $lex ($tag1) \n";
        }

    # Squence traite :
    $entree = $lex."/".$tag1;
 
    if ($entree =~ /ADJ$/) { 
	if ($entree =~ /(-t)-(je|tu|ils?|elles?|nous|vous|on)\//) {

	    $entree = $2;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	}
    else {
	$res =  $self->iliad($entree0,$self->stemm_adjectif($entree)); 
	}
    }


    
    # Concerne PRO

    elsif ($entree =~ /PRO:(poss|pers|indef|demo|clit)/) {

	if (($self->{"lemmatizer"}->est_un_pronom_personnel($lex)) ||
          ($self->{"lemmatizer"}->est_un_pronom_meme($lex)) ||
	    ($self->{"lemmatizer"}->est_un_pronom_invariable($lex))  ) {

	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	}

	elsif (($tag1 =~ /PRO/) &&
	       ($lex =~ /^[jtsclm][e\']$/)) {
	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	}

	elsif (($tag1 =~ /PRO/) &&
	       ($lex =~ /^(l'_on$|-t-|-ce|-il)/)) {
	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	}

	elsif ($tag1 =~ /PRO:(clitic|pers)/) {

	    # Premiere approximation : si PRV echoue, alors c'est un ADJ

	    $entree =~ s/(.*)\/(.*)/$1\/ADJ/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_adjectif($entree));
	}
	    
	# Concerne PRO

	elsif ($lex =~ /(ae|ashe|[0-9]|ante?|[oiay]que|[ai]ble|iche)s?$/) {
	    $entree =~ s/(.*)\/(.*)/$1\/ADJ/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_adjectif($entree));
	}

	# Concerne PRO

	elsif  (($lex =~ /(ose|ate)s?$/)&&($lex !~ /quelque_chose/)) {
	    $entree =~ s/(.*)\/(.*)/$1\/NOM/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_nom($entree));
	}

	elsif ($entree =~ /(-t)?-(je|tu|ils?|elles?|nous|vous|on)\//) {

	    $entree = $2;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	}

	# Concerne PRO

	else {
	    $res = $self->iliad($entree0,$self->stemm_pro($entree));
	} 
	    
    }


    elsif ($entree =~ /(DET|PRO:(inter|rela)|PRE:det)/) {

	if (($self->{"lemmatizer"}->est_un_determinant_ou_une_relative_invariable($lex)) ||
	    ($lex =~ /(quel|^une?$|^des$|^les?$|^la$|^[ld]'$|^aux?$|^du$|^ce|^[mts](ien(ne)?s?|on|a|es)$|^[nv](os|otre)$|^leurs?|^tel|^nul|^tou|^certain|^aucun)/)) {

	    $res = $self->iliad($entree0,$self->stemm_detrel($entree));
	}
	
	elsif ($lex =~ /_de$/) {
	    $entree =~ s/(.*)\/(.*)/$1\/PRE/;
	    $entree0 =~ s/(.*)\/(.*)/$1\/PRE/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;


	    $res = $self->iliad($entree0,$entree);
	}

	else {
	    $entree =~ s/(.*)\/(.*)/$1\/NOM/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    
	    $res = $self->iliad($entree0,$self->stemm_nom($entree));
	}
	    
    }



    elsif ($entree =~ /VER(:aux)?:ppre/) {

	if ($entree =~ /ant\//) {
	    $res = $self->iliad($entree0,$self->stemm_ppres($entree));
	}
	else {
	    $entree =~ s/(.*)\/(.*)/$1\/ADJ/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;
	    
	    $res = $self->iliad($entree0,$self->stemm_adjectif($entree));
	}
    }
    
    elsif  ($entree =~ /NOM/) {

	    $res = $self->iliad($entree0,$self->stemm_nom($entree));
	
    }

    elsif ($entree =~ /VER:aux:pper/) {
	$res = $self->iliad($entree0,$self->stemm_ppasts($entree));
    }

    # Tester les terminaisons potentielles des participes passs
    elsif ($entree =~ /VER:pper/)  {

	if (($entree =~ /^(ha|ou)(e|es|s)?\//) ||
	    ($entree =~ /^mort(e|es|s)?\//) ||
	    ($entree =~ /(sous|soutes?)\//) ||
	    ($entree =~ /(clos|[^a]is|clus)(e|es)?\//) ||
	    ($entree =~ /(|[^oa]i|[^aq]u||[vf]ert|[aeo]int|(f|tr)ait|(d|cr|f|fr|c|cu|du|lu|nu|ru)it)(e|es|s)?\//)) {
	    $res = $self->iliad($entree0,$self->stemm_ppasts($entree));
	}
	else {
	    $entree =~ s/(.*)\/(.*)/$1\/ADJ/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;
	    
	    $res = $self->iliad($entree0,$self->stemm_adjectif($entree));
	}
    }

    # Tester les terminaisons potentielles des verbes a l'infinitif

    elsif ($entree =~ /VER(:aux)?:infi/)  {

	if (($entree =~ /cl[ou]re\//) ||
	    ($entree =~ /[e]r\//) ||
	    ($entree =~ /[^aeiy]ir\//) ||
	    ($entree =~ /[^aefghjklmnoqsuwxyz]re\//) ) {
	    $res = $self->iliad($entree0,$entree);
	}
	else {
	    $entree =~ s/(.*)\/(.*)/$1\/NOM/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    $res = $self->iliad($entree0,$self->stemm_nom($entree));
	}
    }

    elsif ($entree =~ /VER:aux/) {
	$res = $self->iliad($entree0,$self->stemm_verbe($entree));
    }

    # Tester les terminaisons potentielles des verbes
    elsif ($entree =~ /VER/) {

	if (($entree =~ /^(est|s?ont|vont|fut|eut)\//) ||
	    ($entree =~ /^(contre)?fou[st]\//) ||
	    ($entree =~ /^(ou|ha)[st]\//) ||
	    ($entree =~ /^meur[st]\//) ||
	    ($entree =~ /^(con)?vaincs?\//) ||
	    ($entree =~ /[rf]ont\//) ||
	    ($entree =~ /(a|ai|as|t)\//) ||	    
	    ($entree =~ /clo[st]\//) ||
	    ($entree =~ /(e|es|is|it|ons|ez)\//) ||
	    ($entree =~ /[cm]ouds?\//) ||
	    ($entree =~ /[bs]sou[st]\//) ||
	    ($entree =~ /[^aefgijkquwxyzo][u][st]\//) ||
	    # 14 septembre
	    ($entree =~ /(en|par|er|[im]eu|[sd]or|cour|[veaot]in)[st]\//) ||
	    ($entree =~ /([eao]nd|[oe]rd|rompt|sied|vt|[bm][ae]t)s?\//) ||
	    ($entree =~ /[fvpl][ea]u[xt]\//) ||
	    ($entree =~ /(pla|na|para|pa|cro)t\//)) {

	    if ($entree =~ /(gi|ou|[^g]e|a|au)(a|ai|as|t)\//) {
		$entree =~ s/(.*)\/(.*)/$1\/NOM/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    
		$res = $self->iliad($entree0,$self->stemm_nom($entree));
	    }
	    else {
		$res = $self->iliad($entree0,$self->stemm_verbe($entree));
	    }

	}
	else {
	    $entree =~ s/(.*)\/(.*)/$1\/NOM/;
	    print OUT1 "$lex_en_maj / $tag1 ==>  $entree\n" if $debug0;

	    
	    $res = $self->iliad($entree0,$self->stemm_nom($entree));
	}
	
    }
    
    else  {
	$res = $self->iliad($entree0,$entree);
    }
	
    close(OUT1);
    close(OUT2);


    return $res;
}		 

#######################################################
sub stemm_detrel {
    my $self=shift;

    my($a) = @_;
    
    my($lex,$b,$cat);
    
    my($res)="";
    
    $a=~ /^(.*)\/(DET:.*|PRO:(inter|rela)|PRE:det)$/;
    
    $lex=$1;
    $cat = $2;
    
    $b= $self->{"lemmatizer"}->lemme_detrel($lex,$cat);

    $res = $cat." ".$lex." / ".$b;

        #print "RES DE DET = $res\n";

    return $res;
}


sub stemm_pro {
    my $self = shift;
    my($a) = @_;
    
    my($lex,$etiq,$b);
    
    my($res)="";
    
    $a=~ /^(.*)\/(PRO.*)/;
    
    $lex=$1;
    $etiq=$2;

    $b= $self->{"lemmatizer"}->lemme_pro($lex);

    $res = $etiq." ".$lex." / ".$b;
    return $res;
}


sub stemm_adjectif {
    my $self=shift;
    my($a) = @_;
    
    my($lex,$b);
    
    my($res) = "";
    
    $a=~ /^(.*)\/ADJ$/;
    
    $lex=$1;

    $b= $self->{"lemmatizer"}->lemme_adj($lex);

    $res = "ADJ ".$lex." / ".$b;
    return $res;
}

sub stemm_ppres {
    my $self=shift;

    my($a) = @_;
    
    my($lex,$cat,$b);
    
    my($res) = "";
    
    $a=~ /^(.*)\/(VER(:aux)?:ppre)$/;
    
    $lex=$1;
    $cat=$2;

    $b= $self->{"lemmatizer"}->lemme_ppres($lex);

    $res = $cat." ".$lex." / ".$b;
    return $res;
}

sub stemm_ppasts {
    my $self=shift;

    my($a) = @_;
    
    my($lex,$cat,$b);

    my($res)="";

    $a=~ /^(.*)\/(VER(:aux)?:pper)$/;

    $lex=$1;
    $cat=$2;

    $b= $self->{"lemmatizer"}->lemme_ppast($lex);

    $res = $cat." ".$lex." / ".$b;
    return $res;
}

sub stemm_nom {
    my $self=shift;

    my($a) = @_;

    my($lex,$b);

    my($res) = "";

    $a=~ /^(.*)\/NOM$/;


    $lex=$1;

    $b= $self->{"lemmatizer"}->lemme_nom($lex);
    $res = "NOM ".$lex." / ".$b;
    return $res;
}


sub stemm_verbe {
    my $self=shift;

    my($a) = @_;

    my($lex,$cat,$b);

    my($res) = "";

    $a=~ /^(.*)\/(VER(:aux)?:(subp|simp|pres|impf|futu|cond|subi))$/;

    $lex=$1;
    $cat=$2;

    $b= $self->{"lemmatizer"}->lemme_verbe($lex);

    $res = $cat." ".$lex." / ".$b;
	
    return $res;
    
}

sub iliad {
    my $self=shift;
    my($entree0,$entree)= @_;

    my($etiq,$lex,$lex0,$lem,$deb,$reste, $reste0);

    my($res);



    $entree0 =~ /(.*)\/(.*)$/;
    $lex0 = $1;
    $reste0 = $2;

        
    if ($entree =~ /.*[^e]'\/(ADV|PRE|CON:sub)/) {
	$entree =~ s/'/e/;
    }
    
    # Par dfaut le lemmatiseur produit une
    # analyse non dterministe pour "taient 
    # (tre/tayer)". Correction par rapport 
    # Brill o la catgorie est diffrente.

    if ($entree =~ /^VER:aux:impf taient/) {
	$entree = "VER:aux:impf taient / tre, 3ppIMP, (3e groupe)";
    }
    
    if  (($entree !~ /^ADJ /) &&
	   ($entree !~ /:pper /) &&
	   ($entree !~ /:cond /) &&
	   ($entree !~ /:pres /) &&
	   ($entree !~ /:futu /) &&
	   ($entree !~ /:impf /) &&
	   ($entree !~ /:simp /) &&
	   ($entree !~ /:subp /) &&
	   ($entree !~ /:subi /) &&
	   ($entree !~ /^DET/) &&
	   ($entree !~ /^PRE:det/) &&
	   ($entree !~ /^PRO/) &&
	   ($entree !~ /^NOM /) &&
	   ($entree !~ /:ppre /))  {
	
	$entree =~ /(.*)\/(.*)$/;
	$lex = $1;
	if ($entree =~ /NPR/) {
		$res = $lex0."/".$reste0."/".$lex0;
		}
	else {
		$res  = $lex0."/".$reste0."/".$lex;
		}
    }
    
    # On remplace les squences de blancs par une virgule 
    # (sauf mots composs avec "'")
    
    else {
	$entree =~ /^([^ ]*) (.*) \/ (.*)$/;
	$etiq = $1;
	$lex = $2;
	$lem=$3;
	
	# Si le mot contient des blanc, en tenir compte
	
	if (($lex =~ / /) && ($etiq =~ /VER/)) {
	    $lem =~ /^([^ ]*) ([^ ]*)([ ,])(.*)$/;
	    $deb = $1." ".$2;
	    $reste = $3.$4;
	    $reste =~ s/ /,/g;
	    $lem = $deb.$reste;
	}
	elsif ($lex !~ / /) {
	    
	    # on uniformise les sparateurs
	    $lem =~ s/ /,/g;
	}
	
	$lem =~ s/,,+/,/g;
	
	# On distingue les lignes contenant " ou ":
	if ($lem =~ /,ou,/) {
	    
	    $res = $self->distribue_ou($lex0,$lem,$lex,$etiq);
	    
	}	
	
	# traitement de notation proprement dit
	else {
	    $lem =~ s/,/:/g;

          #if ($etiq =~ /(DET|rela|inter|det)/) {print "\n ETIQ = $etiq\nLEM = $lem\n";}

	    $res = $self->decompose($etiq,$lem);
          # Reformatage de l'tiquette

          if ($etiq =~ /^([A-Z][A-Z][A-Z]):([^ ]*)$/) {
              $etiq = $1."(".$2.")";
              }

	    $res = $lex0."/".$etiq.":".$res;

	    if ($res =~ /^(.*)XXX\/(.*)$/) {

		$res = $1."XXX/".$lex0;
	    }
	}
    }
	
    return $res;
}

sub distribue_ou {
    my $self=shift;
    my($lex0,$seq,$lex,$etiq) = @_;

    my($forme_mot1,$groupe1,$flex1,$forme_mot2,$groupe2,$flex2);

    my($res)="";

    if ($etiq =~ /ppre/) {
	$seq =~ /^([^,]*),(\([^\)]*\)),ou,([^,]*):(..):(\([^\)]*\)),?$/;
	$forme_mot1 = $1;
	$flex1 = $4;
	$groupe1 = $2;
	$forme_mot2 = $3;
	$flex2 = $flex1;
	$groupe2 = $5;
	
	$res = "{".$lex0."/".$etiq.":".$self->decompose($etiq,$forme_mot1.":".$flex1.":".$groupe1);
	$res .= "|";
	$res .= $lex0."/".$etiq.":". $self->decompose($etiq, $forme_mot2.":".$flex2.":".$groupe2)."}";
	
    }
    
    elsif ($etiq =~ /VER(:aux)?:(cond|futu|impf|pres|simp|sub[ip])/) {
	if ($seq =~ /^([^,]*),([1-3][^,\( ]*),(\([^\)]*\)),ou,([^,]*),([1-3][^,\( ]*),(\([^\)]*\)),?$/) {
	    
	    $forme_mot1 = $1;
	    $flex1 = $2;
	    $groupe1 = $3;
	    $forme_mot2 = $4;
	    $flex2 = $5;
	    $groupe2 = $6;
	}
	elsif  ($seq =~ /^([^,]*),(\([^\)]*\)),ou,([^,]*),(\([^\)]*\)),([1-3][^,]*),?$/) {
	    $forme_mot1 = $1;
	    $flex1 = $5;
	    $groupe1 = $2;
	    $forme_mot2 = $3;
	    $flex2 = $flex1;
	    $groupe2 = $4;
	}
	elsif  ($seq =~ /^([^,]*),([1-3][^, ]*),ou,([^,]*),([1-3][^,\( ]*),(\([^\)]*\)),?$/) {
	    $forme_mot1 = $1;
	    $flex1 = $2;
	    $groupe1 = $5;
	    $forme_mot2 = $3;
	    $flex2 = $4;
	    $groupe2 = $groupe1;
	}
	elsif  ($seq =~ /^([^ ]*),ou,([^,]*),([1-3][^, ]*),(\([^\)]*\)),?$/) {
	    $forme_mot1 = $1;
	    $flex1 = $3;
	    $groupe1 = $4;
	    $forme_mot2 = $2;
	    $flex2 = $flex1;
	    $groupe2 = $groupe1;
	}
	
	else {
	    #print "Notation de base incorrecte, verbe $lex\n";
	}
	
	$res = "{".$lex0."/".$etiq.":".$self->decompose($etiq,$forme_mot1.":".$flex1.":".$groupe1);
	$res .= "|";
	$res .= $lex0."/".$etiq.":". $self->decompose($etiq, $forme_mot2.":".$flex2.":".$groupe2)."}";
	
    }
    else {
	#Extention aux noms/adjectifs
	if  ($seq =~ /^([^,:]*):([mf_])([sp_])[:,]ou[:,]([^,:]*)[,:]([mf_])([sp_])[:,]?$/) {
	    $forme_mot1 = $1;
	    $flex1 = $2.$3;
	    $forme_mot2 = $4;
	    $flex2 = $5.$6;
	}
	elsif  ($seq =~ /^([^,:]*)[:,]ou[:,]([^,:]*):([mf_])([sp_])[:,]?$/) {
	    $forme_mot1 = $1;
	    $flex1 = $3.$4;
	    $forme_mot2 = $2;
	    $flex2 = $flex1;
	}
	
	else {
	    #print "Notation de base incorrecte, nom $lex\n";
	}
	
	$res = "{".$lex0."/".$etiq.":".$self->decompose($etiq,$forme_mot1.":".$flex1);
	$res .= "|";
	$res .= $lex0."/".$etiq.":". $self->decompose($etiq,$forme_mot2.":".$flex2)."}";
	
    }
    
    return $res;
}

# Affiche le mot lemmatise selon les conventions suivantes:
#
# pour les verbes conjugues (VER(:aux)?:(cond|futu|impf|pres|simp|sub[ip])) :
# MotFlechi/Etiq:pers:nb:tps:mode/LemmeCalcule:gpe:FamilleFlex/
#
# pour les participes passs, les adjectifs, les noms, les determinants et 
# les pronoms relatifs (pper, ADJ, NOM, DET, PRE:det et PRE:rela) :
# MotFlechi/Etiq:genre:nb/LemmeCalcule:FamilleFlex/
#
# pour les participes prsents(ppre) :
# MotFlechi/Etiq:_:_/LemmeCalcule:FamilleFlex/

# Pour les pronoms (PRO:(poss|pers|indef|demo|clit))
# MotFlechi/Etiq:pers:genre:nb:cas/LemmeCalcule:FamilleFlex/
#
# Valeurs possibles :
#
# pers : 1p,2p,3p,_
# genre : m,f,_
# nb : s,p,_
# tps : pst,impft,fut, ps
# mode : ind,subj,imp,cond,imper
# gpe : 1g,2g,3g
# FamilleFlex : _
#
# Pour chacune de ses realisations, les resultats ambigus 
# sont entre separes par '|' et places entre {}. La catgorie de TreeTagger
# est restitue avec l'intgralit de ses informations; celles-ci sont 
# reformates (mises entre parenthses) pour viter de les confondre avec 
# les traits qui suivent:
#
# ex1 :  {bruissant/VER(ppre):_:_/bruisser:1g/|bruissant/PPRES:_:_/bruire:3g/}
#
# ex2 : allions/VER(impf):1p:{impft:ind|pst:subj}/aller:3g/
#

sub decompose {
    my $self=shift;
    my($etiq, $seq) =@_;

    my(@tab);
    my($flex,$gd,$nb,$modele,$tps,$cas);
    my($per)="";
    my($res)="";
    my($famille_flex) =":_";


    @tab = split(':',$seq);

    # Calcul de la famille flexionnelle 
    # $famille_flex = $self->calcule_modele_flex($etiq, $tab[0]);

    $flex = $tab[1];

    # Les pronoms :

    if ($flex =~ /^([123_])([mf_])([sp_])([_naodMRSTU])$/) {

	$per=$1;
	$gd=$2;
	$nb=$3;

	$res = $per."p:".$gd.":".$nb.":";
	$cas = $4;
	if ($cas =~ /[_naod]/) {
	    $res .= $cas."/";
	}
	elsif ($cas =~ /M/) {
	    $res .= "{n|d|o}/";
	}
	elsif ($cas =~ /U/) {
	    $res .= "{a|d|o}/";
	}
	elsif ($cas =~ /R/) {
	    $res .= "{a|d}/";
	}
	elsif ($cas =~ /S/) {
	    $res .= "{a|o}/";
	}
	else {
	    # cas = T = d/o
	    $res .= "{d|o}/";
	}
    }

    # Dterminants, adjectifs, noms, participes passs

    elsif ($flex =~ /^([mf_])([sp_])$/) {
	$gd=$1;
	$nb=$2;
	
	$res = $gd.":".$nb."/";
    }

    elsif ($flex =~ /^([sp_])$/) {
	$nb=$1;
	$res = "_:".$1."/";
    }

    # Verbes conjugus :
    elsif ($flex =~ /^([1-3])\/?([1-3]?).(.)(.*)$/) {
	$res = $1;
	$per = $2;
	$nb = $3;

	$tps = $4;
	if ($per ne "") {
	    $res = "{".$res."|".$per."}";
	}
	$res .= "p:".$nb.":";

	if ($tps =~ /^(IMP\/PSTSUBJ|PSTSUBJ\/IMP)$/) {
	    $res .="{impft:ind|pst:subj}/";
	}
	elsif ($tps =~ /^(PSTIND\/SUBJ\/IMPER)$/) {
	    $res ="{".$res."pst:{ind|subj}|2p:s:pst:imper}/";
	}
	elsif ($tps =~ /^(PSTIND\/IMPER)$/) {
	    if ($flex =~ /ps/) {
		$res ="{".$res."pst:ind|2p:s:pst:imper}/";
	    }
	    else {
		$res .= "pst:{ind|imper}/";
	    }
	}
	elsif ($tps =~ /^(PSTSUBJ\/IMPER)$/) {
	    if ($flex =~ /ps/) {
		$res ="{".$res."pst:subj|2p:s:pst:imper}/";
	    }
	    else {
		$res .= "pst:{subj|imper}/";
	    }
	}
	elsif ($tps =~ /^(IMPER)$/) {
	    if ($flex =~ /ps/) {
		$res ="2p:s:pst:imper/";
	    }
	    else {
		$res .= "pst:imper/";
	    }
	}
	elsif ($tps =~ /^PST(_|IND\/SUBJ)?$/) {
	    $res .="pst:{ind|subj}/";
	}
	elsif ($tps =~ /^PS\/PSTIND$/) {
	    $res .="{pst|ps}:ind/";
	}
	elsif ($tps =~ /^PSTIND\/PS\/IMPER$/) {
	    $res ="{".$res."{pst|ps}:ind|2p:s:pst:imper}/";
	}
	elsif ($tps =~ /^PSTIND$/) {
	    $res .="pst:ind/";
	}
	elsif ($tps =~ /^PSTSUBJ$/) {
	    $res .="pst:subj/";
	}
	elsif ($tps =~ /^SUBJIMP$/) {
	    $res .="impft:subj/";
	}
	elsif ($tps =~ /^PS$/) {
	    $res .="ps:ind/";
	}
	elsif ($tps =~ /^IMP$/) {
	    $res .="impft:ind/";
	}
	elsif ($tps =~ /^FUT$/) {
	    $res .="fut:ind/";
	}
	elsif ($tps =~ /^COND$/) {
	    $res .="pst:cond/";
	}
	else {
	    $res .="xxx:xxx/";
	}
    }
    else {
	$res = "XXX/";

    }
    $res .= $tab[0];
    if (defined($tab[2])) {

	$modele = $tab[2];
	$modele =~ /^\(([1-3])/;
	$res .= ":".$1."g";
    }
    #$res .= $famille_flex."/";
   
    return $res;
}

1;

