M4 est la mise en œuvre par le projet GNU du processeur de macro traditionnel UNIX. M4 lit et interprète un fichier texte en entrée et produit un fichier texte en sortie. Il possède des fonctions internes permettant notamment:
Le processeur de macro copie son entrée sur sa sortie en développant les macros internes ou définies par l'utilisateur.
Lorsque m4 lit le fichier d'entrée il identifie des jetons (unité sémantique). Un jetons peut être un nom, un chaîne citée ou un simple caractère ne faisant parti ni d'un nom ni d'une chaîne citée.
Un nom est une séquence de caractères alphanumériques commençant par une lettre ou le caractère '_'. Si le nom correspond à une définition de macro il sera sujet à développement.
Une chaîne citée est une séquence de caractères encadrée par `
et '
. La valeur du jeton est le texte avec un niveau de citation retiré.
Entrée | Valeur du jeton |
---|---|
`essai' | essai |
``essai2'' | `essai2' |
Les commentaires commencent à partir du caractère #
jusqu’à la fin de ligne. La citation désactive le commentaire.
Les jetons ne faisant pas parti d'un nom, d'une chaîne citée ou d'un commentaire sont copiés directement sur la sortie. Lorsqu'un nom correspond a une définition de macro m4 calcule son développement et peut lire davantage l'entrée pour récupérer les arguments. Le développement est inséré en amont de l'entrée restante. En d'autres termes le texte résultant d'une macro est a nouveau analysé pour déterminer les jetons.
Pas d'espace entre le nom de la macro et la parenthèse ouvrante sinon le processeur de macro tentera de développer la macro en l'appelant sans arguments.
# macro_test est invoquée sans argument macro_test # macro_test invoquée avec 2 arguments macro_test(arg1, arg2) # macro_test invoquée avec 1 argument vide macro_test()
La mise en citation d'une chaine peut éviter l'identification comme un nom de macro la concaténation d'un développement avec les caractères environnants comme le montre l'exemple ci-dessous
define(`macro', `di$1')
# Le developpement de la macro est concatené aux caractères qui le suivent
# mais la mise en citation des caractères suivant empeche l'identification
# du nom de la macro interne divert et la chaine "divert" est transmise
# en sortie.
macro(`v')`ert'
# Sans mise en citation des caractères suivant le nom de macro interne
# "divert" est identifié et la macro est appelé retournant une chaine vide
#
macro(`v')ert
Tous les arguments d'une macros sont des chaînes de caractères mais certaines pourront être interprétées comme nombre, nom de fichier ou expression rationnelle etc.
Un argument vide n'est pas identique à un argument omis. Un argument omis utilise la valeur définie dans le prototype alors qu'un argument vide utilise explicitement une chaîne vide.
La fonction define() permet de définir les macros. Dans la plupart des cas, il faut consolider le nom de la macro pour éviter le développement en cas de redéfinition de la macro.
# Définition de la macro nommée test define(test, un) # Dans la définition ci dessous test est développé define(test, deux) # on obtient: # define(un, deux) # La définition aboutit a une macro différente et non pas à la redéfinition de la macro test test un