 |
Evaluateur
d'expressions
|
Page d'accueil
Thèmes d'activités
<< Thème précédent
Thème suivant >>
On se propose dans
cette feuille de calcul d'évaluer une expression mathématique donnée sous
forme de chaîne de caractères.
Les éléments
constitutifs d'une expression mathématique sont:
- les
opérateurs
: ce sont
les symboles des quatre opérations élémentaires "+", "-", "*", "/", le
symbole de la puissance "^" et le symbole "+-" désignant l'opérateur unaire de
changement de signe.
- les
séparateurs
: ce sont
les opérateurs auxquels on adjoint les symboles : "," (virgule) , "("
(parenthèse ouvrante) et ")" (parenthèse fermante).
- les
fonctions prédéfinies
: à une variable (Functions1) comme "abs" ou "trunc", ou
à deux variables (Functions2) comme "min" ou "max". On pourrait en rajouter
d'autres si besoin est.
> |
Operators:={"+","-","*","/","^"}; Separators:=Operators union {",", "(",
")"};
Functions1:={"abs","sqrt","ln","exp","sin","cos","tan","ceil","trunc","floor"};
Functions2:={"min","max"}; Functions:=Functions1 union Functions2;
|
- les
fonctions-utilisateur
: définies par l'utilisateur, à une variable
(UserFunctions1) comme ici "ch" ou à deux variables (UserFunctions2) comme
ici "logbase".
La priorité des opérateurs est
donnée par la table Prec (
order of precedence
en anglais). De la moins prioritaire (1 pour "+" ou
"-") à la plus prioritaire (3 pour "^" ou "+-").
Les fonctions ont aussi une
priorité 3.
L'associativité gauche, droite
des opérateurs est donnée par la table Assoc (valeur
left
ou
right
). "+-" n'est pas
concernée (valeur
no
) .
La procédure
RemoveChar
(
c
:: string,
s
:: string) donne
pour résultat la chaîne de caractères obtenue en supprimant le caractère
c
de la chaîne de
caractères
s
.
La procédure
GetInteger
(
s
:: string,
n
:: nonnegint)
retourne la valeur de l'entier obtenue à partir de la position
n
dans la chaîne de
caractères s.
Le format scientifique, par exemple ici 012345.67E-04 sera reconnu: on
obtient le résultat 12345.
La procédure
GetNumber
(
s
:: string,
n
:: nonnegint)
retourne une séquence de la forme
chaine
,
valeur
obtenue à partir de la position
n
dans la chaîne de
caractères s.
Par exemple ici à partir de la position 1, on obtient:
.
La procédure
GetIdentifier
(
s
:: string,
n
:: nonnegint)
retourne une chaîne de caractères de type
identificateur
(de fonction ou de variable)
obtenue à partir de la position
n
dans la chaîne de caractères s.
Un
identificateur
commence par une lettre, suivie de lettres ou de
chiffres (comme par exemple ici "abc1").
Procédures retournant l'index
du nom d'une fonction dans leur table respective (si le nom n'est pas présent
dans la table, le résultat est 0):
La procédure
PushBinaryOperator
(
c
,
t1
,
t2
) place au sommet de la pile
st
le résultat de
l'opérateur binaire
c
sur
t1
et
t2
:
La procédure
PushUnaryOperator
(
c
,
t
) place au sommet de la pile
st
le résultat de
l'opérateur unaire
c
sur
t
:
La procédure
PushOpd
(
nb
) place au sommet de la pile
st
l'opérande
nb
:
Procédures plaçant au
sommet de la pile
st
le résultat d'une fonction (
n
désigne l'index du
nom de la fonction dans sa table respective ).
La fonction peut avoir une
variable
t
ou deux variables
t1
,
t2
:
Procédures
d'évaluation des expressions (certaines sont récursives):
> |
Funct2:=proc(s::string, n::posint, user::truefalse)
global indx,st;
local top1,top2;
indx:=indx+1:
if s[indx]<>"(" then error "( expected at position " || indx else
Expression(s):
top1:=stack[top](st):
if s[indx+1]<>"," then error ", expected at position " || indx else
indx:=indx+1:
Expression(s):
top2:=stack[top](st): indx:=indx+1:
if s[indx]<>")" then error ") expected at position " || indx end if;
stack[pop](st): stack[pop](st):
if user then PushUserFunction2(n,top1,top2) else
PushFunction2(n,top1,top2) end if
end if
end if
end proc:
|
> |
Fact:=proc(s::string)
global indx;
local id,f1,f2;
indx:=indx+1:
if IsAlpha(s[indx]) then
id:=GetIdentifier(s,indx):
f1:=GetFunction1(id):
if f1>0 then Funct1(s,f1,false)
else
f2:=GetFunction2(id):
if f2>0 then Funct2(s,f2,false) else
f1:=GetUserFunction1(id):
if f1>0 then Funct1(s,f1,true) else
f2:=GetUserFunction2(id):
if f2>0 then Funct2(s,f2,true) else PushOpd(id) end if;
end if
end if
end if;
elif IsDigit(s[indx]) then
PushOpd(GetNumber(s,indx))
else
if s[indx]="(" then
Expression(s):
indx:=indx+1:
if s[indx]<>")" then error ") expected at position " || indx end if;
else error "missing operand or syntax error at position " || indx end if;
end if
end proc:
|
Error, (in
ExpressionAnalyzer) nothing to parse
Un exemple de calcul formel:
Exemple avec des
fonctions-utilisateurs:

|
haut de cette page
|
©
- Alain Le Stang - Navigation optimisée pour une résolution 1024 x 768.
|