EVALUER UNE EXPRESSION À PARTIR D'UNE CHAINE DE CARACTÈRE

cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 - 12 juin 2009 à 09:32
janhsh Messages postés 6 Date d'inscription samedi 10 octobre 2009 Statut Membre Dernière intervention 21 février 2019 - 13 mars 2017 à 22:39
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/50144-evaluer-une-expression-a-partir-d-une-chaine-de-caractere

janhsh Messages postés 6 Date d'inscription samedi 10 octobre 2009 Statut Membre Dernière intervention 21 février 2019
13 mars 2017 à 22:39
Un bel exercice, mais le code n'est pas re-entrant
En pratique on utilise un compilateur de compilateur genre LEX et YACC (ou BISON) ou ANTLR

va voir sur http://www.linux-france.org/article/devl/lexyacc/minimanlexyacc-4.html pour un exemple

On doit créer un fichier de syntaxe et un fichier de définition et le compilateur génère le code source. Il existe une version de Lex et de Yacc pour PHP ou de ou de ANTLR pour PHP https://github.com/beberlei/antlr-php-runtime
amezghal Messages postés 385 Date d'inscription lundi 27 février 2006 Statut Membre Dernière intervention 21 août 2015 5
23 juin 2009 à 13:26
L'arbre binaire c'est la méthode la plus viable.
Il y a déjà une source ici qui exploite cette méthode,
zorteil07 Messages postés 3 Date d'inscription jeudi 29 novembre 2007 Statut Membre Dernière intervention 20 juin 2009
20 juin 2009 à 18:44
correction pour le tableau $tabSignes, j'avais oublié une valeur (ce que c'est de ne pas tester!)
le bon code:
$tabSignes=array("=","<>","&&","||","<",">","+","-","%","/","^","&","*","|");
zorteil07 Messages postés 3 Date d'inscription jeudi 29 novembre 2007 Statut Membre Dernière intervention 20 juin 2009
20 juin 2009 à 17:16
à la place de
$tabSignes=array();
$tabSignes[0]="=";
$tabSignes[1]="<>";
$tabSignes[2]="&&";
$tabSignes[3]="||";
$tabSignes[4]="<";
$tabSignes[5]=">";
$tabSignes[6]="+";
$tabSignes[7]="-";
$tabSignes[8]="%";
$tabSignes[9]="/";
$tabSignes[10]="^";
$tabSignes[11]="&";
$tabSignes[12]="*";

perso, je mettrai:
$tabSignes=array("=","<>","&&","||","<",">","+","-","%","/","^","&","*");
on s'est évité n fois de rentrer au clavier
$tabSignes[n]="une valeur";

pour un tableau multi dimensionné:
$Montab = array(
"Champ0"=>"valeur0",
"Champ1"=>"valeur1",
"ChampN=>"valeurN"
);

je ne sais pas s'il y a une différence de rapidité d'exécution entre
if($var=="quelque chose")
ou
if($var==="quelque chose")
par contre l'instruction de comparaison == vérifie l'égalité mais ne vérifie pas le type des variables
alors que === vérifie que les deux termes de la condition sont strictement identiques et de même type.
exemple:
$var = 0;
if($var == '0') renvoie true // c'est nul, c'est tout.
if($var==='0') renvoie false // le nombre zéro n'est pas identique au caractère zéro

Dans l'évaluation de chaînes, ça peut avoir son importance.

autre exemple de l'intérêt des comparateurs stricts

$myvar = '0'; // variable avec une valeur non nulle affectée
if(!empty($myvar)) {
// faire ceci
}
else {
// faire cela
}
c'est "faire cela" qui va s'exécuter alors que je considère pour ma part que c'est "faire ceci" qui devrait s'exécuter;

avec les comparateurs stricts il n'y a pas de confusion possible:
if($myvar !==NULL) // si une valeur quelconque affectée
echo" faire ceci";
}
else {
echo "faire cela";
}
TheWeasel47 Messages postés 39 Date d'inscription mercredi 19 mars 2008 Statut Membre Dernière intervention 25 août 2009
20 juin 2009 à 12:37
Je vais répondre rapidement par faute de temps !

Alors pour la première condition! En fait il s'agit d'un exercice de style c'est donc au développeur de changer cette valeur !

Tu parles d'une manière moins fastidieuse de remplir un tableau ? je suis prenneur de toute nouvelle méthode !!!
Tu soulèves une intérrogation le est plus rapide que le simple ???

Merci de tes remarques.
Bien Cordialement
zorteil07 Messages postés 3 Date d'inscription jeudi 29 novembre 2007 Statut Membre Dernière intervention 20 juin 2009
20 juin 2009 à 12:31
étant donné le code (dans index.php)
$Using_Eval=true;
if(!$Using_Eval){
include("Class_Evaluer.php");
}else{
include("Class_EvaluerB.php");
}

peut-on dire au développeur ignare que je suis, dans quelle circonstance le fichier Class_Evaluer.php sera-t-il inclus?

Il est vrai par ailleurs (commentaire de GRENARD) qu'il y a une façon moins fastidieuse de définir le contenu des variables de type array.

Pour le reste, ne comprenant pas déjà pourquoi on fait un test sur la valeur d'une variable qu'on vient juste d'instancier (comment pourrait-elle valoir autre chose que la valeur donnée?) et pourquoi on a joint au package un fichier qui de mon humble avis ne sera jamais exécuté, je n'ai de ce fait pas d'avis sur la pertinence des algoryhtmes.

Si, une petite suggestion cependant: ne serait-il pas indiqué avant toute évaluation de débarasser les chaînes évaluées des caractères espaces superflus?

L'idée me paraît très bonne, et bien sûr libre à chacun de compléter en créant un formulaire dans lequel on entrera la chaîne à évaluer. Mais je reste un peu perplexe sur le code des classes: mériterait une étude approfondie.... des petites choses comme ça qui me chagrinent. juste des impressions, sans fondement?

Dans les boucles if (condition) { ...}
la condition ($var == "une_certaine_valeur")
gagnerait à être remplacée par ($var === "une_certaine_valeur")
vu qu'on travaille sur des caractères alphanumériques qui seront interprétés par le navigateur, dans la suite logique de ce script qui est d'adjoindre un formulaire de saisie de la chaîne à évaluer. Bien entendu pour un formulaire en ligne sur un site public, va falloir sécuriser contre le XSS.
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
12 juin 2009 à 17:26
Oui pour mon PHP.ini...
il faut toujours déveloper ses applications de sorte que ça fonctionne sur tous les autres ordinateurs.

Donc pour ce faire, tu dois activer :
display_error = On
error_reporting = E_ALL
asp_short_tag something = off... par défaut dans les nouvelles versions de PHP, tous les settings sont corrects à l'exception des deux premiers que je viens de mentionner...

Tu verras pour le parser et compiler, il y a beaucoup de connaissance à apprendre, c'est pas en 1 journée que tu vas coder tout ça :)
TheWeasel47 Messages postés 39 Date d'inscription mercredi 19 mars 2008 Statut Membre Dernière intervention 25 août 2009
12 juin 2009 à 10:43
Excellente idée pour les +5 5*-5 je vais essayer de coder ça !
et de fixer le bug du undefined offset :D mais pour obtenir ce bug as tu une configuration d'affichage des erreurs particulière dans ton php.ini ou bien ce bug se produit sur certaines chaine ?

Quand au parser et au compiler.... je vais voir ce que je peux faire !
Merci de ta remarque en tout cas
Cordialement
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
12 juin 2009 à 09:32
C'est vraiment interessant :) Je me souviens de ça dans mes cours d'université qu'on devait coder.
On devait par contre faire plus de classe qu'une seule. Personnellement, je ne crois pas que tu es la bonne technique pour effectuer ce genre d'opération. Je crois qu'il faut plutôt une grammaire, un parser et un compiler. Fait des recherches sur "math, parser, compiler, technique," etc.
Mais étant donné que tu dis que c'est un exercice de style... je ne sais pas trop quoi te dire. C'est quand même un bon début pour analyser les chaînes simples.

Un des problème est que c'est que je reçois une dizaine de "Notice: Undefined offset". Il serait bien de fixer cela :)

Il y a beaucoup de répétition dans ton code... La variable
$tabSignes semble vraiment être similaire à 2 places.
et Opération ne prend qu'un P :)

Il faudrait aussi supporter les chaînes suivantes:
+5
5*-5

Bonne chance.