Documente Academic
Documente Profesional
Documente Cultură
Évaluation d’expressions
Luc Brun
luc.brun@greyc.ensicaen.fr
NB : On ne fait pas intervenir de constantes ou de fonctions (petite
simplification).
L’évaluation d’une expression implique la définition d’un environnement
(affectation de chaque variable à une valeur).
opérateurs logiques
Opérateurs unaires
opérateurs arithmétiques
NB : , .
opérateurs logiques
#
#
!
"
"
3. si est une ECP et un opérateur unaire alors est une ECP,
!
$
!
4. Il n’y a pas d’autre ECP que celles formées par les 3 règles précédentes.
%
( optun ecp ) |
variable
optbin &
&
&
&
&
&
&
&
&
&
&
%
optun
&
&
variable
&
&
&
&'
(
1. une variable est une EPRE,
2. si et sont des EPRE et un opérateur binaire alors est une EPRE,
#
!
"
!
"
3. Si est une EPRE et un opérateur unaire, alors est une EPRE,
!
$
!
4. il n’y a pas d’autres EPRE que celles formées à partir des règles
)
précédentes.
%
optun epre |
variable
optbin &
&
&
&
&
&
&
&
&
&
&
%
optun
&
&
variable
&
&
&
&'
non = + A B C (non ((A+B)=C))
Expressions incorrectes
A-+BC
non B C
#
!
"
!
"
EPOST,
3. Si est une EPOST et un opérateur unaire, alors est une EPOST,
!
$
4. il n’y a pas d’autres EPOST que celles formées à partir des règles
)
précédentes.
%
epost optun |
variable
optbin &
&
&
&
&
&
&
&
&
&
&
%
optun
&
&
variable
&
&
&
&'
*
1. Priorité des opérateurs
+
2. Priorité à gauche pour les opérateurs de même priorité
+
Les parenthèses imposent des priorités
+
Évaluation d’expressions – p.14/38
Priorité des opérateurs
Opérateur Priorité
( 0
1
ou, +, - 2
et, *, / 3
, non 4
,
!-.
%
esimple terme op2 terme
%
terme facteur op3 facteur
%
facteur variable |
%
op4 facteur |
( einf )
op1
&
&
&
&
&
%
op2
&
&
op3
&
&
%
op4
&
&
variable
&
&
&
&'
"
evaluation(S) = opération( ,
#
si variable(x) alors valeur(x) sinon evaluation(x),
si variable(y) alors valeur(y) sinon evaluation(y))
(
*
)
evaluation(S) = opération(+,A,évaluation(B*C))
= opération(+,A,opération(*,B,C))
= opération(+,2,opération(*,3,4))
= opération(+,2,12)
= 14
3
2 6
2
pile vide empiler A empiler B evaluer *
AB*CD+/# B*CD+/# A *CD+/# AB CD+/#
0
0
1
2 3
2 2
6 6
6
empiler C empiler D évaluer + evaluer /
AB* D+/# AB*C +/# AB*CD /# AB*CD+ #
0
1
position dans la chaî ne.
Si epost[i]=’#’ : l’évaluation est terminé. Résultat en sommet de pile.
Si epost[i] ’#’
2
Déclaration i :Entier,valG,valD :Réel,p : Pile
début
p creer() sinon
3
i 1 valD dépiler(p)
3
3
tant que epost[i] ’#’ faire valG dépiler(p)
3
si variable(epost[i]) alors valD
3
empiler(epost[i],p) oper2(valG,epost[i],valD)
sinon empiler(valD,p)
si unaire(epost[i]) alors finsi
valD dépiler(p) finsi
3
3
fintantque
empiler(valD,p) retourner sommet(p)
Évaluation d’expressions – p.23/38
Évaluation d’ECP
Utilisation d’une pile à travers trois types d’actions :
1. Si le symbole lu est un opérateur : on l’empile
2. si c’est une variable : on empile sa valeur,
3. Si c’est une parenthèse droite : on dépile une sous expression et on empile
le résultat.
3
* *
2 *
2 2
2
( *(B+C))# (A (B+C))# (A* B+C))# (A*( +C))#
0
0
0
1
+
+ 4
3
3 * 8
*
* 2
2
2
(A*(B C))# (A*(B+ ))# (A*(B+C )# (A*(B+C) #
0
Évaluation d’ECP : l’algorithme
fonction evalEcp (ecp : Tableau[ ] deCaratère ) : Réel
2
Déclaration i :Entier,op :Caratère,valG,valD :Réel,p : Pile
début
p creer() valD dépiler(p)
3
3
i 1 op dépiler(p)
3
3
tant que ecp[i] ’#’ faire si unaire(op) alors
3
finsi emp.(op2(valG,op,valD),p)
si operateur(ecp[i]) alors finsi
empiler(ecp[i],p) finsi
continuer i i+1
3
finsi fintantque
si ecp[i]=’)’ alors retourner sommet(p) Évaluation d’expressions – p.26/38
Conversion ECP à EPOST
ECP lisibles, tapé par exemple dans un code source,
EPOST directement interprétable par une machine.
Nécessité de convertir.
Remarque : Lors de la lecture d’une ECP on rencontre les opérandes dans le
même ordre que dans l’EPOST. Seul l’opérateur est placé à la fin.
%
Idée : Empiler les opérateurs et les dépiler sur les parenthèses fermantes.
Opérateur : empiler,
variable : écrire dans chaî ne résultat.
parenthèse fermante : dépiler un opérateur
parenthèse ouvrante : ne rien faire.
* * *
A A A AB
( *(B+C))# (A (B+C))# (A* B+C))# (A*( +C))#
0
0
+ + 0
*
* *
AB ABC ABC+ ABC+*
(A*(B C))# (A*(B+ ))# (A*(B+C )# (A*(B+C) #
0
0
0
Évaluation d’expressions – p.28/38
Conversion ECP à EPOST : l’algorithme
procédure convEcpEpost ( E ecp : Tableau[ ] deCaratère , S
2
epost : Tableau[ ] deCaratère )
2
Déclaration indecp,indepost :Entier,p : Pile
début
p creer() indepost indepost+1
3
3
indecp 1 continuer
3
indepost 1 finsi
3
3
empiler(ecp[i],p) indepost indepost+1
3
continuer finsi
finsi indecp indecp+1
3
si variable(ecp[i]) alors fintantque
epost[indepost] ecp[indecp] epost[indepost] #
3
3
fin
Évaluation d’expressions – p.29/38
Conversion ECP/EPOST : Amélioration
Détection d’erreurs de syntaxe dans l’ECP.
La pile ne doit pas être vide avant la fin (trop de parenthèses fermantes) et
vide à la fin (pas assez).
Un caractère d’ECP est soit :
un opérateur,
une variable,
une parenthèse fermante,
une parenthèse ouvrante.
* * +
A A AB A B*
*B+C/(D+E)# A B+C/(D+E)# A* +C/(D+E)# A*B C/(D+E)#
0
0
( (
/
+ / /
+
+ +
A B *C A B *C A B* C + A B* C D
A*B+ /(D+E)# A*B+C (D+E)# A*B+C/ D+E)# A*B+C/( +E)#
0
0
+ +
(
( (
/
/ /
+
+ +
A B *C D A B *C D A B* C D E
A*B+C/( +E)# A*B+C/(D E)# A*B+C/(D+ )#
4
0
0
0
/
+
A B* C D E + A B* C D E + / +
A*B+C/(D+E # A*B+C/(D+E)#
2
deCaratère E/S p : Pile,indpost : Naturel )
Déclaration dépil : Booléen,élément : Caratère
début
dépil non vide(p)
3
élément depiler(p)
3
epost[indpost] élément
3
indpost indpost+1
3
sinon
dépil faux
3
finsi
fintantque
empiler(op) Évaluation d’expressions – p.35/38
Rencontre d’une parenthèse fermante
procédure traiterPF ( S epost : Tableau[ ] deCaratère , E/S
2
indpost : Naturel,p : Pile )
Déclaration élément : Caratère
début
élément dépiler(p)
3
epost[indpost] élément
3
indpost indpost+1
3
élément depiler(p)
3
fintantque
fin
2
indpost : Naturel,p : Pile )
Déclaration élément : Caratère
début
tant que non vide(p) faire
epost[indpost] depiler(p)
3
indpost indpost+1
3
fintantque
epost[indpost] ’#’
3
fin
2
epost : Tableau[ ] deCaratère )
2
Déclaration indinf,indpost :Entier,p : Pile
début
p creer() indpost indpost+1
3
3
indinf 1 continuer
3
indpost 1 finsi
3
3
si variable(einf[indinf]) alors fintantque
epost[indpost] einf[indinf] traiterFin(epost,indpost,p)
3