Valider 3058f0c8 rédigé par esj's avatar esj
Parcourir les fichiers

Deuxième modification des spécifications du décompilateur (cf [14197] et 14227]).

Il n'était pas normal que les fonctions de formatage reçoivent un bout de l'arbre de syntaxe abstraite, alors que leur rôle est de fournir un syntaxe concrète indépendamment de cet arbre. De plus, cela ne permettait que de forcer la notation en champ étendu lorsqu'un champ est suivi d'un caractère qui pourrait s'agrégé à lui (par exemple {{{#X}}} suivi d'une étoile doit s'écrire {{{[(#X)]*}}}), mais difficilement la situation inverse (par exemple une parenthèse suivie d'un champ doit s'écrire {{{([(#X)]}}}).

On introduit donc une nouvelle fonction chargée de restituter la syntaxe de la concaténation de lexèmes, car elle n'est pas forcément la fonction identité. Elle reçoit un tableau formé de sous-tableaux de deux éléments: le lexème et son type (afin de distinguer l'origine de ces syntaxes concrètes). Par ailleurs, les deux fonctions qui recevaient l'extrait d'arbre de syntaxe abstraite ne le reçoivent plus. Enfin, on introduit aussi une fonction chargée de restituer la syntaxe concrète d'un texte brut, ça peut servir au transcodage de caractères.

Le jeu de fonctions restituant le format de sortie passe donc à 9: {{{format_boucle_* format_include_* format_polyglotte_* format_idiome_* format_champ_* format_critere_* format_liste_* format_suite_* format_texte_*}}}. Le suffixe par défaut est toujours celui indiqué par la constante _EXTENSION_SQUELETTES, savoir html traditionnellement, et le fichier public/format_''format''.php est toujours automatiquement chargé pour fournir la syntaxe en sortie.

Cette nouvelle spécification permet de réaliser plus facilement le devoir de vacances suite à la [http://videos.spip.org/spip.php?article113 session de Juin 2009 de SPIP-Party]: écrire les 9 fonctions produisant la syntaxe proposée. On pourra utiliser [http://zone.spip.org/trac/spip-zone/changeset/29950 ce plugin], mais il devra être mis à jour.
parent 26bd7f41
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+20 −19
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -14,7 +14,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return;

// Decompilation de l'arbre de syntaxe abstraite d'un squelette SPIP

function decompiler_boucle($struct, $fmt, $prof=0, $next='')
function decompiler_boucle($struct, $fmt, $prof=0)
{
	$nom = $struct->id_boucle;
	$avant = public_decompiler($struct->avant, $fmt, $prof);
@@ -42,7 +42,7 @@ function decompiler_boucle($struct, $fmt, $prof=0, $next='')
	return $f($avant, $nom, $type, $crit, $milieu, $apres, $altern, $prof);
}
	
function decompiler_include($struct, $fmt, $prof=0, $next='')
function decompiler_include($struct, $fmt, $prof=0)
{
	$res = array();
	$fond = '';
@@ -55,22 +55,23 @@ function decompiler_include($struct, $fmt, $prof=0, $next='')
			else $res[]= $a;
		}
	}
	$f = 'format_include_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	$f = 'format_inclure_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($struct->texte, $fond, $res, $prof);
}

function decompiler_texte($struct, $fmt, $prof=0, $next='')
function decompiler_texte($struct, $fmt, $prof=0)
{
	return $struct->texte;
	$f = 'format_texte_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return strlen($struct->texte) ? $f($struct->texte, $prof) : '';
}

function decompiler_polyglotte($struct, $fmt, $prof=0, $next='')
function decompiler_polyglotte($struct, $fmt, $prof=0)
{
	$f = 'format_polyglotte_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($struct->traductions, $prof);
}

function decompiler_idiome($struct, $fmt, $prof=0, $next='')
function decompiler_idiome($struct, $fmt, $prof=0)
{
	$module = ($struct->module == 'public/spip/ecrire')? ''
	  : $struct->module;
@@ -83,10 +84,10 @@ function decompiler_idiome($struct, $fmt, $prof=0, $next='')
	$filtres =  decompiler_liste($struct->param, $fmt, $prof);

	$f = 'format_idiome_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($struct->nom_champ, $module, $args, $filtres, $next, $prof);
	return $f($struct->nom_champ, $module, $args, $filtres, $prof);
}

function decompiler_champ($struct, $fmt, $prof=0, $next='')
function decompiler_champ($struct, $fmt, $prof=0)
{
	$avant = public_decompiler($struct->avant, $fmt, $prof);
	$apres = public_decompiler($struct->apres, $fmt, $prof);
@@ -96,9 +97,8 @@ function decompiler_champ($struct, $fmt, $prof=0, $next='')
		  $args = decompiler_liste(array(array_shift($p)), $fmt, $prof);
		$filtres = decompiler_liste($p, $fmt, $prof);
	}

	$f = 'format_champ_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $next, $prof);
	return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
}

function decompiler_liste($sources, $fmt, $prof=0) {
@@ -129,9 +129,9 @@ function decompiler_liste($sources, $fmt, $prof=0) {
// - le champ apres signale le critere {"separateur"} ou {'separateur'}
// - les champs sont implicitement etendus (crochets implicites mais interdits)
function decompiler_criteres($sources, $comp, $fmt='', $prof=0) {
	if (!is_array($sources)) return '';
	$res = '';
	$f = 'format_critere_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);

	foreach($sources as $crit) {
		if (!is_array($crit)) continue; // boucle recursive
		array_shift($crit);
@@ -157,12 +157,14 @@ function decompiler_criteres($sources, $comp, $fmt='', $prof=0) {
	return $res;
}


function public_decompiler($liste, $fmt='', $prof=0, $suite=' ')
{
	if (!is_array($liste))  return '';
	include_spip('public/format_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES));
	$contenu = '';
	$prof2 = ($prof < 0) ? ($prof-1) : ($prof+1);
	if (is_array($liste)) foreach($liste as $k => $p) {
	$contenu = array();
	foreach($liste as $k => $p) {
	    if (!isset($p->type)) continue; #??????
	    $d = 'decompiler_' . $p->type;
	    $next = isset($liste[$k+1]) ? $liste[$k+1] : false;
@@ -182,11 +184,10 @@ function public_decompiler($liste, $fmt='', $prof=0, $suite=' ')
		$next->texte = substr($next->texte, $n);
	      }
	    }
	    // preciser le suivant pour permettre le raccourci [(#X)] ==> #X
	    $contenu .= $d($p, $fmt, $prof2, $next);
	    $contenu[] = array($d($p, $fmt, $prof2), $p->type);

	}

	return $contenu;
	$f = 'format_suite_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($contenu);
}
?>
+53 −29
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -21,12 +21,12 @@ function format_boucle_html($avant, $nom, $type, $crit, $corps, $apres, $altern,
	return "$avant<BOUCLE$nom($type)$crit$corps$apres$altern";
}

function format_include_html($file, $fond, $args, $prof)
function format_inclure_html ($file, $fond, $args, $prof)
{
 	$t = $file ? ("(" . $file . ")") : "" ;
	if ($fond) array_unshift($args, "fond=" . $fond);
	if ($args) $args = "{" . join(", ",$args) . "}";
	return "<INCLURE" . $t . $args  . ">";
	return ("<INCLURE" . $t . $args  . ">");
}

function format_polyglotte_html ($args, $prof)
@@ -34,17 +34,17 @@ function format_polyglotte_html($args, $prof)
	$contenu = array(); 
	foreach($args as $l=>$t)
		$contenu[]= ($l ? "[$l]" : '') . $t;
	return "<multi>" . join(" ", $contenu) . "</multi>";
	return ("<multi>" . join(" ", $contenu) . "</multi>");
}

function format_idiome_html($nom, $module, $args, $filtres, $next, $prof)
function format_idiome_html ($nom, $module, $args, $filtres, $prof)
{
	foreach ($args as $k => $v) $args[$k] = "$k=$v";
	$args = (!$args ? '' : ('{' . join(',', $args) . '}'));
	return "<:" . ($module ? "$module:" : "") . $nom . $args . $filtres . ":>";
	return ("<:" . ($module ? "$module:" : "") . $nom . $args . $filtres . ":>");
}

function format_champ_html($nom, $boucle, $etoile, $avant, $apres, $args, $filtres, $next, $prof)
function format_champ_html ($nom, $boucle, $etoile, $avant, $apres, $args, $filtres, $prof)
{
	$nom = "#"
	. ($boucle ? ($boucle . ":") : "")
@@ -54,30 +54,16 @@ function format_champ_html($nom, $boucle, $etoile, $avant, $apres, $args, $filtr
	. $filtres;

	// Determiner si c'est un champ etendu, 
	// notamment pour viter que le lexeme suivant s'agrege au champ
	// si pas d'etoile terminale, pas d'arg et suivi d'une ambiguite

	$s = ($avant OR $apres OR $filtres
	      OR ($prof < 0) 
	      OR (strpos($args, '(#') !==false)
	      OR (!$args
		    AND !$etoile
		    AND	$next
		    AND ($next->type == 'texte')
		  AND preg_match(',^[\w\d|{*],', $next->texte)));
	      OR (strpos($args, '(#') !==false));

	return $s ? "[$avant($nom)$apres]" : $nom;
	return ($s ? "[$avant($nom)$apres]" : $nom);
}

function format_liste_html($fonc, $args, $prof)
{
  return (($fonc!=='') ? "|$fonc" : $fonc)
	. (!$args ? "" : ("{" . join(",", $args) . "}"));
}

function format_critere_html($criteres)
function format_critere_html ($critere)
{
	foreach ($criteres as $k => $crit) {
	foreach ($critere as $k => $crit) {
		$crit_s = '';
		foreach ($crit as $operande) {
			list($type, $valeur) = $operande;
@@ -88,8 +74,46 @@ function format_critere_html($criteres)
			}
			$crit_s .= $valeur;
		}
		$criteres[$k] = $crit_s;
		$critere[$k] = $crit_s;
	}
	return (!$critere ? "" : ("{" . join(",", $critere) . "}"));
}

function format_liste_html ($fonc, $args, $prof)
{
	return ((($fonc!=='') ? "|$fonc" : $fonc)
	. (!$args ? "" : ("{" . join(",", $args) . "}")));
}

// Concatenation sans separateur: verifier qu'on ne cree pas de faux lexemes
function format_suite_html ($args)
{
	for($i=0; $i < count($args)-1; $i++) {
		list($texte, $type) = $args[$i];
		list($texte2, $type2) = $args[$i+1];
		if (!$texte OR !$texte2) continue; 
		$c1 = substr($texte,-1);
		if ($type2 !== 'texte') {
		  // si un texte se termine par ( et est suivi d'un champ
		  // ou assimiles, forcer la notation pleine
			if ($c1 == '(' AND substr($texte2,0,1) == '#')
				$args[$i+1][0] = '[(' . $texte2 . ')]';
		} else {
			if ($type == 'texte') continue;
			// si un champ ou assimiles est suivi d'un texte
			// et si celui-ci commence par un caractere de champ
			// forcer la notation pleine
			if (($c1 == '}' AND substr(ltrim($texte2),0,1) == '|')
			OR (preg_match('/[\w\d_*]/', $c1) AND preg_match('/^[\w\d_*{|]/', $texte2)))
				$args[$i][0] = '[(' . $texte . ')]';
		}
	}
	return join("", array_map('array_shift', $args));
}
	return (!$criteres ? "" : ("{" . join(",", $criteres) . "}"));

function format_texte_html ($texte)
{
	return $texte;
}

?>