#/usr/bin/perl
#--------------------------------------------------------------------------------------------
# --- BAO 3 --- Version: RegEx --------------------------------------------------------------
#--------------------------------------------------------------------------------------------
# Entrée: Le programme construit en entrée:
#			-- Un texte étiqueté et lemmatisé par Talismane + un fichier de patrons syntaxiques 
#			   avec un patron par ligne (ex: NC ADJ).
# Sortie: Le programme construit en sortie:
#			Un fichier avec pour chaque patron sa liste de termes triés par fréquence
# Mode de lancement:
# 		perl5.28.1.exe perl_version_regex.pl FICHIER_TALISMANE.txt FICHIER_PATRONS.txt 
#--------------------------------------------------------------------------------------------
 
# On met explicitement utf8 comme encodage, de façon à qu'on s'assure que la sortie soit écrite en UTF-8:
use utf8;

# On appelle module perl qui gére le temps qui nous aide à afficher le temps de début et fin de traitement:
use Time::HiRes qw(gettimeofday tv_interval);
my $timepg = [gettimeofday];

# On sauvegarde dans une variable le fichier Talismane passé comme argument au programme sur indice 0(premier):
my $filetalismane=$ARGV[0];
# On sauvegarde dans une variable le fichier des patrons passé comme argument au programme sur indice 1(deuxième):
my $filetermino=$ARGV[1];

# On ouvre ces fichiers avec encodage utf8 et on les met dans les variables réspectives:
open my $fileT,"<:encoding(UTF-8)",$filetalismane;
open my $fileTer,"<:encoding(UTF-8)",$filetermino;

# On convertit le contenu du fichier des patrons dans un liste pour faire les recherches:
my @TERMINO=<$fileTer>,

# Fermeture du fichier des patrons:
close $fileTer;

# Initialisation du diccionaire temporaire:
my %dicotmp=();

# Initialisation du diccionaire de patrons:
my %dicoPatron=();

# On initialise un compteur ppur le nombre de termes repérés:
my $nbTerme=0;

# On comptabilise le nombre de mots dans une phrase:
my $nbMotInPhrase=0;

# Lecture du fichier ligne à ligne: 
while (my $ligne=<$fileT>) {
	# En utilisant des expressions régulières, on saute de ligne si elle contient les caractères suivants: £, #, $
	next if (($ligne=~/^1\t££/) or ($ligne=~/^\#\#/) or ($ligne=~/^$/));
	
	# Grâce à la boucle conditionelle, si la ligne actuelle ne contient pas '§', alors on prend le caractère digital (numéro) suivi par la tabulation et plusieurs caractères alphanumériques qui suivent après:
	if ($ligne!~/^\d+\t§/) {
		$ligne=~/^\d+\t(.+)$/;
		# Ce qui reste:
		my $reste=$1;
		# On augmente le compteur de nombre de mots dans la phase:
		$nbMotInPhrase++;
		# Clé qui va servir pour que le diccionaire obtienne cette valeur du compteur:
		my $cle=$nbMotInPhrase;
		# Le reste on va diviser avec la tabulation:
		my @listereste=split(/\t/,$reste);
		# On le met dans le diccionaire temporaire (la clé, c'est le nombre de mots, la reste, c'est le patron).
		$dicotmp{$cle}=\@listereste;
	}
	# Si ce n'est pas le cas, on fait l'extraction:
	else {
		#------------------------
		# Extraction termino....
		# Initialisation d'une chaîne de caractères vide. 
		my $phrase=" ";
		# On initialise un variable qui reprend les clés de diccionaire temporaire(nb de mots)
		my $longueur = scalar (keys %dicotmp);
		# À l'aide d'une boucle for on va dire qu'une variable i est égal à 1, et chaque fois que le compteur de longueur est moins ou égal à i, on incrémente i.
		for (my $i=1;$i<=$longueur;$i++) {
			# On met i comme clé du diccionaire temporaire et on le saugarde dans une liste:
			my $LISTE=$dicotmp{$i};
			# On convertit cette variable dans un vrai objet liste:
			my @listedeferencee = @$LISTE;
			# Dans cette liste on associe à la variable mot les tokens (qui sont les éléments de chaque ligne avec indice 0, et ces POS tags qui sont sous l'indice 2 à variable POS).
			my $mot = $listedeferencee[0];
			my $pos = $listedeferencee[2];
			# Dans $phrase on met tous les tokens et parties du discours réspectives:
			$phrase = $phrase . $mot . "/" . $pos . " ";
		}
		# Avec une boucle foreach on prend nos patrons et liste de patrons du ficher termino:
		foreach my $patron (@TERMINO) {
			# Pour ne pas perdre la variable patron on fait une recopie ($patron2):
			my $patron2 = $patron;
			# On chompe chaque ligne:
			chomp($patron2);
			$patron2=~s/([^ ]+)/\[\^ \]\+\/\\b$1/g;
			# Lorsque la phrase commence par les patrons de termino...
			while ($phrase=~/(?=\s($patron2))/g) { 
				# On prend le terme et le patron et on les met dans le diccionaire comme clé et valeur:
				my $terme=$1;
				$terme=~s/\/[^ ]+//g;
				$dicoPatron{$patron}->{$terme}++;
				# On incrémente le compteur de nombre de termes:
				$nbTerme++;
			}
		}
		# On vide le diccionnaire temporel:
		%dicotmp=();
		# Et on arrête le compteur:
		$nbMotInPhrase=0;
	}
}
# Fermeture du fichier Talismane:
close($fileT);

# On ouvre un fichier de sortie, avec encodage utf8:
open my $fileResu,">:encoding(UTF-8)","BAO3-TALISMANE-PERL-V1.txt";
# On écrit dans le fichier: 
print "$nbTerme éléments trouvés\n";
print $fileResu "$nbTerme éléments trouvés\n";
# Avec une boucle foreach on associe le patron (clé de diccionaire) à son valeur dans le diccionaire dicoPatron
# On met le patron dans le fichier:
foreach my $patron (keys %dicoPatron) {
	print "\nType de pattern: ".$patron." \n\n";
	print $fileResu "\nType de pattern: ".$patron." \n\n";
	# Avec une boucle foreach on associe à la variable terme la suite de tokens repérée du diccionaire via les patrons:
	foreach my $terme (sort {$dicoPatron{$patron}->{$b} <=> $dicoPatron{$patron}->{$a} } keys %{$dicoPatron{$patron}}) {
		# On écrit les patrons dans la même ligne que son patron:
		print $dicoPatron{$patron}->{$terme}."\t".$terme."\n";
		print $fileResu $dicoPatron{$patron}->{$terme}."\t".$terme."\n";
	}
}
# On affiche le temps de l'exécution:
print "\nScript execution time: " . tv_interval($timepg) . " seconds.";
print $fileResu "\nScript execution time: " . tv_interval($timepg) . " seconds.";
# Fermeture du fichier de sortie:
close($fileResu);
