Parser (calculette....)

Contenu du snippet

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 / Exemple :


/*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.....

A voir également

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.