Analyse de Grammaire Formelles pour
Documentation
du programme AnaGram
Gilles HUNAULT, Philippe ALBERT, Angers - 94
Anagram :
Analyse d'une grammaire et Affichage des productions.
Le nom du fichier associé à la grammaire est passé en
paramètre.
Les paramètres possibles sont :
p1 : nom de grammaire(.grm).
p2 : le mot STOP pour un arrêt après l'analyse
seulement de la grammaire (pas de productions)
ou le mot DBG pour mise au point, FILTRE pour
choisir les affichages, NOSTAT pour éviter les
statistiques d'utilisation des règles, etc.
p3 : le mot SIMPLIF pour une simplification.
p4 : le mot CUMUL pour un cumul.
p5 : le mot INT pour une interprétation numérique
des symboles (fichier .INT), les valeurs de cette
interprétation étant stockées dans un fichier .SIN
p6 : le mot FOR (plus un nombre d'étape). Par défaut le
nombre d'étape est 5.
p7 : le mot GPL pour générer un fichier lisible par
Gnuplot (cela induit forcement une interprétation
numérique, l'option INT est donc automatiquement
activée).
p8 : le mot REP pour que la génération de productions se
fasse en mode répétition, sinon elle se fait en
mode modulo.
Si l'ordre des paramètres est a priori fixé, le
programme sait "à peu près" reconnaitre les mots STOP,
INT, etc.
Déroulement :
On lit dans cet ordre sur la ligne 1 l'alphabet puis les
variables sur la ligne 2 puis le symbole de départ.
Enfin, chaque production est lue, à raison d'une par
ligne, avec en fin de ligne l'impulsion correspondant à
la production.
Variables fondamentales :
Ligne alphabet : LA ; symboles A.i en nombre NA
Ligne variables : LV ; symboles V.i en nombre NV
Symbole terminal : S
Ligne production : LP ; partie gauche p.g.i
partie droite p.d.i
en nombre np
Impulsion associé à la production : E.i
Méthode :
Chaque production génère une ligne NLS qu'on renomme
ensuite LS ; NLS comptient NT mots qu'on note toujours
MS. On recherche la production qui va s'appliquer à MS.
Pour cela on vérifie :
* la présence de MS dans la partie gauche de
la production (pour les deux modes).
* que le reste de la division de l'impulsion
E.i par l'indice MS.T de MS est bien égale à zéro (en
mode MODULO).
* que le nombre de fois, de suite, ( = E.i )
où la règle de production doit s'appliquer n'est pas
dépassé (mode REPETITION).
Exemple : r1 est définie par : a > b [1]
r2 est définie par : a > c [2]
En mode MODULO il s'applique, à l'étape 1 : r1
2 : r2
3 : r1
4 : r2
EN mode REPETITION, à l'étape 1 : r1
2 : r2
3 : r2
4 : r1
On remplace alors ms par la partie droite de la
production associée. En fin de programme, on affiche
combien de fois chaque règle est utilisée.
Un symbole de l'alphabet est toujours recopié, mais pas
une variable. Les règles peuvent avoir des productions
multiples ; ainsi a > a | b est valide. La machine fait
un tirage alétaoire du n³ de production à utiliser.
Interprétation numérique :
Seules les variables de poids non nul doivent être
entrées ; toute variable non indiquée se voit affecter
un poids égal à 0.
Remarques sur les paramètres :
Les mots suivants sont reconnus
CUMUL
DBG
FILTRE
For [nbetap], par default: 5
GPL
INT
NOAFF
NOSTAT
NOWAIT
REP
SIMPLIF
STOP
Pour que ANAGRAM fonctionne vous devez posséder les
fichiers :
ANAGRAM.HLP
ANAGRAM.REX
CUMULE.REX
DSE.REX
EXISTE.REX
MONTRE.REX
SIMPLE.REX
Texte
du programme AnaGram
#! /home/xed/srexx
/* Anagram.Rex */
/* # 0.0 Détection des paramètres */
parse arg nomf lignearg /* parse est obligatoire pour UNIX */
lignearg = upper(lignearg)
if wordpos("DBG",lignearg) > 0 then do
signal on failure
signal on halt
signal on error
signal on syntax
debug = "ON"
end
if wordpos("STOP" ,lignearg) > 0 then do ; arret = "STOP" ; end
if wordpos("CUMUL" ,lignearg) > 0 then do ; cumul = "OUI" ; end
if wordpos("SIMPLIF",lignearg) > 0 then do ; simplif = "OUI" ; end
if wordpos("FILTRE" ,lignearg) > 0 then do ; filtrage = "OUI" ; end
if wordpos("INT" ,lignearg) > 0 then do ; interp = "INT" ; end
if wordpos("NOSTAT" ,lignearg) > 0 then do ; nostat = "OUI" ; end
if wordpos("NOAFF" ,lignearg) > 0 then do ; affiche = "NON" ; end
if wordpos("NOWAIT" ,lignearg) > 0 then do ; nowait = "OUI" ; end
if wordpos("FOR" ,lignearg) > 0 then do
etapf = "OUI"
say lignearg
parse var lignearg with "FOR" nef .
if (nef = "") | \datatype(nef,"W") then do ; nef = 5 ; end
end
if wordpos("GPL" ,lignearg) > 0 then do
gnuplt = "GPL"
interp = "INT"
end
if wordpos("REP" ,lignearg) > 0 then do
gen = "REP"
pas = 1
end ; else do
gen = "MOD" /* option par défaut */
pas = 2
end
if debug = "ON" then do
if arret = "STOP" then do ; say " on stoppe après analyse " ; end
if cumul = "OUI" then do ; say " on cumule " ; end
if simplif = "OUI" then do ; say " on simplifie " ; end
if filtrage = "OUI" then do ; say " on filtre " ; end
if interp = "INT" then do ; say " il y a interprétation numérique " ; end
if gnuplt = "GPL" then do ; say " il y a génération d'un fichier lisible par Gnuplot" ; end
if etapf = "OUI" then do ; say " en route pour " nef " étapes " ; end
call charout , " ok ? "
pull .
end
/* attention au disque virtuel */
virtuel = "D:" /* ou virtuel = "" sont ok */
virtuel = "/tmp/" /* pour Unix */
virtuel = "" /* pour Unix */
/* # 0.1 Gestion de la demande d'aide */
/* Si le paramètre est ? on affiche un texte d'aide */
if nomf = '?' | nomf = '' then do
call montre "anagram.hlp"
exit
end /* finsi nomf = '?' | nomf = '' */
/* # 0.2 Gestion des paramètres et fichiers */
/* - nom du fichier grammaire */
/* - fichier d'interprétation */
/* Si on ne voit pas le fichier sur le répertoire courant, */
/* on le dit et on abandonne le programme. */
ip = pos(".",nomf)
if ip=0
then do ; fichgram=nomf||".grm" /* minuscule pour Unix */ ; end ;
else do
fichgram=nomf
nomf = substr(nomf,1,ip-1)
end
/* fin de si */
if existe(fichgram) = "" then do
say " fichier " fichgram "non vu "
say " abandon du programme "
exit -1
end /* if existe(fichgram) = 0 */
sorint = nomf".sin"
sorgpl = nomf".gpl"
call dse(sorint)
call dse(sorgpl)
/* # 1.0 Analyse de la grammaire */
/* # 1.0 Lecture du fichier grammaire */
/* On lit l'aphabet, les variables, le symbole de départ */
/* dans les trois première lignes du fichier . */
/* Chaque règle de production est lue à raison d'une */
/* par ligne, la partie gauche et la partie droite */
/* sont séparées par le symbole > */
/* # 1.1 Lecture de l'alphabet */
LL = linein( fichgram )
if pos(";",LL) > 0
then do ; parse value LL with LA ";" rems ; end ;
else do ; LA = LL ; end
/* fin de si */
na = words(LA)
do i = 1 to na
A.i = word(LA,i)
end /* do i = 1 to na */
/* # 1.2 Lecture des variables */
/* On considère que trouver un symbole de variable égal */
/* à un symbole d'alphabet est une erreur ; on le signale */
/* en cours de lecture et on rappelle le nombre d'erreurs */
/* en fin de lecture. */
LL = linein( fichgram )
if pos(";",LL) > 0
then do ; parse value LL with LV ";" rems ; end ;
else do ; LV = LL ; end
err = 0
nv = words(LV)
do i = 1 to nv
vtmp = word(LV,i)
V.i = vtmp
if pos(vtmp,LA) > 0 then do
err = err + 1
say " " vtmp " déja vu dans " LA
end
end /* do i = 1 to nv */
if err > 0 then do
say err " erreur(s) pour les variables "
end /* if err > 0 */
/* # 1.3 Lecture du symbole de départ */
/* C'est une erreur que de ne pas trouver le symbole */
/* de départ dans la liste des variables s'il n'a qu'une lettre. */
/* En mode MODULO on attribut un indice égale à 1 au symbole */
/* de départ : de facon à avoir S, puis un blanc, puis l'indice. */
LL = linein( fichgram )
if pos(";",LL) > 0
then do ; parse value LL with S ";" rems ; end ;
else do ; S = LL ; end
S = strip(S,'B')
if gen = "MOD" then do
nS = S||" "
p = pos(" ",nS)
do while p > 0
nS = substr(nS,1,p)||"1 "||substr(nS,p+1)
p = pos(" ",nS,p+3)
end /* do while p > 0 */
nS = strip(nS,'B')
end /* if gen = "MOD" */
else do ; nS = S ;end
if pos(S,LV) = 0 & length(S) = 1 then do
err = err + 1
say "erreur ! ; symbole de départ non vu comme variable "
say " symbole de départ : " S
say " liste des variables " LV
pull .
end /* pos(S,LV) = 0 */
/* # 1.4 Lecture des règles de production */
/* On vient tester que chaque partie gauche notée X */
/* a chacun de ses mots (noté XJ) dans LAuLv qui */
/* est la concaténation de LA et LV ; même test */
/* pour chaque partie gauche LY et ses mots YJ */
/* pour un bel affichage, on supprime les blancs */
/* de tête et de queue éventuels. */
/* On associe à la règle nø i : */
/* p.g.i la partie droite avant > */
/* p.r.i le nombre de productions séparées par | */
/* p.d.i.1 est la première production */
/* p.d.i.2 est la deuxième production */
/* ... */
/* p.d.i.(p.r.i) est la dernière */
/* p.n.i compte le nombre de fois où la règle */
/* est utilisée. */
/* e.i est l'impulsion associée à la règle, */
/* elle correspond au modulo (option MOD) */
/* ou au nombre de répétitions de la règle */
/* (option REP). Si e.i n'existe pas dans */
/* le fichier de grammaire, on lui */
/* attribut la valeur 1 . */
i = 0
LAuLV = la lv
do while lines(fichgram)> 0 /* > 0 pour Unix */
i = i+1
lp = linein( fichgram )
if pos("[",lp) = 0 then do
parse value lp with x ">" y ";" rems
e.i = 1
end
else do ; parse value lp with x ">" y "[" e.i "]" ";" rems ; end
x = strip(x,'B')
if gen = "REP" then do
/* Le test suivant va compter le nombre de règles s'adressant */
/* à la même partie gauche. */
if x = temoin then do ; nbr.x = nbr.x + 1 ; end
else do ; nbr.x = 1 ; end
p.g.i = x /* partie gauche */
temoin = p.g.i
end /* if gen = "REP" */
else do ; p.g.i = x ; end
y = strip(y,'B') "|"
ly = y
ind124 = pos("|",ly)
nbpr = 0
do while ind124 > 0
nbpr = nbpr + 1
p.d.i.nbpr = strip(substr(ly,1,ind124-1),'B') /* partie droite */
ly = substr(ly,ind124+1)
ind124 = pos("|",ly)
if gen = "MOD" then do
/* On attribut un indice égale à 1 à chaque mot de la */
/* partie droite de la règle. Cet indice servira, par */
/* la suite à déterminer la règle devant s'appliquer. */
resul = ''
rest = p.d.i.nbpr||" "
do while pos(" ",rest) > 0
parse value rest with m " " rest
m = strip(m,'B')||" 1 "
resul = resul||m
end /* do while pos(" ",rest) > 0 */
p.d.i.nbpr = strip(resul,'B')
end /* if gen = "MOD" */
end /* do while ind124 > 0 */
p.r.i = nbpr
p.n.i = 0 /* nombre de fois */
do j = 1 to words(x)
xj = word(x,j)
if pos(xj , laulv ) = 0 then do
say "erreur ; partie gauche de règle invalide " xj
err = err + 1
pull .
end /* if pos(x laulv ) = 0 */
end /* do j = 1 to word(x) */
do j = 1 to words(y)
yj = word(y,j)
if pos( yj , laulv ) = 0 & yj \= "|" then do
say "erreur ; règle nø " i " invalide : " lp
say "erreur ; partie droite de règle invalide " yj
err = err + 1
pull .
end /* if pos(y , laulv ) = 0 */
end /* do j = 1 to word(y) */
end /* while lines(fichgram) */
np = i
/* # 2.0 Affichage de la grammaire */
/* On rappelle tout d'abord les constituants de la grammaire. */
/* "cls" */
say " Analyse du fichier grammaire : " fichgram
say " ---------------------------- "
say
if gen = "MOD" then do ; say " La génération de productions se fera en mode MODULO" ; end
else do ; say " La génération de productions se fera en mode REPETITION" ; end
say
say " Alphabet : "
do i = 1 to na
say " " substr(A.i " ",1,6) " est le symbole numéro " i
end /* do i = 1 to na */
if na = 0 then do
say " (aucun alphabet, sans doute un système L)"
end
say
say " Variables : "
do i = 1 to nv
say " " substr(V.i " ",1,6) " est la variable numéro " i
end /* do i = 1 to nv */
say
say " Symbole de départ est : " S
say
if (np >= 3) & (etapf \= "OUI") & nowait \= "OUI" then do
call charout , " Enter pour continuer "
pull .
end /* if np > 5 */
say " Productions : "
do i = 1 to np
call charout , " production " format(i,2) " : " p.g.i " ---> "
do j = 1 to p.r.i
call charout , p.d.i.j
if j < p.r.i then do ; call charout , " | " ; end
end
say
if (i = 20) & (etapf \= "OUI") then do
call charout , " Enter pour continuer "
pull .
end /* if i = 20 */
end /* do i = 1 to np */
say
say " Impulsions : "
do i = 1 to np
say " Pour la production "format(i,2)" : ["e.i"]"
end
say
call charout , " Enter pour continuer "
pull .
if interp="INT" then do
say
say " Interprétation Numérique : "
fichint = nomf||'.int'
if existe(fichint) = "" then do
say " Fichier " fichint "non vu "
say " Abandon du programme "
exit -1
end /* if existe(fichint) = 0 */
vaut. = 0
do while lines(fichint) > 0
lg = linein(fichint)
ma = word(lg,1) ; mb = word(lg,2) ;
vaut.ma = mb
say " " ma " vaut " mb
end
say
end
if err > 0 | arret = "STOP" then do ; exit ; end
/* # 3.0 Productions étape par étape */
/* une boucle infinie et qui s'arrête à chaque étape */
/* est utilisée ; on sort soit par la frappe d'un mot, soit */
/* par le Ctrl-Break habituel. */
/* # 3.1 Génération des productions */
chdep = ""
Filtre = ""
Ofltre = ""
AfficheSt = ""
SupVar = ""
if filtrage = "OUI" then do
call charout , " Affichage des productions "
call charout , " avec le Start Symbol ? (NON ou enter pour oui) "
pull AfficheSt .
call charout , " Filtre de début d'affichage ? "
parse pull Filtre
call charout , " Filtre d'omission en début ? "
parse pull Ofltre
call charout , " Suppression des variables sauf le SS ? "
parse pull SupVar
call charout , " Chaîne de départ (et indice si mode = MODULO) ? "
parse pull chdep
end /* fin de si sur filtrage */
if chdep = "" then do ; chdep = nS ; end
lonfil = length(Filtre)
lonOfl = length(Ofltre)
etape = 0 ; say ; say " Etape : " etape
if filtrage \= "OUI" then do ; say " " S ; end
else do ; say " " chdep ; end
say ; vu.chdep = 1
/* if interp="INT"
then do
say " valeur : " format(vaut.chdep,5)
end
else do ; say ; end */
fichprod = virtuel||"anagram.prd" /* et non pas "f:anagram.prd" */
fichsor = virtuel||"anagram.sor"
call dse(fichprod)
/* pas de call dse(fichsor) car il est fait dans
la boucle de réécriture */
call lineout fichprod , chdep
call lineout fichprod
/* toutes les productions obtenues à une étape sont stockées */
/* dans le fichier fichprod. on écrit les nouvelles productions */
/* dans fichsor. bien sùr, en fin d'étape, fichsor est recopié */
/* dans fichprod. chaque production lue s'appelle ls */
do nr = 1 to np ; p.n.nr = 0 ; test.nr = e.nr
do iet = 1 to 50 ; p.n.nr.iet = 0 ; end
end
infini:
do forever
call dse(fichsor)
etape = etape + 1
tot.etape = 0
say " Etape : " etape
vu. = 0 ; vu.tmp = 0
do while lines(fichprod) >0
ls = linein(fichprod)
nt = words(ls)
/* à chaque étape, chacune des productions précédentes */
/* qu'on note LS est analysée : elle contient NT mots nommés */
/* MS. On va rechercher la régle qui s'applique. */
/* On remplace alors MS par son substitué. */
/* On passe alors au mot suivant. */
/* Après l'affichage pur et dur de chaque nouvelle */
/* production, on tente - un affichage simplifié : */
/* aacbbbc donne aýcb3c ( fichier SIMPLE.REX ) */
/* - un affichage cumulé : */
/* aacbbbc donne aýcýb3 ( fichier CUMULE.REX ) */
declenche = 0
alphapres = 0
nls = ""
do m = 1 to nt by pas
nr = 0
ms = strip(word(ls,m),'B')
if gen = "MOD" then do
/* GENERATION DES PRODUCTIONS EN MODE MODULO */
/* On va chercher la règle qui s'applique à MS. Pour cela */
/* on test la présence de MS dans la partie droite de */
/* chaque règle, et le modulo donné par la division de */
/* l'indice de MS (MS.T) par l'impulsion associé à la règle */
/* (E.Q). Si plusieurs règle sont susceptibles de */
/* s'appliquer on prend celle ayant l'impulsion la plus */
/* importante, ou la première des deux si elles ont la */
/* même impulsion. */
ms.t = strip(word(ls,m+1),'B')
val = 0
do q = 1 to np
if pos(ms,p.g.q) > 0 then do
declenche = 1
if ( ms.t // e.q = 0 ) & ( e.q > val ) then do
val = e.q
nr = q
end /* fin si (ms.t//e.q=0)&(e.q>val) */
end /* fin si pos(ms,p.g.q) */
end /* do q = 1 to np */
if ( nr \= 0 ) then do
nbpec = p.r.nr
if nbpec = 1 then do ; h = 1 ; end
else do
alea = random(1,nbpec)
h = alea
end /* else do */
p = wordpos(ms,p.d.nr.h)
if p > 0 then do /* test s'il y a réécriture du mot */
nms.t = ms.t + 1
nms = subword(p.d.nr.h,1,p)||" "||nms.t||" "||subword(p.d.nr.h,p+2)
nms = strip(nms,'B')
end /* if p > 0 */
else do ; nms = strip(p.d.nr.h,'B') ; end
p.n.nr = p.n.nr + 1
p.n.nr.etape = p.n.nr.etape + 1
tot.etape = tot.etape + 1
end /* if nr \= 0 */
else do
if wordpos(ms,LA) = 0 then do
nms.t = ms.t + 1
nms = ms||" "||nms.t
end /* if wordpos(ms,LA) = 0 */
end /* else do de if nr \= 0 */
if wordpos(ms,LA) > 0 then do
nms.t = ms.t + 1
nms = ms||" "||nms.t
alphapres = 1
end /* if worpos(ms,LA) > 0 */
nls = nls||" "||nms
end /* if gen = "MOD" */
if gen = "REP" then do
/* GENERATION DES PRODUCTIONS EN MODE REPETITION */
/* Si aucune règle ne s'applique NBR est mis à 0 */
if datatype(nbr.ms,'N') = 0 then do ; nbr.ms = 0 ; end
/* On va rechercher la règle qui s'applique le mieux */
/* à MS. On test si plusieurs règles sont susceptibles */
/* de s'appliquer, si oui on recherche laquelle est la */
/* bonne en vérifiant que MS est bien présent dans la */
/* partie gauche de la règle Q, et que le nombre de fois où */
/* la règle doit s'appliquer (E.Q) n'est pas dépassé */
/* (TEST.Q > 0). Si toutes les règles correspondants au mot */
/* ont été appliquées le bon nombre de fois, on */
/* réinitialise la variable TEST.Q (= E.Q) . */
/* ATTENTION : l'application des règles se fait suivant */
/* leur ordre dans le fichier de grammaire */
tem = 0
if nbr.ms > 1 then do while(nr = 0)
q = 1
do while(tem = 0)
if pos(ms,p.g.q) > 0 & test.q \= 0 then do
test.q = test.q - 1
nr = q
tem = 1
end /* if pos(ms,p.g.q) > 0 & test.q \= 0 */
else do ; q = q + 1 ; end
if q > np then do ; tem = 1 ; end
end /* do while(tem = 0) */
if nr = 0 then do
do k = 1 to np
if pos(ms,p.g.k) > 0 then do ; test.k = e.k ; end
end /* do k = 1 to np */
tem = 0
end /* if nr = 0 */
end /* if nbr.ms > 1 */
else do q = 1 to np
if pos(ms,p.g.q) > 0 then do ; nr = q ; end
end /* else do q = 1 to np */
if (nr \= 0 ) then do
nbpec = p.r.nr
if nbpec = 1 then nms = strip(p.d.nr.1,'B')
else do
alea = random(1,nbpec)
nms = strip(p.d.nr.alea,'B')
end /* else do */
p.n.nr = p.n.nr + 1
p.n.nr.etape = p.n.nr.etape + 1
tot.etape = tot.etape + 1
declenche = 1
nls = nls||" "||nms
end /* if nr \= 0 */
if wordpos(ms,LA) > 0 then do
nms = ms
nls = nls||" "||nms
alphapres = 1
end /* if wordpos(ms,LA) > 0 */
end /* if gen = "REP" */
end /* m = 1 to nt by pas */
nls= strip(nls,'B')
vu.tmp = vu.tmp + 1
aff = pos(s,nls) = 0 | AfficheSt = ""
aff = aff & (declenche | alphapres)
aff = aff & (vu.tmp = 1)
if filtrage = "OUI" then do
if lonfil > 0 then do ; aff = aff & (substr(nls||" ",1,lonfil) = Filtre) ; end
if lonOfl > 0 then do ; aff = aff & (substr(nls||" ",1,lonOfl)\= Ofltre) ; end
end /* filtrage = "OUI" */
if SupVar <> "" then do ;
do iv = 1 to nv
if V.iv \= S then do ; aff = aff & pos(V.iv,nls) = 0 ; end
end /* fin pour iv */
end /* fin de si suvar <> "" */
/* affichage soigné */
tt = 0
if aff & affiche \= "NON" then do i = 1 to words(nls) by pas
mot = strip(word(nls,i),'B')
call charout ," "mot
tt = tt + length(mot) + 1
if tt >= 64 then do ; say ; tt = 0 ; end
end /* finsi aff & affiche */
say
call lineout fichsor , nls
/* # 3.2 Cumul */
if cumul = "OUI" then do ;
call cumule(pas nls) ; end
/* # 3.3 Simplification */
if simplif = "OUI" then do ; call simple(pas nls) ; end
/* # 3.4 Interprétation numérique */
if interp="INT" then do
v = 0
do j = 1 to words(nls) by pas
ind = word(nls,j)
v = v + vaut.ind
end
say " valeur : " format(v,5)
call lineout sorint , v
end
end /* } do while lines(fichprod)*/
if declenche = 0 then do
say
say " Plus aucune règle ne s'applique... abandon avec complétion."
if ( etapf = "OUI" ) & ( etape < nef ) & ( interp = "INT" ) then do k = etape to nef
call lineout sorint , v
end
call lineout sorint
call GNUPLOT
exit
end
call lineout fichsor
call lineout fichprod
"cp " fichsor fichprod
call lineout fichprod
/* copy fichsor fichprod '> nul' */
/* relance éventuelle */
if etapf \= "OUI" & nowait \= "OUI" then do
say
call charout , copies(" ",55) " fin de l'étape "
pull rep
if length(rep) > 0 then live = "oui"
end ; else if etape = nef then leave
if live = "oui" then leave
end /* forever */
/* # 4.0 Affichage des statistiques */
if nostat \= "OUI" then do
say
say " Comptage des Productions : sur " etape " étape(s) "
say ; call charout , "Prod nø"
taillesor = 5
do i = 1 to np
call charout , format(i,taillesor)
end /* i = 1 to np */
say ; say ; call charout , " "
do ie = 1 to etape
do i = 1 to np
call charout , format(p.n.i.ie,taillesor)
/* if ie = 20 then do
call charout , " Enter pour continuer "
pull .
end /* if (ie == 20 ) */
*/
end /* do i = 1 to np */
call charout , " (étape " format(ie,2) ") total "
say format(tot.ie,taillesor)
call charout , " "
end /* if ie = 1 to etape */
say
call charout , " Total "
do i = 1 to np
call charout , format(p.n.i,taillesor)
end
call lineout sorint
say
end
/* # 5.0 Fabrication d'un fichier utilisable par gnuplot */
GNUPLOT :
if gnuplt = "GPL" then do
txt = "plot '"sorint"' with linespoints"
call lineout sorgpl,txt
call lineout sorgpl
'gpl' nomf
say
say " Pour revoir le graphique tapez : gpl "nomf
say " OU : gnuplot "sorgpl
end /* if gnuplot = "GPL" */
exit
error:
failure:
halt:
syntax:
say
say " déroutement volontaire, ligne " Sigl
do tag = 1 to 5
vtag = sigl-3+tag
say "("vtag") " sourceline(vtag)
end
trace '?i'
say " donc..."
exit