BEE(Boolean Expression Evaluator) permet d'évaluer des expressions booléennes.
Les opérateurs et symboles prédéfinis sont :
0 : faux
1 : vrai
& : opérateur et
| : opérateur ou
! : opérateur non
( : parenthèse gauche
) : parenthèse droite
Il est cependant possible de spécifier ses propres valeurs.
Des variables peuvent de plus être utilisées dans les expressions.
Les erreurs (de syntaxe, de parenthésage, de variable indéfinie) sont gérées et peuvent être récupérées en utilisant un bloc try catch autour de l'appel de la méthode eval (voir l'exemple "simple").
Il est possible de connaître la description de l'erreur et la position du caractère fautif dans l'expression normalisée.
Le code est commenté et documenté (la documentation est déjà générée et le fichier Doxyfile est fourni).
Deux exemples sont fournis avec le code :
- simple : permet d'évaluer des expressions booléenne avec variables et possibilité de choisir ses opérateurs.
- table : permet de générer la table de vérité d'une expression booléenne. (c'est celui qui est affiché ci-dessous)
Attention, le zip et le code fournis sur cette page ne sont pas forcément à jour ! Pour voir les dernières sources, rendez-vous ici :
https://bitbucket.org/mcc/dev/src/tip/BEE/
Source / Exemple :
#include "../../src/BEE.hpp"
#include <iomanip>
#include <cmath>
int main(int argc, char** argv) {
if(argc == 1) {
std::cerr << "Usage : " << argv[0] << " expression booleenne"
<< std::endl;
return 1;
}
try {
BEE bee(argv[1]);
std::vector<std::string> vars = bee.vars();
//Affichage de l'entête.
for(unsigned int i = 0; i < vars.size(); i++) {
std::cout << vars[i] << " ";
}
std::cout << argv[1] << std::endl;
//On doit trouver toutes les valeurs possibles pour toutes les
//variables. Ca revient à convertir en binaire les nombres de 0 à
//2 ^ nbVars. On prend ensuite chaque bit de ces nombres et on assigne
//chacun d'eux à la variable associée.
int nbVars = vars.size();
int sizeType = 4 * sizeof(int);
int nbLines = pow(2, nbVars);
int maxType = pow(2, sizeType - 1);
for(int l = 0; l < nbLines; l++) {
//On se décale jusqu'aux bits utiles.
int t = l << (sizeType - nbVars);
//On affiche les bits.
for(int i = 0; i < nbVars; i++) {
bool valBit = t & maxType;
bee.setVar(vars[i], valBit);
t <<= 1;
std::cout << valBit << std::setw(vars[i].length() + 1);
}
//On évalue l'expression avec les nouvelles valeurs.
bool res = bee.eval();
std::cout << res << std::endl;
}
} catch(BEE::Error err) {
std::cout << std::endl;
std::cout << err.src() << std::endl;
std::cout << std::setw(err.ind() + 1) << "^" << std::endl;
std::cout << std::setw(err.ind() + err.desc().length()) << err.desc()
<< std::endl;
}
return 0;
}
Conclusion :
Cette source peut être utile notamment pour savoir comment convertir une expression (booléenne ou non) en notation polonaise inversée. (l'algorithme n'est pas entièrement de moi, sa structure provient d'une page Wikipédia mentionnée au dessus de la fonction concernée).
Il existe peut-être des bugs, si c'est le cas, merci de me les indiquer.
20 juil. 2011 à 14:27
cas ++i:
add i, 1
cmp i, n
jge LABEL
cas i++:
cmp i, n
jge LBEL
add i, 1
Il n'y a fort heureusement pas besoin de recopie ni rien d'autre.
15 juil. 2011 à 15:10
12 juil. 2011 à 15:52
12 juil. 2011 à 11:45
J'aurai juste une remarque : meme si ++i est plus rapide que i++, je suis pratiquement sur que tous les compilateurs modernes un peu serieux sont capables d'optimiser ca tout seul, surtout si il n'y a rien autour (si tu vas par la, pourquoi ne pas declarer la variable en "register" :o) (c'est une blague, ne le faites pas ;o) )).
Et puis je crois que ton "pseudo code equivalent" devrait plutot etre : {itTmp it; it it + 1; return itTmp; }
Pour le xor, effectivement c'est un peu un outil de base.
Si tu veux faire un truc un peu plus marrant a coder, tu peux essayer d'implementer un DEFFN (definition de fonctions utilisateur) et modifier ton code pour charger un fichier d'initialisation au demarrage de ton parseur.
J'avais fait ca lors d'un de mes premier projets scolaires (et eu une bonne note pour l'originalite :o) ).
En gros, on devait coder une calculatrice scientifique avec plein de fonctions sin, cos, tan, etc.
Au lieu de tout coder en C, j'avais uniquement fait sin(x), puis dans mon fichier d'initialisation j'avais des trucs genre :
DEFFN cos(x)=sin(x+pi/2)
DEFFN tan(x)=sin(x)/cos(x)
Enfin, tu vois le genre. Avec ca, tu peux rajouter simplement les XOR, NAND, NOR, etc... a ton parseur.
Eric
10 juil. 2011 à 17:36
Pour le XOR, il est vrai que j'aurais pu le mettre, mais il me semble que ce n'est pas un opérateur "de base" au sens où il peut être construit à partir des trois autres (!, &, |). Mais c'est vrai que ça pourrait simplifier de le mettre.
Pour ce qui est de la gestion des tokens, c'est vrai que c'est pas top.
Pour ce qui est le l'indice de la classe Error, je vois pas trop comment je pourrais retrouver le bon indice, mais je vais chercher.
Sinon, il faudra en effet que je regarde un peu ce que donne la méthode AST, ça peut être intéressant pour aller encore plus loin.
Voilà je vais voir ça et le reste prochainement !
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.