Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

PARSER (CALCULETTE....)


Information sur la source

Catégorie :Maths & Algorithmes Niveau : Initié Date de création : 11/09/2004 Date de mise à jour : 20/01/2005 22:56:15 Vu : 2 934

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (20)
Ajouter un commentaire et/ou une note


Description

c'est bon j'en ai fait un objet!!!! et je lui ai pas trouver de bug......
c'est un objet qui permet d'interpreter des formules mathematique en faisant
attention  au priorite, il est tres facile d'y ajouter de nouvelles fonctions.....
 

Source

  • /*Fichier bparser.c*/
  • #ifndef __WINDOWS_H
  • #include<windows.h>
  • #endif
  • #include<math.h>
  • #include "bparser.hpp"
  • #define OPU (OPUD|OPUG)
  • enum CErreur{SYMB=0,MEM,BADTYPE,ARG,OVFLOW};
  • TParser ADD(TParser arg[]);
  • TParser SUB(TParser arg[]);
  • TParser MUL(TParser arg[]);
  • TParser DIV(TParser arg[]);
  • TParser MOD(TParser arg[]);
  • TParser POW(TParser arg[]);
  • TParser SIN(TParser arg[]);
  • TParser COS(TParser arg[]);
  • TParser TAN(TParser arg[]);
  • TParser FACT(TParser arg[]);
  • TParser SQRT(TParser arg[]);
  • TParser NEG(TParser arg[]);
  • TParser EXP(TParser arg[]);
  • TParser LN(TParser arg[]);
  • TParser LOG(TParser arg[]);
  • TParser AND(TParser arg[]);
  • TParser OR(TParser arg[]);
  • TParser NOT(TParser arg[]);
  • TParser ROUND(TParser arg[]);
  • char *TErreur[5]= {
  • "Symbole inconnu",
  • "Probleme memoire!",
  • "Autre type attendu",
  • "Trop ou pas assez d'arguments",
  • "Depassement de capacitee"
  • };
  • int TParser::nbop=19;
  • operateur TParser::op[19]={
  • "+",(TParser (*)(TParser *))ADD,{OPB,11},
  • "-",(TParser (*)(TParser *))SUB,{OPB|OPUG,11},
  • "*",(TParser (*)(TParser *))MUL,{OPB,12},
  • "/",(TParser (*)(TParser *))DIV,{OPB,12},
  • ".-",(TParser(*)(TParser *))NEG,{OPUG,15},
  • "%",(TParser (*)(TParser *))MOD,{OPB,12},
  • "^",(TParser (*)(TParser *))POW,{OPB,13},
  • "!",(TParser (*)(TParser *))FACT,{OPUD,15},
  • "&",(TParser (*)(TParser *))AND,{OPB,12},
  • "|",(TParser (*)(TParser *))OR,{OPB,11},
  • "~",(TParser (*)(TParser *))NOT,{OPUG,15},
  • "sin",(TParser(*)(TParser *))SIN,{FONC,1},
  • "cos",(TParser(*)(TParser *))COS,{FONC,1},
  • "tan",(TParser(*)(TParser *))TAN,{FONC,1},
  • "sqrt",(TParser(*)(TParser *))SQRT,{FONC,1},
  • "exp",(TParser(*)(TParser *))EXP,{FONC,1},
  • "ln",(TParser(*)(TParser *))LN,{FONC,1},
  • "log",(TParser(*)(TParser *))LOG,{FONC,1},
  • "round",(TParser(*)(TParser *))ROUND,{FONC,1}
  • };
  • int TParser::nbvar=6;
  • variable TParser::var[6]= {
  • "x",NBR|VAR,0.0,
  • "y",NBR|VAR,0.0,
  • "z",NBR|VAR,0.0,
  • "t",NBR|VAR,0.0,
  • "ans",NBR|VAR,0.0,
  • "pi",NBR,M_PI//3.1415927,
  • };
  • TParser::TParser()
  • {type=VIDE;}
  • TParser::~TParser()
  • {FreeExpression();}
  • TParser TParser::Calcul()
  • {
  • TParser res=*this;
  • res.CalculExpression();
  • var[4].type=res.type|VAR; /*Met le resultat dans la*/
  • var[4].donnee=res.nombre; /*variable "ans"*/
  • return res;
  • }
  • void TParser::CalculExpression()
  • {
  • TParser arg[2],*texp;
  • noeud *cour;
  • feuille *pfeuille;
  • int nbarg;
  • ParserExcept err;
  • switch(type)
  • {
  • case VAR:
  • type=var[nombre.var].type&(~VAR);
  • nombre=var[nombre.var].donnee;
  • break;
  • case PNOEUD:
  • cour=nombre.pnoeud;
  • arg[0]=cour->nbG;
  • arg[0].CalculExpression();
  • arg[1]=cour->nbD;
  • arg[1].CalculExpression();
  • *this=op[cour->indexop].f(arg);
  • break;
  • case FONC:
  • pfeuille=nombre.pfeuille;
  • nbarg=op[pfeuille->indexfonc].info.priorite;
  • if((texp=new TParser[nbarg])==NULL)
  • {
  • err.code=MEM;
  • throw(err);
  • }
  • while(nbarg--)
  • {
  • texp[nbarg]=pfeuille->arg[nbarg];
  • texp[nbarg].CalculExpression();
  • }
  • *this=op[pfeuille->indexfonc].f(texp);
  • delete[] texp;
  • break;
  • case OPU:
  • pfeuille=nombre.pfeuille;
  • arg[0]=pfeuille->arg[0];
  • arg[0].CalculExpression();
  • *this=op[pfeuille->indexfonc].f(&arg[0]);
  • break;
  • }
  • nbarg=0;
  • }
  • void TParser::CreeArbre(char phrase[],lexeme *lex)
  • {
  • char ctemp;
  • lexeme *lcourant,*sauv;
  • int priorite,temp,nbarg,poscourant;
  • priorite=16;
  • lcourant=lex;
  • /*Cherche l'operateur binaire ayant la plus petite priorite*/
  • while(lcourant->type!=FIN)
  • {
  • if(lcourant->type&OPB)
  • {
  • temp=op[lcourant->index].info.priorite;
  • if(temp<=priorite)
  • {
  • sauv=lcourant;
  • priorite=temp;
  • }
  • }
  • lcourant=lcourant->suivant;
  • }
  • /*Si il y a un OPB alors on remplit sinon il ni a plus
  • d'operateur binaire et donc c'est une TParser*/
  • if(!(priorite&16))
  • {
  • type=PNOEUD;
  • if((nombre.pnoeud=new noeud)!=NULL)
  • {
  • /*Coupe en 2 la chaine de lexeme*/
  • /*La partie a gauche de l'OPB et la droite*/
  • sauv->type=FIN;
  • lcourant=sauv->suivant;
  • lcourant->avant=sauv->suivant=NULL;
  • nombre.pnoeud->indexop=sauv->index;
  • nombre.pnoeud->nbG.CreeArbre(phrase,lex);
  • nombre.pnoeud->nbD.CreeArbre(phrase,lcourant);
  • /*Retabli les information dans la chaine de lexeme*/
  • sauv->type=OPB;
  • sauv->suivant=lcourant;
  • lcourant->avant=sauv;
  • }
  • }
  • else
  • {
  • lcourant=lex;
  • switch(lcourant->type)
  • {
  • case BIN:
  • ctemp=phrase[lcourant->lignefin+1];
  • phrase[lcourant->lignefin+1]='\0';
  • type=NBE;
  • nombre.sint=BinToInt(phrase+lcourant->lignedeb);
  • phrase[lcourant->lignefin+1]=ctemp;
  • break;
  • case HEX:
  • ctemp=phrase[lcourant->lignefin+1];
  • phrase[lcourant->lignefin+1]='\0';
  • type=NBE;
  • nombre.sint=HexToInt(phrase+lcourant->lignedeb);
  • phrase[lcourant->lignefin+1]=ctemp;
  • break;
  • case NBR:
  • ctemp=phrase[lcourant->lignefin+1];
  • phrase[lcourant->lignefin+1]='\0';
  • type=NBR;
  • nombre.freel=atof(phrase+lcourant->lignedeb);
  • phrase[lcourant->lignefin+1]=ctemp;
  • break;
  • case NBE:
  • ctemp=phrase[lcourant->lignefin+1];
  • phrase[lcourant->lignefin+1]='\0';
  • type=NBE;
  • nombre.sint=atoi(phrase+lcourant->lignedeb);
  • phrase[lcourant->lignefin+1]=ctemp;
  • break;
  • case CONSTE:
  • type=var[lcourant->index].type;
  • nombre.freel=var[lcourant->index].donnee.freel;
  • break;
  • case VAR:
  • type=VAR;
  • nombre.var=lcourant->index;
  • break;
  • case FONC:
  • type=FONC;
  • nombre.pfeuille=new feuille;
  • nombre.pfeuille->indexfonc=lcourant->index;
  • nbarg=op[lcourant->index].info.priorite;
  • nombre.pfeuille->arg=new TParser[nbarg];
  • temp=poscourant=lcourant->suivant->lignedeb+1;
  • priorite=0;
  • while(--nbarg)
  • {
  • while(phrase[temp]!=',')temp++;
  • phrase[temp]='\0';
  • nombre.pfeuille->arg[priorite].Parse(phrase+poscourant);
  • phrase[temp]=',';
  • poscourant=++temp;
  • priorite++;
  • }
  • temp=lcourant->suivant->lignefin;
  • ctemp=phrase[temp];
  • phrase[temp]='\0';
  • nombre.pfeuille->arg[priorite].Parse(phrase+poscourant);
  • phrase[temp]=ctemp;
  • break;
  • case OPUG:
  • type=OPU;
  • nombre.pfeuille=new feuille;
  • nombre.pfeuille->indexfonc=lcourant->index;
  • nombre.pfeuille->arg=new TParser[1];
  • temp=lcourant->suivant->lignefin;
  • ctemp=phrase[temp];
  • phrase[temp]='\0';
  • nombre.pfeuille->arg[0].Parse(&phrase[lcourant->suivant->lignedeb+1]);
  • phrase[temp]=ctemp;
  • break;
  • case EXPR:
  • if(lcourant->suivant->type!=OPUD)
  • {
  • temp=lcourant->lignefin;
  • ctemp=phrase[temp];
  • phrase[temp]='\0';
  • Parse(phrase+lcourant->lignedeb+1);
  • phrase[temp]=ctemp;
  • }
  • /* cas OPUD: */
  • else
  • {
  • type=OPU;
  • nombre.pfeuille=new feuille;
  • nombre.pfeuille->indexfonc=lcourant->suivant->index;
  • temp=lcourant->lignefin;
  • nombre.pfeuille->arg=new TParser[1];
  • ctemp=phrase[temp];
  • phrase[temp]='\0';
  • nombre.pfeuille->arg[0].Parse(phrase+lcourant->lignedeb+1);
  • phrase[temp]=ctemp;
  • }
  • break;
  • }
  • }
  • }
  • void TParser::Parse(char phrase[])
  • {
  • lexeme lex,*lcourant,*opb,*temp;
  • unsigned int prio;
  • int lgdeb,lgfin;
  • ParserExcept err;
  • if(type!=VIDE)
  • {
  • FreeExpression();
  • type=VIDE;
  • }
  • err.code=ARG;
  • if(*phrase!='\0')
  • {
  • if(!AnalyseLexical(phrase,&lex) && !AnalyseGrammatical(&lex))
  • {
  • /*On cree une expression autour de OPUG*/
  • lcourant=&lex;
  • while(lcourant->type!=FIN)
  • {
  • if(lcourant->type & OPUG)
  • {
  • opb=lcourant->suivant->suivant;
  • prio=op[lcourant->index].info.priorite;
  • lgdeb=opb->avant->lignefin;
  • while(opb->type!=FIN)
  • {
  • if(opb->type&(OPB|OPUD))
  • {
  • if(op[opb->index].info.priorite<=prio)break;
  • }
  • lgdeb=opb->lignefin;
  • opb=opb->suivant;
  • delete opb->avant;
  • }
  • temp=lcourant->suivant;
  • temp->type=EXPR;
  • if(!(opb->type&OPUD))lgdeb++;
  • temp->lignefin=lgdeb;
  • temp->lignedeb--;
  • temp->suivant=opb;
  • opb->avant=temp;
  • }
  • lcourant=lcourant->suivant;
  • }
  • /*On cree une TParser autour de OPUD*/
  • while(lcourant!=NULL)
  • {
  • if(lcourant->type & OPUD)
  • {
  • opb=lcourant->avant;
  • lgdeb=opb->lignedeb;
  • lgfin=opb->lignefin;
  • prio=op[lcourant->index].info.priorite;
  • while(opb!=&lex)
  • {
  • temp=opb=opb->avant;
  • if(opb->type==OPB)
  • {
  • if(op[opb->index].info.priorite<prio)break;
  • }
  • lgdeb=opb->lignedeb;
  • if(temp!=&lex)
  • delete temp;
  • }
  • temp=lcourant->avant;
  • if(opb==&lex)
  • {
  • if(temp!=&lex)delete temp;
  • temp=&lex;
  • lcourant->avant=&lex;
  • temp->suivant=lcourant;
  • }
  • else
  • {
  • temp->avant=opb;
  • opb->suivant=temp;
  • }
  • temp->type=EXPR;
  • temp->lignedeb=lgdeb-1;
  • temp->lignefin=lgfin+1;
  • }
  • lcourant=lcourant->avant;
  • }
  • /*Tout est verifier on peut creer l'arbre*/
  • CreeArbre(phrase,&lex);
  • }
  • }
  • /*On desalloue la memoire occupe par les lexemes*/
  • lcourant=lex.suivant;
  • while(lcourant->type!=FIN)
  • {
  • temp=lcourant;
  • lcourant=lcourant->suivant;
  • delete temp;
  • }
  • delete lcourant;
  • if(type==VIDE) throw(err);
  • }
  • #define FIXE (NBE|NBR|VAR|HEX|BIN|CONSTE|EXPR)
  • unsigned int TParser::AnalyseGrammatical(lexeme *lex)
  • {
  • unsigned short type;
  • lexeme *courant,*suivant;
  • short boole;
  • ParserExcept err;
  • err.code=BADTYPE;
  • courant=lex;
  • while(courant->suivant!=NULL)
  • {
  • if( (type=courant->type) & (FIXE|OPUD))
  • {
  • if((type&OPUD)&&(courant->avant==NULL))throw(err);
  • if((courant=courant->suivant)==NULL)throw(err);
  • if( ((type&(NBE|NBR|HEX|BIN|EXPR)) && (courant->type&(FONC|VAR|CONSTE|EXPR)))
  • ||( (type&(CONSTE|VAR) ) && (courant->type&EXPR)))
  • {
  • if((suivant=new lexeme)!=NULL)
  • {
  • suivant->type=OPB;
  • suivant->index=2; /*2=Index de la Multiplication*/
  • suivant->lignefin=suivant->lignedeb=courant->lignedeb;
  • suivant->suivant=courant;
  • suivant->avant=courant->avant;
  • courant->avant->suivant=suivant;
  • courant->avant=suivant;
  • continue;
  • }
  • else
  • {
  • err.code=MEM;
  • throw(err);
  • }
  • }
  • if((type=courant->type) &(FIN|OPUD))
  • continue;
  • else
  • {
  • if(type&OPB)
  • {
  • /*Fait le choix OPB|OPUG|OPUD*/
  • courant->type=OPB;
  • if((courant=courant->suivant)==NULL)throw(err);
  • if(courant->type&(FIXE|FONC|OPUG))
  • continue;
  • }
  • }
  • }
  • else
  • {
  • if(type&OPUG)
  • {
  • courant->type=OPUG;
  • if((courant=courant->suivant)==NULL)throw(err);
  • if(courant->type&(FIXE|FONC|OPUG))
  • {
  • if(courant->avant->index==1)
  • courant->avant->index=4;
  • continue;
  • }
  • }
  • else
  • {
  • if(type&FONC)
  • {
  • boole=op[courant->index].info.priorite;
  • if((courant=courant->suivant)==NULL)throw(err);
  • if(courant->type&EXPR)
  • {
  • if(courant->index==boole)
  • continue;
  • err.code=ARG;
  • }
  • }
  • }
  • }
  • throw(err);
  • }
  • return 0; /*Syntaxe correcte*/
  • }
  • unsigned int TParser::AnalyseLexical(char phrase[],lexeme *lex)
  • {
  • int type,index;
  • unsigned int len,lenmax;
  • lexeme *courant,*suivant;
  • ParserExcept err;
  • lex->avant=lex->suivant=NULL;
  • courant=lex;
  • err.PosCourant=0;
  • err.code=SYMB;
  • do
  • {
  • type=VIDE;
  • lenmax=EstCeUneExpression(phrase,&index);
  • if(lenmax)
  • type=EXPR;
  • else
  • {
  • lenmax=EstCeUnNombre(phrase,&type);
  • if(!lenmax)
  • {
  • len=EstCeUnOperateur(phrase,&index);
  • if(lenmax<len)
  • {
  • lenmax=len;
  • type=op[index].info.type;
  • }
  • len=EstCeUneVariable(phrase,&index);
  • if(lenmax<len)
  • {
  • lenmax=len;
  • type=CONSTE;
  • if(var[index].type&VAR)
  • type=VAR;
  • }
  • len=EstCeUnNombreHex(phrase);
  • if(lenmax<len)
  • {
  • lenmax=len;
  • type=HEX;
  • }
  • len=EstCeUnNombreBin(phrase);
  • if(lenmax<len)
  • {
  • lenmax=len;
  • type=BIN;
  • }
  • if(*phrase==' ')
  • {
  • err.PosCourant++;
  • phrase++;
  • continue;
  • }
  • }
  • }
  • if(type!=VIDE)
  • {
  • if((suivant=new lexeme)!=NULL)
  • {
  • courant->suivant=suivant;
  • courant->index=index;
  • courant->type=type;
  • courant->lignedeb=err.PosCourant;
  • courant->lignefin=(err.PosCourant+=lenmax)-1;
  • suivant->avant=courant;
  • courant=suivant;
  • phrase+=lenmax;
  • continue;
  • }
  • err.code=MEM; /*Erreur memoire*/
  • }
  • courant->suivant=NULL;
  • courant->type=FIN;
  • throw(err);
  • }
  • while(*phrase!='\0' && *(phrase-1)!='\0');
  • courant->type=FIN;
  • courant->lignedeb=courant->lignefin=err.PosCourant;
  • courant->suivant=NULL;
  • return 0; /*Reussi*/
  • }
  • unsigned int TParser::CmpRefToStr(register char *ref,register char *str)
  • {
  • int i;
  • i=0;
  • if(!*ref || !*str)return 0;
  • while(*ref==*str)
  • {
  • i++;ref++;str++;
  • if(!*ref)return i;
  • if(!*str)return 0;
  • }
  • return 0;
  • }
  • unsigned int TParser::EstCeUneVariable(char phrase[],int *index)
  • {
  • int i,len,lenmax,imax;
  • lenmax=i=0;
  • imax=-1;
  • while(i!=nbvar)
  • {
  • if(lenmax<(len=CmpRefToStr(var[i].nom,phrase)))
  • {
  • lenmax=len;
  • imax=i;
  • }
  • i++;
  • }
  • if(imax!=-1)*index=imax;
  • return lenmax;
  • }
  • unsigned int TParser::EstCeUnOperateur(char phrase[],int *index)
  • {
  • int i,len,lenmax,imax;
  • lenmax=i=0;
  • imax=-1;
  • while(i!=nbop)
  • {
  • if(lenmax<(len=CmpRefToStr(op[i].nom,phrase)))
  • {
  • lenmax=len;
  • imax=i;
  • }
  • i++;
  • }
  • if(imax!=-1)*index=imax;
  • return lenmax;
  • }
  • /*retourne <Pos> et type=NBE si c'est un nombre entier
  • retourne <Pos> et type=NBR si c'est un nombre reel
  • retourne <Pos> et type=NBR si c'est un nombre exponentielle
  • retourne <Pos erreur> et type=VIDE si ce n'est pas un nombre*/
  • unsigned int TParser::EstCeUnNombre(char phrase[],int *type)
  • {
  • unsigned int a,i=0;
  • *type=NBE;
  • a=i;
  • while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
  • if(i==a)
  • {
  • *type=VIDE;
  • return 0;
  • }
  • if(phrase[i]=='.')
  • {
  • *type=NBR;
  • a=++i;
  • while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
  • if(i==a)
  • {
  • *type=VIDE;
  • return 0;
  • }
  • }
  • if(phrase[i]=='e')
  • {
  • *type=NBR;
  • a=++i;
  • if((phrase[i]=='+')||(phrase[i]=='-'))i++;
  • if(a!=i)
  • {
  • a=i;
  • while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
  • if(i==a)
  • {
  • *type=VIDE;
  • return 0;
  • }
  • }
  • else
  • {
  • while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
  • if(i==a)i--;
  • }
  • }
  • return i;
  • }
  • unsigned int TParser::EstCeUnNombreHex(char phrase[])
  • {
  • unsigned int i=0;
  • ParserExcept err;
  • err.code=OVFLOW;
  • if(*phrase=='h')
  • {
  • do i++;
  • while((phrase[i]>='0' && phrase[i]<='9')||
  • (phrase[i]>='a' && phrase[i]<='f'));
  • if((i-1)>(sizeof(unsigned int)*2))throw(err);
  • }
  • return i;
  • }
  • unsigned int TParser::EstCeUnNombreBin(char phrase[])
  • {
  • unsigned int i=0;
  • ParserExcept err;
  • err.code=OVFLOW;
  • if(*phrase=='b')
  • {
  • do i++;
  • while(phrase[i]=='0' || phrase[i]=='1');
  • if((i-1)>(sizeof(unsigned int)*8))throw(err);
  • }
  • return i;
  • }
  • unsigned int TParser::EstCeUneExpression(char phrase[],int *nbarg)
  • {
  • unsigned int i;
  • int nbparenthese=0;
  • *nbarg=i=1;
  • if(*phrase=='(')
  • {
  • while(*phrase)
  • {
  • if(*phrase=='(')nbparenthese++;
  • if(*phrase==')')
  • {
  • if(!(--nbparenthese))
  • break;
  • }
  • if(*phrase==',' && nbparenthese==1)(*nbarg)++;
  • phrase++;
  • i++;
  • }
  • return i;
  • }
  • return 0;
  • }
  • unsigned int HexToInt(char phrase[])
  • {
  • unsigned int res=0,c;
  • while(*(++phrase))
  • {
  • c=*phrase-'0';
  • if(c>9)c-=('a'-'9'-1);
  • res=res*16+c;
  • }
  • return res;
  • }
  • unsigned int BinToInt(char phrase[])
  • {
  • unsigned int res=0;
  • while(*(++phrase))
  • res=(res<<1)+*phrase-'0';
  • return res;
  • }
  • void TParser::FreeExpression()
  • {
  • // feuille *pfeuille;
  • // int i,nbarg=1;
  • // pfeuille=nombre.pfeuille;
  • switch(type)
  • {
  • case PNOEUD:
  • // nombre.pnoeud->nbG.FreeExpression();
  • // nombre.pnoeud->nbD.FreeExpression();
  • delete nombre.pnoeud;
  • break;
  • case FONC:
  • // nbarg=op[pfeuille->indexfonc].info.priorite;
  • case OPU:
  • // for(i=0;i<nbarg;i++)
  • // pfeuille->arg[i].FreeExpression();
  • delete[] nombre.pfeuille->arg;
  • delete nombre.pfeuille;
  • break;
  • }
  • type=var[4].type&(~VAR); /* Met dans exp le*/
  • nombre=var[4].donnee; /*dernier resultat (4=ans)*/
  • }
  • /*----------------------------------------------------------------------*/
  • ParserExcept::ParserExcept()
  • {
  • PosCourant=0;
  • code=0;
  • }
  • void ParserExcept::affiche(HWND hwnd,char *text)
  • {
  • char conserve[100];
  • wsprintf(conserve,"%s:\n%s",TErreur[code],text+PosCourant);
  • MessageBoxA(hwnd,conserve,"Parser Erreur",MB_OK|MB_ICONEXCLAMATION);
  • }
  • /*---------------------------------------------------------------------*/
  • TParser ADD(TParser *arg)
  • {
  • TParser a;
  • a.type=NBR;
  • if(arg[0].type==NBR)
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=arg[0].nombre.freel+arg[1].nombre.freel;
  • else
  • a.nombre.freel=arg[0].nombre.freel+(float)arg[1].nombre.sint;
  • }
  • else
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=(float)arg[0].nombre.sint+arg[1].nombre.freel;
  • else
  • {
  • a.type=NBE;
  • a.nombre.sint=arg[0].nombre.sint+arg[1].nombre.sint;
  • }
  • }
  • return a;
  • }
  • TParser SUB(TParser *arg)
  • {
  • TParser a;
  • a.type=NBR;
  • if(arg[0].type==NBR)
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=arg[0].nombre.freel-arg[1].nombre.freel;
  • else
  • a.nombre.freel=arg[0].nombre.freel-(float)arg[1].nombre.sint;
  • }
  • else
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=(float)arg[0].nombre.sint-arg[1].nombre.freel;
  • else
  • {
  • a.type=NBE;
  • a.nombre.sint=arg[0].nombre.sint-arg[1].nombre.sint;
  • }
  • }
  • return a;
  • }
  • TParser MUL(TParser *arg)
  • {
  • TParser a;
  • a.type=NBR;
  • if(arg[0].type==NBR)
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=arg[0].nombre.freel*arg[1].nombre.freel;
  • else
  • a.nombre.freel=arg[0].nombre.freel*(float)arg[1].nombre.sint;
  • }
  • else
  • {
  • if(arg[1].type==NBR)
  • a.nombre.freel=(float)arg[0].nombre.sint*arg[1].nombre.freel;
  • else
  • {
  • a.type=NBE;
  • a.nombre.sint=arg[0].nombre.sint*arg[1].nombre.sint;
  • }
  • }
  • return a;
  • }
  • TParser DIV(TParser *arg)
  • {
  • TParser res;
  • float a,b;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • b=arg[1].nombre.freel;
  • if(arg[1].type==NBE)
  • b=(float)arg[1].nombre.sint;
  • res.nombre.freel=a/b;
  • return res;
  • }
  • TParser NEG(TParser *arg)
  • {
  • TParser a=arg[0];
  • if(a.type==NBR)
  • a.nombre.freel=-a.nombre.freel;
  • else
  • a.nombre.sint=-a.nombre.sint;
  • return a;
  • }
  • TParser MOD(TParser *arg)
  • {
  • TParser a;
  • a.type=NBE;
  • if(arg[0].type==NBE && arg[1].type==NBE)
  • {
  • if((a.nombre.sint=arg[0].nombre.sint%arg[1].nombre.sint)<0)
  • a.nombre.sint+=arg[1].nombre.sint;
  • }
  • return a;
  • }
  • TParser POW(TParser *arg)
  • {
  • TParser res;
  • float a,b;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • b=arg[1].nombre.freel;
  • if(arg[1].type==NBE)
  • b=(float)arg[1].nombre.sint;
  • res.nombre.freel=pow(a,b);
  • return res;
  • }
  • TParser FACT(TParser *arg)
  • {
  • TParser a;
  • int res;
  • a.type=NBE;
  • if(arg[0].type==NBE)
  • {
  • res=arg[0].nombre.sint;
  • for(a.nombre.sint=1;res>0;res--)
  • a.nombre.sint*=res;
  • }
  • return a;
  • }
  • TParser SIN(TParser *arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=sin(a);
  • return res;
  • }
  • TParser COS(TParser *arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=cos(a);
  • return res;
  • }
  • TParser TAN(TParser *arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=tan(a);
  • return res;
  • }
  • TParser SQRT(TParser *arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=sqrt(a);
  • return res;
  • }
  • TParser EXP(TParser* arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=exp(a);
  • return res;
  • }
  • TParser LN(TParser* arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=log(a);
  • return res;
  • }
  • TParser LOG(TParser* arg)
  • {
  • TParser res;
  • float a;
  • res.type=NBR;
  • a=arg[0].nombre.freel;
  • if(arg[0].type==NBE)
  • a=(float)arg[0].nombre.sint;
  • res.nombre.freel=log10(a);
  • return res;
  • }
  • TParser ROUND(TParser arg[])
  • {
  • TParser a=arg[0];
  • if(a.type==NBR)
  • {
  • a.type=NBE;
  • a.nombre.sint=(signed int)(a.nombre.freel+0.5);
  • }
  • return a;
  • }
  • TParser NOT(TParser arg[])
  • {
  • TParser a;
  • a.type=NBE;
  • if(arg[0].type==NBE)
  • a.nombre.sint=~arg[0].nombre.sint;
  • return a;
  • }
  • TParser AND(TParser *arg)
  • {
  • TParser a;
  • if(arg[0].type==NBE && arg[1].type==NBE)
  • a.nombre.sint=arg[0].nombre.sint & arg[1].nombre.sint;
  • a.type=NBE;
  • return a;
  • }
  • TParser OR(TParser *arg)
  • {
  • TParser a;
  • if(arg[0].type==NBE && arg[1].type==NBE)
  • a.nombre.sint=arg[0].nombre.sint | arg[1].nombre.sint;
  • a.type=NBE;
  • return a;
  • }
  • /*Fichier bparser.h*/
  • /*
  • Probleme lie a l'enchainement d'un nombre avec une
  • fonction ou une variable ou une constante commencant
  • par la lettre e suivit d'un chiffre
  • ex:
  • 12e0 <> 12*e0
  • 12*10^0=12 <> 12*e0 avec e une variable
  • */
  • unsigned int HexToInt(char phrase[]);
  • unsigned int BinToInt(char phrase[]);
  • enum ELexeme{VIDE=0,OPB=1,OPUG=2,OPUD=4,FONC=8,NBE=16,NBR=32,
  • VAR=64,PNOEUD=128,CONSTE=256,EXPR=512,HEX=1024,
  • /*PFEUILLE=2048,*/BIN=4096,FIN=8192};
  • typedef struct lexeme
  • {
  • unsigned short type;
  • signed short lignedeb,lignefin;
  • unsigned short index;
  • struct lexeme *avant,*suivant;
  • } lexeme;
  • typedef struct information
  • {
  • unsigned int type:4;
  • unsigned int priorite:4;
  • } information;
  • typedef union variant
  • {
  • float freel;
  • signed int sint;
  • struct noeud *pnoeud;
  • struct feuille *pfeuille;
  • unsigned short var;
  • } variant;
  • typedef struct variable
  • {
  • char *nom;
  • char type;
  • union variant donnee;
  • } variable;
  • class TParser
  • {
  • private:
  • unsigned int EstCeUnNombre(char phrase[],int *type);
  • unsigned int EstCeUneExpression(char phrase[],int *nbarg);
  • unsigned int EstCeUnOperateur(char phrase[],int *indeop);
  • unsigned int EstCeUneVariable(char phrase[],int *index);
  • unsigned int CmpRefToStr(char *str1,char *str2);
  • unsigned int AnalyseLexical(char phrase[],lexeme *lex);
  • unsigned int AnalyseGrammatical(lexeme *lex);
  • unsigned int EstCeUnNombreHex(char phrase[]);
  • unsigned int EstCeUnNombreBin(char phrase[]);
  • void CalculExpression();
  • void CreeArbre(char phrase[],lexeme *lex);
  • static struct operateur op[];
  • static struct variable var[];
  • static int nbop,nbvar;
  • public:
  • unsigned char type; // Peut contenir les lexemes<256
  • union variant nombre;
  • TParser();
  • ~TParser();
  • void Parse(char phrase[]);
  • TParser Calcul();
  • void FreeExpression();
  • };
  • typedef struct operateur
  • {
  • char *nom;
  • TParser (*f)(TParser *);
  • information info;
  • } operateur;
  • typedef struct noeud
  • {
  • short indexop;
  • TParser nbG;
  • TParser nbD;
  • } noeud;
  • typedef struct feuille /*Sert uniquement pour les appels de fonctions*/
  • {
  • short indexfonc;
  • TParser *arg; /*Permet de conserver un tableau d'expressions*/
  • } feuille; /*de la taille operateur[indexfonc].info.priorite*/
  • class ParserExcept
  • {
  • public:
  • int code;
  • int PosCourant;
  • ParserExcept();
  • void affiche(HWND hwnd,char *text);
  • };
/*Fichier bparser.c*/
#ifndef __WINDOWS_H
#include<windows.h>
#endif
#include<math.h>
#include "bparser.hpp"

#define OPU (OPUD|OPUG)

enum CErreur{SYMB=0,MEM,BADTYPE,ARG,OVFLOW};

TParser ADD(TParser arg[]);
TParser SUB(TParser arg[]);
TParser MUL(TParser arg[]);
TParser DIV(TParser arg[]);
TParser MOD(TParser arg[]);
TParser POW(TParser arg[]);
TParser SIN(TParser arg[]);
TParser COS(TParser arg[]);
TParser TAN(TParser arg[]);
TParser FACT(TParser arg[]);
TParser SQRT(TParser arg[]);
TParser NEG(TParser arg[]);
TParser EXP(TParser arg[]);
TParser LN(TParser arg[]);
TParser LOG(TParser arg[]);
TParser AND(TParser arg[]);
TParser OR(TParser arg[]);
TParser NOT(TParser arg[]);
TParser ROUND(TParser arg[]);

char *TErreur[5]=  {
  "Symbole inconnu",
  "Probleme memoire!",
  "Autre type attendu",
  "Trop ou pas assez d'arguments",
  "Depassement de capacitee"
};

int TParser::nbop=19;
operateur TParser::op[19]={
                          "+",(TParser (*)(TParser *))ADD,{OPB,11},
			  "-",(TParser (*)(TParser *))SUB,{OPB|OPUG,11},
			  "*",(TParser (*)(TParser *))MUL,{OPB,12},
			  "/",(TParser (*)(TParser *))DIV,{OPB,12},
			  ".-",(TParser(*)(TParser *))NEG,{OPUG,15},
			  "%",(TParser (*)(TParser *))MOD,{OPB,12},
			  "^",(TParser (*)(TParser *))POW,{OPB,13},
			  "!",(TParser (*)(TParser *))FACT,{OPUD,15},
			  "&",(TParser (*)(TParser *))AND,{OPB,12},
			  "|",(TParser (*)(TParser *))OR,{OPB,11},
			  "~",(TParser (*)(TParser *))NOT,{OPUG,15},
			  "sin",(TParser(*)(TParser *))SIN,{FONC,1},
			  "cos",(TParser(*)(TParser *))COS,{FONC,1},
			  "tan",(TParser(*)(TParser *))TAN,{FONC,1},
			  "sqrt",(TParser(*)(TParser *))SQRT,{FONC,1},
			  "exp",(TParser(*)(TParser *))EXP,{FONC,1},
			  "ln",(TParser(*)(TParser *))LN,{FONC,1},
			  "log",(TParser(*)(TParser *))LOG,{FONC,1},
			  "round",(TParser(*)(TParser *))ROUND,{FONC,1}
  			};
int TParser::nbvar=6;
variable TParser::var[6]=	{
  			  "x",NBR|VAR,0.0,
			  "y",NBR|VAR,0.0,
			  "z",NBR|VAR,0.0,
			  "t",NBR|VAR,0.0,
			  "ans",NBR|VAR,0.0,
			  "pi",NBR,M_PI//3.1415927,
  			};
TParser::TParser()
{type=VIDE;}

TParser::~TParser()
{FreeExpression();}

TParser TParser::Calcul()
{
  TParser res=*this;
  res.CalculExpression();
  var[4].type=res.type|VAR;	/*Met le resultat dans la*/
  var[4].donnee=res.nombre;	/*variable "ans"*/
  return res;
}

void TParser::CalculExpression()
{
  TParser arg[2],*texp;
  noeud *cour;
  feuille *pfeuille;
  int nbarg;
  ParserExcept err;

  switch(type)
    {
    case VAR:
      type=var[nombre.var].type&(~VAR);
      nombre=var[nombre.var].donnee;
      break;
    case PNOEUD:
      cour=nombre.pnoeud;
      arg[0]=cour->nbG;
      arg[0].CalculExpression();
      arg[1]=cour->nbD;
      arg[1].CalculExpression();
      *this=op[cour->indexop].f(arg);
      break;
    case FONC:
      pfeuille=nombre.pfeuille;
      nbarg=op[pfeuille->indexfonc].info.priorite;
      if((texp=new TParser[nbarg])==NULL)
	{
	  err.code=MEM;
          throw(err);
	}
      while(nbarg--)
      {
        texp[nbarg]=pfeuille->arg[nbarg];
        texp[nbarg].CalculExpression();
      }
     *this=op[pfeuille->indexfonc].f(texp);
      delete[] texp;
      break;
    case OPU:
      pfeuille=nombre.pfeuille;
      arg[0]=pfeuille->arg[0];
      arg[0].CalculExpression();
      *this=op[pfeuille->indexfonc].f(&arg[0]);
      break;
    }
    nbarg=0;
}

void TParser::CreeArbre(char phrase[],lexeme *lex)
{
  char ctemp;
  lexeme *lcourant,*sauv;
  int priorite,temp,nbarg,poscourant;

  priorite=16;
  lcourant=lex;
  /*Cherche l'operateur binaire ayant la plus petite priorite*/
  while(lcourant->type!=FIN)
    {
      if(lcourant->type&OPB)
	{
	  temp=op[lcourant->index].info.priorite;
	  if(temp<=priorite)
	    {
	      sauv=lcourant;
	      priorite=temp;
	    }
	}
      lcourant=lcourant->suivant;
    }
  /*Si il y a un OPB alors on remplit sinon il ni a plus
    d'operateur binaire et donc c'est une TParser*/
  if(!(priorite&16))
    {
      type=PNOEUD;
      if((nombre.pnoeud=new noeud)!=NULL)
	{
	  /*Coupe en 2 la chaine de lexeme*/
	  /*La partie a gauche de l'OPB et la droite*/
	  sauv->type=FIN;
	  lcourant=sauv->suivant;
	  lcourant->avant=sauv->suivant=NULL;
	  nombre.pnoeud->indexop=sauv->index;
	  nombre.pnoeud->nbG.CreeArbre(phrase,lex);
	  nombre.pnoeud->nbD.CreeArbre(phrase,lcourant);
	  /*Retabli les information dans la chaine de lexeme*/
	  sauv->type=OPB;
	  sauv->suivant=lcourant;
	  lcourant->avant=sauv;
	}
    }
  else
    {
      lcourant=lex;

      switch(lcourant->type)
	{
	case BIN:
	  ctemp=phrase[lcourant->lignefin+1];
	  phrase[lcourant->lignefin+1]='\0';
	  type=NBE;
	  nombre.sint=BinToInt(phrase+lcourant->lignedeb);
	  phrase[lcourant->lignefin+1]=ctemp;
	  break;
	case HEX:
	  ctemp=phrase[lcourant->lignefin+1];
	  phrase[lcourant->lignefin+1]='\0';
	  type=NBE;
	  nombre.sint=HexToInt(phrase+lcourant->lignedeb);
	  phrase[lcourant->lignefin+1]=ctemp;
	  break;
	case NBR:
	  ctemp=phrase[lcourant->lignefin+1];
	  phrase[lcourant->lignefin+1]='\0';
	  type=NBR;
	  nombre.freel=atof(phrase+lcourant->lignedeb);
	  phrase[lcourant->lignefin+1]=ctemp;
	  break;
	case NBE:
	  ctemp=phrase[lcourant->lignefin+1];
	  phrase[lcourant->lignefin+1]='\0';
	  type=NBE;
	  nombre.sint=atoi(phrase+lcourant->lignedeb);
	  phrase[lcourant->lignefin+1]=ctemp;
	  break;
	case CONSTE:
	  type=var[lcourant->index].type;
	  nombre.freel=var[lcourant->index].donnee.freel;
	  break;
	case VAR:
	  type=VAR;
	  nombre.var=lcourant->index;
	  break;
	case FONC:
	  type=FONC;
	  nombre.pfeuille=new feuille;
	  nombre.pfeuille->indexfonc=lcourant->index;
	  nbarg=op[lcourant->index].info.priorite;
	  nombre.pfeuille->arg=new TParser[nbarg];
	  temp=poscourant=lcourant->suivant->lignedeb+1;
	  priorite=0;
	  while(--nbarg)
	    {
	      while(phrase[temp]!=',')temp++;
	      phrase[temp]='\0';
	      nombre.pfeuille->arg[priorite].Parse(phrase+poscourant);
	      phrase[temp]=',';
	      poscourant=++temp;
	      priorite++;
	    }
	  temp=lcourant->suivant->lignefin;
	  ctemp=phrase[temp];
	  phrase[temp]='\0';
	  nombre.pfeuille->arg[priorite].Parse(phrase+poscourant);
	  phrase[temp]=ctemp;
	  break;

	case OPUG:
	  type=OPU;
	  nombre.pfeuille=new feuille;
	  nombre.pfeuille->indexfonc=lcourant->index;
	  nombre.pfeuille->arg=new TParser[1];

	  temp=lcourant->suivant->lignefin;
	  ctemp=phrase[temp];
	  phrase[temp]='\0';
	  nombre.pfeuille->arg[0].Parse(&phrase[lcourant->suivant->lignedeb+1]);
	  phrase[temp]=ctemp;
	  break;

	case EXPR:
	  if(lcourant->suivant->type!=OPUD)
	    {
	      temp=lcourant->lignefin;
	      ctemp=phrase[temp];
	      phrase[temp]='\0';
	      Parse(phrase+lcourant->lignedeb+1);
	      phrase[temp]=ctemp;
	    }
	  /*   cas OPUD: */
	  else
	    {
	      type=OPU;
	      nombre.pfeuille=new feuille;
	      nombre.pfeuille->indexfonc=lcourant->suivant->index;
	      temp=lcourant->lignefin;
	      nombre.pfeuille->arg=new TParser[1];
	      ctemp=phrase[temp];
	      phrase[temp]='\0';
	      nombre.pfeuille->arg[0].Parse(phrase+lcourant->lignedeb+1);
	      phrase[temp]=ctemp;
	    }
	  break;
	}
    }
}

void TParser::Parse(char phrase[])
{
  lexeme lex,*lcourant,*opb,*temp;
  unsigned int prio;
  int lgdeb,lgfin;
  ParserExcept err;

  if(type!=VIDE)
  {
    FreeExpression();
    type=VIDE;
  }
  err.code=ARG;
  if(*phrase!='\0')
    {
      if(!AnalyseLexical(phrase,&lex) && !AnalyseGrammatical(&lex))
	{
	  /*On cree une expression autour de OPUG*/
	  lcourant=&lex;
	  while(lcourant->type!=FIN)
	    {
	      if(lcourant->type & OPUG)
		{
		  opb=lcourant->suivant->suivant;
		  prio=op[lcourant->index].info.priorite;
		  lgdeb=opb->avant->lignefin;
		  while(opb->type!=FIN)
		    {
		      if(opb->type&(OPB|OPUD))
			{
			  if(op[opb->index].info.priorite<=prio)break;
			}
		      lgdeb=opb->lignefin;
		      opb=opb->suivant;
		      delete opb->avant;
		    }
		  temp=lcourant->suivant;
		  temp->type=EXPR;
		  if(!(opb->type&OPUD))lgdeb++;
		  temp->lignefin=lgdeb;
		  temp->lignedeb--;
		  temp->suivant=opb;
		  opb->avant=temp;
		}
	      lcourant=lcourant->suivant;
	    }
	  /*On cree une TParser autour de OPUD*/
	  while(lcourant!=NULL)
	    {
	      if(lcourant->type & OPUD)
		{
		  opb=lcourant->avant;
		  lgdeb=opb->lignedeb;
		  lgfin=opb->lignefin;
		  prio=op[lcourant->index].info.priorite;
		  while(opb!=&lex)
		    {
		      temp=opb=opb->avant;
		      if(opb->type==OPB)
			{
			  if(op[opb->index].info.priorite<prio)break;
			}
		      lgdeb=opb->lignedeb;
		      if(temp!=&lex)
			delete temp;
		    }
		  temp=lcourant->avant;
		  if(opb==&lex)
		    {
		      if(temp!=&lex)delete temp;
		      temp=&lex;
		      lcourant->avant=&lex;
		      temp->suivant=lcourant;
		    }
		  else
		    {
		      temp->avant=opb;
		      opb->suivant=temp;
		    }
		  temp->type=EXPR;
		  temp->lignedeb=lgdeb-1;
		  temp->lignefin=lgfin+1;
		}
	      lcourant=lcourant->avant;
	    }
	  /*Tout est verifier on peut creer l'arbre*/
	  CreeArbre(phrase,&lex);
        }
      }
/*On desalloue la memoire occupe par les lexemes*/
      lcourant=lex.suivant;
      while(lcourant->type!=FIN)
      {
        temp=lcourant;
        lcourant=lcourant->suivant;
        delete temp;
      }
      delete lcourant;
      if(type==VIDE) throw(err);
}

#define FIXE (NBE|NBR|VAR|HEX|BIN|CONSTE|EXPR)
unsigned int TParser::AnalyseGrammatical(lexeme *lex)
{
  unsigned short type;
  lexeme *courant,*suivant;
  short boole;
  ParserExcept err;

  err.code=BADTYPE;
  courant=lex;

  while(courant->suivant!=NULL)
    {
      if( (type=courant->type) & (FIXE|OPUD))
	{
	  if((type&OPUD)&&(courant->avant==NULL))throw(err);
	  if((courant=courant->suivant)==NULL)throw(err);
	  if( ((type&(NBE|NBR|HEX|BIN|EXPR)) && (courant->type&(FONC|VAR|CONSTE|EXPR)))
	      ||( (type&(CONSTE|VAR)  ) && (courant->type&EXPR)))
	    {
	      if((suivant=new lexeme)!=NULL)
		{
		  suivant->type=OPB;
		  suivant->index=2; /*2=Index de la Multiplication*/
		  suivant->lignefin=suivant->lignedeb=courant->lignedeb;
		  suivant->suivant=courant;
		  suivant->avant=courant->avant;
		  courant->avant->suivant=suivant;
		  courant->avant=suivant;
		  continue;
		}
	      else
		{
		  err.code=MEM;
                  throw(err);
		}
	    }
	  if((type=courant->type) &(FIN|OPUD))
	    continue;
	  else
	    {
	      if(type&OPB)
		{
		  /*Fait le choix OPB|OPUG|OPUD*/
		  courant->type=OPB;
		  if((courant=courant->suivant)==NULL)throw(err);
		  if(courant->type&(FIXE|FONC|OPUG))
 	            continue;
		}
	    }
	}
      else
	{
	  if(type&OPUG)
	    {
	      courant->type=OPUG;
	      if((courant=courant->suivant)==NULL)throw(err);
	      if(courant->type&(FIXE|FONC|OPUG))
		{
		  if(courant->avant->index==1)
                    courant->avant->index=4;
                  continue;
	        }
	    }
	  else
	    {
	      if(type&FONC)
		{
		  boole=op[courant->index].info.priorite;
		  if((courant=courant->suivant)==NULL)throw(err);
		  if(courant->type&EXPR)
		    {
		      if(courant->index==boole)
		        continue;
		      err.code=ARG;
		    }
		}
	    }
	}
      throw(err);
    }
  return 0;  /*Syntaxe correcte*/
}

unsigned int TParser::AnalyseLexical(char phrase[],lexeme *lex)
{
  int type,index;
  unsigned int len,lenmax;
  lexeme *courant,*suivant;
  ParserExcept err;

  lex->avant=lex->suivant=NULL;
  courant=lex;
  err.PosCourant=0;
  err.code=SYMB;
  do
  {
    type=VIDE;
    lenmax=EstCeUneExpression(phrase,&index);
    if(lenmax)
      type=EXPR;
    else
    {
      lenmax=EstCeUnNombre(phrase,&type);
      if(!lenmax)
      {
        len=EstCeUnOperateur(phrase,&index);
        if(lenmax<len)
        {
	      lenmax=len;
	      type=op[index].info.type;
        }
        len=EstCeUneVariable(phrase,&index);

        if(lenmax<len)
        {
	      lenmax=len;
	      type=CONSTE;
	      if(var[index].type&VAR)
	        type=VAR;
        }
        len=EstCeUnNombreHex(phrase);
        if(lenmax<len)
        {
	      lenmax=len;
	      type=HEX;
        }

        len=EstCeUnNombreBin(phrase);
        if(lenmax<len)
        {
	      lenmax=len;
	      type=BIN;
        }
	if(*phrase==' ')
	{
	  err.PosCourant++;
	  phrase++;
	  continue;
	}

      }
    }
    if(type!=VIDE)
    {
      if((suivant=new lexeme)!=NULL)
      {
        courant->suivant=suivant;
        courant->index=index;
        courant->type=type;
        courant->lignedeb=err.PosCourant;
        courant->lignefin=(err.PosCourant+=lenmax)-1;

        suivant->avant=courant;
        courant=suivant;
        phrase+=lenmax;
        continue;
      }
      err.code=MEM;	/*Erreur memoire*/
    }
    courant->suivant=NULL;
    courant->type=FIN;
    throw(err);
  }
  while(*phrase!='\0' && *(phrase-1)!='\0');
  courant->type=FIN;
  courant->lignedeb=courant->lignefin=err.PosCourant;
  courant->suivant=NULL;
  return 0;	/*Reussi*/
}

unsigned int TParser::CmpRefToStr(register char *ref,register char *str)
{
  int i;
  i=0;
  if(!*ref || !*str)return 0;
  while(*ref==*str)
  {
    i++;ref++;str++;
    if(!*ref)return i;
    if(!*str)return 0;
  }
  return 0;
}

unsigned int TParser::EstCeUneVariable(char phrase[],int *index)
{
  int i,len,lenmax,imax;

  lenmax=i=0;
  imax=-1;
  while(i!=nbvar)
  {
    if(lenmax<(len=CmpRefToStr(var[i].nom,phrase)))
    {
      lenmax=len;
      imax=i;
    }
    i++;
  }
  if(imax!=-1)*index=imax;

  return lenmax;
}

unsigned int TParser::EstCeUnOperateur(char phrase[],int *index)
{
  int i,len,lenmax,imax;

  lenmax=i=0;
  imax=-1;
  while(i!=nbop)
  {
    if(lenmax<(len=CmpRefToStr(op[i].nom,phrase)))
    {
      lenmax=len;
      imax=i;
    }
    i++;
  }
  if(imax!=-1)*index=imax;
  return lenmax;
}

/*retourne <Pos> 		et type=NBE si c'est un nombre entier
retourne <Pos> 		et type=NBR si c'est un nombre reel
retourne <Pos> 		et type=NBR si c'est un nombre exponentielle
retourne <Pos erreur>	et type=VIDE si ce n'est pas un nombre*/
unsigned int TParser::EstCeUnNombre(char phrase[],int *type)
{
  unsigned int a,i=0;
  *type=NBE;
  a=i;
  while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
  if(i==a)
  {
    *type=VIDE;
    return 0;
  }
  if(phrase[i]=='.')
  {
    *type=NBR;
    a=++i;
    while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
    if(i==a)
    {
      *type=VIDE;
      return 0;
    }
  }
  if(phrase[i]=='e')
  {
    *type=NBR;
    a=++i;
    if((phrase[i]=='+')||(phrase[i]=='-'))i++;
    if(a!=i)
    {
      a=i;
      while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
      if(i==a)
      {
       *type=VIDE;
       return 0;
      }
    }
    else
    {
      while((phrase[i]>='0')&&(phrase[i]<='9'))i++;
      if(i==a)i--;
    }
  }
  return i;
}

unsigned int TParser::EstCeUnNombreHex(char phrase[])
{
  unsigned int i=0;
  ParserExcept err;
  err.code=OVFLOW;
  if(*phrase=='h')
  {
    do i++;
    while((phrase[i]>='0' && phrase[i]<='9')||
    	  (phrase[i]>='a' && phrase[i]<='f'));
    if((i-1)>(sizeof(unsigned int)*2))throw(err);
  }
  return i;
}

unsigned int TParser::EstCeUnNombreBin(char phrase[])
{
  unsigned int i=0;
  ParserExcept err;
  err.code=OVFLOW;
  if(*phrase=='b')
  {
    do i++;
    while(phrase[i]=='0' || phrase[i]=='1');
    if((i-1)>(sizeof(unsigned int)*8))throw(err);
  }
  return i;
}

unsigned int TParser::EstCeUneExpression(char phrase[],int *nbarg)
{
  unsigned int i;
  int nbparenthese=0;
  *nbarg=i=1;
  if(*phrase=='(')
  {
    while(*phrase)
    {
      if(*phrase=='(')nbparenthese++;
      if(*phrase==')')
      {
        if(!(--nbparenthese))
          break;
      }
      if(*phrase==',' && nbparenthese==1)(*nbarg)++;
      phrase++;
      i++;
    }
    return i;
  }
  return 0;
}

unsigned int HexToInt(char phrase[])
{
  unsigned int res=0,c;
while(*(++phrase))
  {
    c=*phrase-'0';
    if(c>9)c-=('a'-'9'-1);
    res=res*16+c;
  }
  return res;
}

unsigned int BinToInt(char phrase[])
{
  unsigned int res=0;
  while(*(++phrase))
    res=(res<<1)+*phrase-'0';
  return res;
}

void TParser::FreeExpression()
{
//  feuille *pfeuille;
//  int i,nbarg=1;

//  pfeuille=nombre.pfeuille;
  switch(type)
  {
   case PNOEUD:
//      nombre.pnoeud->nbG.FreeExpression();
//      nombre.pnoeud->nbD.FreeExpression();
      delete nombre.pnoeud;
      break;
   case FONC:
//     nbarg=op[pfeuille->indexfonc].info.priorite;
   case OPU:
//     for(i=0;i<nbarg;i++)
//       pfeuille->arg[i].FreeExpression();
     delete[] nombre.pfeuille->arg;
     delete nombre.pfeuille;
     break;
  }
  type=var[4].type&(~VAR); /* Met dans exp le*/
  nombre=var[4].donnee;   /*dernier resultat (4=ans)*/
}
/*----------------------------------------------------------------------*/
ParserExcept::ParserExcept()
{
  PosCourant=0;
  code=0;
}

void ParserExcept::affiche(HWND hwnd,char *text)
{
  char conserve[100];
  wsprintf(conserve,"%s:\n%s",TErreur[code],text+PosCourant);
  MessageBoxA(hwnd,conserve,"Parser Erreur",MB_OK|MB_ICONEXCLAMATION);
}
/*---------------------------------------------------------------------*/

TParser ADD(TParser *arg)
{
  TParser a;
  a.type=NBR;
  if(arg[0].type==NBR)
  {
    if(arg[1].type==NBR)
      a.nombre.freel=arg[0].nombre.freel+arg[1].nombre.freel;
    else
      a.nombre.freel=arg[0].nombre.freel+(float)arg[1].nombre.sint;
  }
  else
  {
    if(arg[1].type==NBR)
      a.nombre.freel=(float)arg[0].nombre.sint+arg[1].nombre.freel;
    else
    {
      a.type=NBE;
      a.nombre.sint=arg[0].nombre.sint+arg[1].nombre.sint;
    }
  }
  return a;
}
TParser SUB(TParser *arg)
{
  TParser a;
  a.type=NBR;
  if(arg[0].type==NBR)
  {
    if(arg[1].type==NBR)
      a.nombre.freel=arg[0].nombre.freel-arg[1].nombre.freel;
    else
      a.nombre.freel=arg[0].nombre.freel-(float)arg[1].nombre.sint;
  }
  else
  {
    if(arg[1].type==NBR)
      a.nombre.freel=(float)arg[0].nombre.sint-arg[1].nombre.freel;
    else
    {
      a.type=NBE;
      a.nombre.sint=arg[0].nombre.sint-arg[1].nombre.sint;
    }
  }
  return a;
}
TParser MUL(TParser *arg)
{
  TParser a;
  a.type=NBR;
  if(arg[0].type==NBR)
  {
    if(arg[1].type==NBR)
      a.nombre.freel=arg[0].nombre.freel*arg[1].nombre.freel;
    else
      a.nombre.freel=arg[0].nombre.freel*(float)arg[1].nombre.sint;
  }
  else
  {
    if(arg[1].type==NBR)
      a.nombre.freel=(float)arg[0].nombre.sint*arg[1].nombre.freel;
    else
    {
      a.type=NBE;
      a.nombre.sint=arg[0].nombre.sint*arg[1].nombre.sint;
    }
  }
  return a;
}
TParser DIV(TParser *arg)
{
  TParser res;
  float a,b;
  res.type=NBR;
  a=arg[0].nombre.freel;
  if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
  b=arg[1].nombre.freel;
  if(arg[1].type==NBE)
   b=(float)arg[1].nombre.sint;
  res.nombre.freel=a/b;
  return res;

}
TParser NEG(TParser *arg)
{
  TParser a=arg[0];
  if(a.type==NBR)
    a.nombre.freel=-a.nombre.freel;
  else
    a.nombre.sint=-a.nombre.sint;
  return a;
}
TParser MOD(TParser *arg)
{
  TParser a;
  a.type=NBE;
  if(arg[0].type==NBE && arg[1].type==NBE)
  {
    if((a.nombre.sint=arg[0].nombre.sint%arg[1].nombre.sint)<0)
      a.nombre.sint+=arg[1].nombre.sint;
  }
  return a;
}
TParser POW(TParser *arg)
{
  TParser res;
  float a,b;
  res.type=NBR;
  a=arg[0].nombre.freel;
  if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
  b=arg[1].nombre.freel;
  if(arg[1].type==NBE)
   b=(float)arg[1].nombre.sint;
  res.nombre.freel=pow(a,b);
  return res;
}

TParser FACT(TParser *arg)
{
  TParser a;
  int res;
  a.type=NBE;
  if(arg[0].type==NBE)
  {
    res=arg[0].nombre.sint;
    for(a.nombre.sint=1;res>0;res--)
      a.nombre.sint*=res;
  }
  return a;
}

TParser SIN(TParser *arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=sin(a);
 return res;
}
TParser COS(TParser *arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=cos(a);
 return res;
}
TParser TAN(TParser *arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=tan(a);
 return res;
}
TParser SQRT(TParser *arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=sqrt(a);
 return res;
}
TParser EXP(TParser* arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=exp(a);
 return res;
}
TParser LN(TParser* arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=log(a);
 return res;
}
TParser LOG(TParser* arg)
{
 TParser res;
 float a;
 res.type=NBR;
 a=arg[0].nombre.freel;
 if(arg[0].type==NBE)
   a=(float)arg[0].nombre.sint;
 res.nombre.freel=log10(a);
 return res;
}

TParser ROUND(TParser arg[])
{
  TParser a=arg[0];
  if(a.type==NBR)
  {
    a.type=NBE;
    a.nombre.sint=(signed int)(a.nombre.freel+0.5);
  }
  return a;
}

TParser NOT(TParser arg[])
{
  TParser a;
  a.type=NBE;
  if(arg[0].type==NBE)
    a.nombre.sint=~arg[0].nombre.sint;
  return a;
}
TParser AND(TParser *arg)
{
  TParser a;
  if(arg[0].type==NBE && arg[1].type==NBE)
    a.nombre.sint=arg[0].nombre.sint & arg[1].nombre.sint;
  a.type=NBE;
  return a;
}
TParser OR(TParser *arg)
{
  TParser a;
  if(arg[0].type==NBE && arg[1].type==NBE)
    a.nombre.sint=arg[0].nombre.sint | arg[1].nombre.sint;
  a.type=NBE;
  return a;
}

/*Fichier bparser.h*/
/*
Probleme lie a l'enchainement d'un nombre avec une
fonction ou une variable ou une constante commencant
par la lettre e suivit d'un chiffre
ex:
12e0 <> 12*e0
12*10^0=12 <> 12*e0 avec e une variable
*/
unsigned int HexToInt(char phrase[]);
unsigned int BinToInt(char phrase[]);
enum ELexeme{VIDE=0,OPB=1,OPUG=2,OPUD=4,FONC=8,NBE=16,NBR=32,
	     VAR=64,PNOEUD=128,CONSTE=256,EXPR=512,HEX=1024,
	     /*PFEUILLE=2048,*/BIN=4096,FIN=8192};

typedef struct lexeme
{
  unsigned short type;
  signed short lignedeb,lignefin;
  unsigned short index;
  struct lexeme *avant,*suivant;
} lexeme;

typedef struct information
{
  unsigned int type:4;
  unsigned int priorite:4;
} information;

typedef union variant
{
  float freel;
  signed int sint;
  struct noeud *pnoeud;
  struct feuille *pfeuille;
  unsigned short var;
} variant;

typedef struct variable
{
  char *nom;
  char type;
  union variant donnee;
} variable;

class TParser
{
 private:
  unsigned int EstCeUnNombre(char phrase[],int *type);
  unsigned int EstCeUneExpression(char phrase[],int *nbarg);
  unsigned int EstCeUnOperateur(char phrase[],int *indeop);
  unsigned int EstCeUneVariable(char phrase[],int *index);
  unsigned int CmpRefToStr(char *str1,char *str2);
  unsigned int AnalyseLexical(char phrase[],lexeme *lex);
  unsigned int AnalyseGrammatical(lexeme *lex);
  unsigned int EstCeUnNombreHex(char phrase[]);
  unsigned int EstCeUnNombreBin(char phrase[]);
  void CalculExpression();
  void CreeArbre(char phrase[],lexeme *lex);

  static struct operateur op[];
  static struct variable var[];
  static int nbop,nbvar;
 public:
   unsigned char type; // Peut contenir les lexemes<256
   union variant nombre;
   TParser();
   ~TParser();
   void Parse(char phrase[]);
   TParser Calcul();
   void FreeExpression();
};


typedef struct operateur
{
  char *nom;
  TParser (*f)(TParser *);
  information info;
} operateur;

typedef struct noeud
	{
	  short indexop;
	  TParser nbG;
	  TParser nbD;
	} noeud;

typedef struct feuille          /*Sert uniquement pour les appels de fonctions*/
	{
	  short indexfonc;
	  TParser *arg;  /*Permet de conserver un tableau d'expressions*/
	} feuille;       /*de la taille operateur[indexfonc].info.priorite*/

class ParserExcept
{
 public:
  int code;
  int PosCourant;
  ParserExcept();
  void affiche(HWND hwnd,char *text);
};

Conclusion

il faut encore ameliorer la presentation des erreurs style, syntaxe error....
car j'ai fait une gestion des erreurs un peut a l'ancienne (mais ca marche) et ce n'est pas trop satisfaisant donc un jour si j'ai le temps.....
 

Historique

20 janvier 2005 22:56:16 :
passage de C à C++

Commentaires et avis

signaler à un administrateur
Commentaire de victorcoasne le 11/09/2004 20:22:38

Un peu long (ça donne presque pas envie de lire)

Faire aussi une petite interface console DOS pour utiliser ça , ça serait pas mal avec aussi un zip (et une capture) ce serait mieux !

signaler à un administrateur
Commentaire de Kirua le 12/09/2004 19:16:53

tes fonctions cos, tan, exp... sont super redondantes, il y a systématiquement un bout de code copié/collé, c'est pas pratique si tu dois faire une màj. et puis tu peux pas utiliser des fonctions multi-paramètres avec ce système, je me trompe? tu pourrais facilement (et proprement ^^) rajouter une fonction min(x,y) par exemple?

à part ça, boh si ça marche, c'est bon hein ^^

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 10:44:24

spécifie que ton parser est en C (on pourrait s'attendre a trouver du lex...)

sinon, ça me semble bcp trop redondant est loin d'etre en POO

++
Nono.

signaler à un administrateur
Commentaire de keos31 le 13/09/2004 10:59:43

j'ai voulut faire une bibliotheque pouvant comprendre les expressions mathematique, comme ca si dans un projet on a besoin de renter des chiffres dans un edit ou autre on peut directement taper une expression mathematique au lieu de tout faire a la calculette et de rentrer uniquement le resultat!
pour ce qui est du zip, mon pc ayant quelque probleme j'ai plus winzip......et enfin oui on peut rajouter proprement des fonctions ayant au max 15 parametres, exemple:

declaration:

"min",(expression(*)(expression *))MIN,{FONC,2}
                                                                           ^
                                                                            |
                                                         0<nb parametres<=15
fonctions:

expression MIN(expression *arg)
{
  /*en entree on a arg[0] et arg[1]*/
}


petit exemple d'utilisation:

#include<bparser.h>

main(){
char Sexp="1+5"
expression Aexp,res;

Aexp=Parse(exp);
res=Calcul(&Aexp);
if(res.type==NBR)
  printf("%e\n",res.nombre.freel);
else
  printf("%d\n",res.nombre.sint);
}

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 11:17:54

#include"bparser.h"
préférable

pour un nombre de param variable , utilise: "..."

exemple:

#include <STDARG.H>
void BString::format(const char*modele, ...)
{
/// ------------------------------------------------------------------------------
/// ---------------- BString::format(const BString& modele ,... ) ----------------
/// ------------------------------------------------------------------------------
/// -----  Objectif : init en modèle formatage d'une chaine
/// -----  Auteur(s) : Bruno CELLE 01/09/04
/// -----  PreCond : /
/// -----  PostCond : /
/// -----  Etat : 1 (-1<0<1<2)
/// ------------------------------------------------------------------------------
/// -----  const char* modele : modèle...
/// -----  ... : nombre variable de param
/// ------------------------------------------------------------------------------
/// -----  Var Utilisées de la classe (1) : m_str
/// -----  Var Muettes (cf.partie préc) (1) : modele
/// -----  Var Internes à la fonction (1) : liste
/// -----  Var In  (2) : m_str ,modele
/// -----  Var In  Globales Constantes (1) : TAILLE_MAX
// inspiré de CString::format  de Soilwork
ALLOUEn(m_str,char,TAILLE_MAX);
va_list liste;
//seul warning DevC++ à subsister... si modele est un BString => transfo en const char*
va_start(liste, modele);
vsprintf(m_str, modele, liste);
va_end(liste);
//TODO ; check présence du '\0'
//reallocation(strlen(tmp)+1);
majTaille();
}

Nono.

signaler à un administrateur
Commentaire de keos31 le 13/09/2004 14:30:24

je connait cet methode pour avoir un nombre de parametres variable mais avec mon compilateur j'arrivais pas a declarer un pointeur sur une fonction utilisant cet technique de plus ma facon de faire est finalement la meilleur (je pense), je ne passe qu'un seul parametre par la pile et je peut allouer directement la place necessaire a mon tableau.....
sinon vous l'avez essaye mon code?
si vous trouvez des bugs e-mailer moi.......
keos31

signaler à un administrateur
Commentaire de Kirua le 13/09/2004 17:23:32

je vais pas tester ton code parce que la longueur me rebute et que ma version C++ me satisfait ^^ (je l'ai pas postée parce que je trouve qu'il y en a déjà trop), mais au vu de ce que tu viens d'expliquer sur la souplesse des paramètres, je reconnais que ta lib a de la classe (ahah, dsl). vrmnt dommage que ça ne soit pas OO, et encore, t'aurais pas eu besoin de POO pour condenser tt ça, ça fait vrmnt peur la longueur :/

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 17:26:35

poste donc ton src Kiru...

ça lui pemettra d'apprendre...

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 17:26:45

poste donc ton src Kiru...

ça lui pemettra d'apprendre...

signaler à un administrateur
Commentaire de Kirua le 13/09/2004 17:36:14

boh, c'est juste une approche différente du problème (POO), parce que du pt de vue technique, le C sera plus rapide que le C++, je n'ai pas de gestion d'erreur et je ne gère rien de plus que lui (fonctions multi-paramétriques, constantes, expr arithmétiques et logiques, "tous" les opérateurs classiques... ah si: ça désalloue la mémoire, lol :p

à l'occasion je posterai pê alors, mais pas ce soir je pense.
sinon, c'est vrai que ça peut être vrmnt bien pr permettre aux gens de saisir une expression plutôt qu'un nombre ds une appli, j'avais créé mon code pr le challenge, sans but précis, ça c'est tt bon ^^ ah, puis c utile pr créer un langage de script aussi!

signaler à un administrateur
Commentaire de Kirua le 13/09/2004 17:39:17

juste une chose: rajoute deux fonctions: DegToRad et RadToDeg, pour faire les conversions d'angles. ça sert tjs ;)

signaler à un administrateur
Commentaire de keos31 le 13/09/2004 18:46:49

magic_nono toi qui  a l'air caler en programmation, tu pourrai pas me dire pourquoi mon compiilateur c/c++ ne m'autorise pas a creer des pointeur sur des fonctions ayant des un nombre de parametres variable plutot que de me reprendre sur #include "bparser.h". ceci dit tu m'as retirer une grosse epine du pied...

  merci d'avance

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 19:32:02

>
Keos> lol

ui,

J'ai lu qu'il fallait un proto défini pr les ptr de fonctions

a priori, ... est un nb variable de param... ça colle dc certainement po bien...

C ptet po géré...
je ferai des essais ac VC7, je te communiquerai le rsltt


qu'utilises-tu comme compilo?
___

astuce de prog

passe tes param en spécifiant const
si la var n'est po modifiée

++

signaler à un administrateur
Commentaire de kheolane le 13/09/2004 20:13:06

magic_Nono, j'aurais honte d'écrire:
_ #include"bparser.h" préférable _
au regard du source plus haut qui a compilé du premier coup sous FreeBSD.

T&#8217;ergotes, ok pour la POO mais ça n'empêche pas d'avoir de bonnes idées en C, d'autant plus que ça fonctionne, je le test actuellement.
A mon avis il a déjà les connaissances sur la POO, sans doute a t-il trouvé plus judicieux de le faire en C. pourquoi ? je sais pas.
A l'avenir poste des critiques constructive, tu pollueras moins le forum.

Quand la rigueur est de mise....

PS: Ce message est écrit pour les newbies qui auraient "honte" de poster leurs sources de peur de recueillir des commentaires de ce genre et uniquement pour ceci (cad n&#8217;a pas d&#8217;autre caractère que celui énoncé ci avant).

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 20:55:49

ho !
calmos,

C juste un pe critiq, mé pr faire avancer
Je trouve ce srcc plutot bien progué

et il est tt a fait possible de faire du C en POO like
la preuve...
(struct...)

Sérieux, aucune mauvaises pensée...
mais si tu es si fort,
donne dc des coups de pouce sur des prj
& produit dc des srce

l'hatitude consommateur de certain est déplorable


on pe ts s'améliorer, & progresser en partageant
C mon point de vu
après, on choisi son camp
++

signaler à un administrateur
Commentaire de Kirua le 13/09/2004 21:01:48

les " sont en effet préférables pour les includes de fichiers locaux. les < > sont, par convention, réservés aux librairies du compilo. magic nono n'a pas a avr honte de l'avoir dit...

sois pas agressif.

signaler à un administrateur
Commentaire de magic_Nono le 13/09/2004 21:11:11

merci Kirua

signaler à un administrateur
Commentaire de fraboulet le 07/10/2005 06:12:40

Et Lex/yacc dans tout ça?

signaler à un administrateur
Commentaire de magic_Nono le 07/10/2005 10:53:26

Absent

cf mon 1er com sur cette page

Magicalement

signaler à un administrateur
Commentaire de victorcoasne le 08/10/2005 11:04:28

Si tu n'as plus WinZip essaye WinRAR ! ;-)

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,530 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.