SPIP - Contrib

[ar] [en] [es] [fr] [it]



Accueil du site > Documentation > Tutoriaux pour le code de SPIP

Le Compilateur De Squelettes

mercredi 5 octobre 2005. Dernier ajout dimanche 17 juin 2007



Comment ça marche : le compilateur de squelettes

Là .. on attaque le gros morceau :-)

La fonction calculer_squelette (dans inc-compilo) prend 4 arguments :

  • $squelette : le texte du squelette source
  • $nom : le nom de la fonction principale attendue
  • $gram : l’extension
  • $sourcefile : le nom du fichier squelette source

Voila ce qu’elle fait :

  • défini un tableau $boucles vide. Il contiendra plus tard une entrée par boucle du squelette (ccmStructureTableauBoucle).
  • inclusion de inc-$gram-squel.php3 qui doit définir une fonction phraser (ccmPhraseur)
  • appel de cette fonction ($boucle est passé en argument et peuplé par la fonction) et retour mis dans la variable $racine (=nom de la boucle principale du squelette)
  • init d’un tableau $descr avec les champs nom (le nom de la fonction principale), documents (false) et sourcefile (le nom du fichier sqC)
  • on passe le champ document à true s’il y a une boucle de type documents avec le critère doublons.
  • on établi le lien mère/fille pour les boucles récursives et on appelle calculer_liste dessus
  • pour les autres boucles
    • on récupère son id_table et sa primary_key ainsi que ses jointures (pour les tables spip)
    • on appelle calculer_criteres dessus
    • on appelle calculer_liste dessus
  • on appelle calculer_liste sur la racine
  • dans les 3 cas, le retour de la fonction calculer_liste est mis dans le champ return de la boucle.
  • pour chaque boucle
    • on appelle la fonction de génération de code associée, c’est à dire une fonction boucle_{machin}, sinon boucle_{machin]-dist, sinon boucle_DEFAUT (machin étant le type de la boucle, c’est à dire ARTICLES, MOTS ...). Ces fonctions doivent retourner le corps d’une fonction générant le code de la boucle.
      • la plupart de ces fonctions appellent calculer_boucle qui effectue la génération de code select et la boucle d’itérations associée. À ce moment, le phraseur à déjà analysé les critères de boucle, et mis leur interprétation dans les champs de la structure boucle, mais c’est cette fonctio qui en déduit les éléments de requète et d’itérateur à générer.
    • on affecte au champ return le code de la déclaration d’une fonction :
      • son nom est construit à partir du nom du squelette et de celui de la boucle
      • son code est celui retourné par la fonction boucle_*
      • ses arguments sont fixés
    • si on est en mode debug, on ajoute des trucs au champ return, via la fonction boucle_debug_compile
  • pour chaque boucle, on ajoute son champ return à une chaine de caractère qui constitue donc le code compilé
  • on ajoute un commentaire d’entête à tout le machin et la définition de la fonction principale
  • on retourne le tout.

Bon ... c’est carrément pas clair car il est toujours difficile d’expliquer un code de compilateur, où des fonctions retournent le code d’un corps de fonction à placer dans une chaîne qui devient un fichier source ...
Voila un schéma qui résume un peu ces différentes étapes :

j’ai également une version pdf et la source xfig que vous pouvez améliorer si ça vous botte.

À plusieurs reprises, on appelle calculer_liste sur une entrée du tableau boucles. Voila le commentaire de cette fonction :

// Production du code PHP a partir de la sequence livree par le phraseur
// $boucles est passe par reference pour affectation par index_pile.
// Retourne une expression PHP,
// (qui sera argument d'un Return ou la partie droite d'une affectation).

Elle appelle compile_cas puis colle les extraits de codes retournés avec éventuelement des infos de debug.

compile_cas boucle sur les éléments du tableau passé en argument (soit la racine d’un squelette, soit le milieu d’une boucle).
Pour chacun, selon qu’il s’agit d’un texte, un polyglotte (tag <multi>), un include, une boucle, un idiome (tag <:..:>), ou un champ, on appelle une fonction dédiée à ce cas (calculer_inclure, calculer_champ), ou on génère directement le code correspondant (appel à _T, multi_trad ou texte déspécialisé).
Dans certains cas, des parties avant/apres/sinon sont évaluées via un appel à calculer_liste.
Pour chaque bloc, on génère ensuite un extrait contenant le code seul, ou la construction si/alors/sinon associée à une boucle ou un champ.

Il y a également un appel tout discret à calculer_criteres qui a pourtant son importance : cette fonction parcours la liste des critères de la boucle, et pour chacun, il appelle une fonction criteres_OP sinon criteres_OP_dist sinon calculer_critere_DEFAUT ou calculer_critere_parties (dans le cas des critères {1,2} ou {1/3}.
Le "OP" correspond à l’opérateur du critère, c’est à dire un élément isolé lors du parsing (pour plus de détail, voir la fonction phraser_criteres de inc-html-squel, bon courage ...).


Répondre à cet article



Suivre la vie du site RSS 2.0 | Plan du site | Espace privé | Charte et vie SPIP-Contrib | SPIP | L'autre.net