Le Compilateur De Squelettes

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 ...).

Discussion

No discussion

Add a comment

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite / PostgreSQL
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparait.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Who are you?
[Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom