#!/usr/bin/perl

# script qui affiche les nombres d'occurences des variables d'un fichier perl, en ordre croissant
# classée par 3 catégories : scalaire, vectoriel et hash
# les nombres d'occurences des mots dans les commentaires (si on donne un 2° argument au script)

$fichier_texte = shift;
chomp $fichier_texte;
open(TEXT, "<$fichier_texte");
print "\n";
# affichage d'une ligne vide à l'écran
# pour permettre de voir plus facilement où commence l'exécution du script
$traiter_commentaires = shift;
chomp $traiter_commentaires;

while (<TEXT>) {
	if (/\s*#/) {
	# c'est du commentaire
		if ($traiter_commentaires ne "") {
		# si on a demandé de traiter les commentaires
			s/^\s*#//;
			# supprimer le premier caractère "#" et les éventuels "espaces" qui précèdent
	
			# ce qui suit est repris du script "occurences2b"
			s/[.,"';:!?\(\)]/ /g;
			# remplacer les caractères de ponctuation par des espaces
			s/(.*)/\L$1/g;
			# mettre tout en minuscules
			@mots = split;
			# mettre les mots de la ligne dans le vecteur @mots
			foreach (@mots) {
			# parcourir le vecteur ($_ = le mot)
				$mots{$_}++;
				# incrémenter le compteur du hash %mots pour la clé = le mot
			}
		}
	} else {
		# c'est du code
		while (/[\$@%]\w+/) {
		# tant que la ligne contient une variable (des 3 catégories)
		# examiner la première, la traiter et la supprimer
		# la première : entre le début de ligne "^" et ce qu'on cherche "\$\w+\["
		# il n'y que des caractères qui ne sont ni "$", ni "@", ni "%" : "[^\$@%]*"
			if (/^[^\$@%]*\$\w+\[/) {
			# si c'est une composante d'un vecteur (style $vect[])
				s/[^\$@%]*(\$\w+)\[//;
				# supprimer la variable, et tout ce qui précède
				$var = $1;
				# récupérer la variable, qui avait été mise entre () dans le s///;
				$var =~ s/\$/@/;
				# transformer le nom de la variable en "@"
				$vars_vect{$var}++;
				# incrémenter le hash %vars_vect pour la variable
			} elsif (/^[^\$@%]*\$\w+\{/) {
			# si c'est une valeur d'un hash (style $hash{})
				s/[^\$@%]*(\$\w+)\{//;
				# supprimer la variable, et tout ce qui précède
				$var = $1;
				# récupérer la variable, qui avait été mise entre () dans le s///;
				$var =~ s/\$/%/;
				# transformer le nom de la variable en "%"
				$vars_hash{$var}++;
				# incrémenter le hash %vars_hash pour la variable
			} elsif (/^[^\$@%]*\$/) {
			# si une variable scalaire, c'est-à-dire
			# un $ qui n'est suivi ni par un "[" ni par une "{"
			# qui sont les cas traités ci-dessus
				s/[^\$@%]*(\$\w+)//;
				# supprimer la variable, et tout ce qui précède
				$var = $1;
				# récupérer la variable, qui avait été mise entre () dans le s///;
				$vars_scal{$var}++;
				# incrémenter le hash %vars_scal pour la variable
			} elsif (/^[^\$@%]*\@/) {
			# si c'est un vecteur (désigné globalement, style @vect)
				s/[^\$@%]*(\@\w+)//;
				# supprimer la variable, et tout ce qui précède
				$var = $1;
				# récupérer la variable, qui avait été mise entre () dans le s///;
				$vars_vect{$var}++;
				# incrémenter le hash %vars_vect pour la variable
			} elsif (/^[^\$@%]*\%/) {
			# si c'est un hash (désigné globalement, style %hash)
				s/[^\$@%]*(\%\w+)//;
				# supprimer la variable, et tout ce qui précède
				$var = $1;
				# récupérer la variable, qui avait été mise entre () dans le s///;
				$vars_hash{$var}++;
				# incrémenter le hash %vars_hash pour la variable
			}

		}
	}
}
print "Le fichier \"$fichier_texte\" contient : \n\"Nombre d'occurences\" : \"Variable scalaire\"\n";
foreach (sort keys %vars_scal) {
	 push (@occurences, "$vars_scal{$_}\t: $_\n");
	# mettre les lignes d'affichage dans le vecteur @occurences
}
foreach (sort {$a <=> $b} @occurences) {
# trier en odre croissant (des nombres d'occurences) pour l'affichage
# l'option {$a <=> $b} fait que le tri (sort) se fait en ordre numérique
# au lieu de l'ordre lexical (alphabétique), qui est le tri par défaut
	 print;
}

@occurences = "";
# réinitialiser @occurences à vide
print "Le fichier \"$fichier_texte\" contient : \n\"Nombre d'occurences\" : \"Variable vectorielle\"\n";
foreach (sort keys %vars_vect) {
	 push (@occurences, "$vars_vect{$_}\t: $_\n");
	# mettre les lignes d'affichage dans le vecteur @occurences
}
foreach (sort {$a <=> $b} @occurences) {
# trier en odre croissant (des nombres d'occurences) pour l'affichage
# l'option {$a <=> $b} fait que le tri (sort) se fait en ordre numérique
# au lieu de l'ordre lexical (alphabétique), qui est le tri par défaut
	 print;
}

@occurences = "";
# réinitialiser @occurences à vide
print "Le fichier \"$fichier_texte\" contient : \n\"Nombre d'occurences\" : \"Variable hash\"\n";
foreach (sort keys %vars_hash) {
	 push (@occurences, "$vars_hash{$_}\t: $_\n");
	# mettre les lignes d'affichage dans le vecteur @occurences
}
foreach (sort {$a <=> $b} @occurences) {
# trier en odre croissant (des nombres d'occurences) pour l'affichage
# l'option {$a <=> $b} fait que le tri (sort) se fait en ordre numérique
# au lieu de l'ordre lexical (alphabétique), qui est le tri par défaut
	 print;
}

if ($traiter_commentaires ne "") {
# si on a demandé de traiter les commentaires
	@occurences = "";
	# réinitialiser @occurences à vide
	# ce qui suit est repris du script "occurences2b"
	print "Les commentaires du fichier \"$fichier_texte\" contiennent : \n\"Nombre d'occurences\" : \"Mots\"  :\n";
	foreach (sort keys %mots) {
		push (@occurences, "$mots{$_}\t: $_\n");
		# mettre les lignes d'affichage dans le vecteur @occurences
	}
	foreach (sort {$a <=> $b} @occurences) {
	# trier en odre croissant (des nombres d'occurences) pour l'affichage
	# l'option {$a <=> $b} fait que le tri (sort) se fait en ordre numérique
	# au lieu de l'ordre lexical (alphabétique), qui est le tri par défaut
		print;
	}
}
