void Dup::execute(QVector<Litterale*> litterals) const { Litterale* operande = litterals[0]; if (operande!=nullptr){ Litterale* res = operande->clone(); //On a des operandes qui sont des ptr sur des LitteralesNombre -> l'operateur + y est defini -> polymorphisme //On empile notre operande et notre resultat Pile::getInstance().push(operande); Pile::getInstance().push(res); Pile::lastOpname = "DUP"; } else { this->reChargerOperande(litterals); } }
/*! * \brief Calcule la littérale résultante de l'expression */ Litterale* LitteraleExpression::eval() { Interpreteur& inter=Interpreteur::getInstance(); FactoryLitterale& fl=FactoryLitterale::getInstance(); FactoryOperateur& fo=FactoryOperateur::getInstance(); string s(exp); regex e; smatch m; // Traitement des opérateurs unaires s'appliquant à l'expression regex opUnaire("([A-Z](?:[A-Z]|[0-9])*)\\(([^,\\(\\)]+)\\)"); while (std::regex_search (s,m,opUnaire)) { cout<<m[0]<<" "<<m[1]<<" "<<m[2]<<endl; // m[1] l'opérateur et m[2] l'argument if(inter.isOperateur(m[1])) { Litterale* l1 = fl.newLitteraleExpression(m[2])->eval(); Operateur* op= inter.toOperateur(m[1]); return op->applyUnaire(l1); } } // Traitement des opérateurs binaires s'appliquant à l'expression regex opBinaire("([A-Z](?:[A-Z]|[0-9])*)\\(([^,\\(]+),([^,\\(\\)]+)\\)"); while (std::regex_search (s,m,opBinaire)) { //cout<<m[0]<<" "<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl; // m[1] l'opérateur et m[2] l'argument 1 et m[2] l'argument 2 if(inter.isOperateur(m[1])) { Litterale* l1 = fl.newLitteraleExpression(m[2])->eval(); Litterale* l2 = fl.newLitteraleExpression(m[3])->eval(); Operateur* op= inter.toOperateur(m[1]); return op->applyBinaire(l1,l2); } } // Remplacement des variables par leur contenu regex atome("((?:[[:upper:]]{1})(?:[[:upper:]]|[[:digit:]])*)"); while (regex_search(s,m,atome)) { LitteraleAtome* var = LitteraleAtome::getVar(m[1]); if(var) { Litterale* c = var->getValeur(); s.replace(s.find(m[0]), m[0].length(), c->toString()); } } // Traitement des groupes parenthésés // Le but est de ne se retrouver qu'avec // une suite d'opérations arithmétiques sans parenthèses regex paren("\\(([^\\(]*?)\\)"); while (regex_search(s,m,paren)) { //cout<<m[0]<<" va être remplcé par "<<m[1]<<endl; Litterale* c = fl.newLitteraleExpression(m[1])->eval(); //cout<<"av. "<<s<<endl; s.replace(s.find(m[0]), m[0].length(), c->toString()); //cout<<"apr. "<<s<<endl; } // Traitement des + et - regex somme("([^\\+]*[1-9])([\\+-])(.+)"); if (regex_search(s,m,somme)) { //cout<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl; // Conversion en littérale des deux cotés Litterale* l1=fl.newLitteraleExpression(m[1])->eval(); // On converti en littérale la partie gauche Litterale* l2=fl.newLitteraleExpression(m[3])->eval(); // On converti en littérale la partie droite // Création de l'opérateur OperateurNumerique* op=fo.newOperateurNumerique(m[2]); // Application du résultat Litterale* l3=op->applyBinaire(l1, l2); return l3; } // Traitement des * et / regex produit("([^\\+]*[1-9])([\\*/])(.+)"); if (regex_search(s,m,produit)) { //cout<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl; // Conversion en littérale des deux cotés Litterale* l1=fl.newLitteraleExpression(m[1])->eval(); // On converti en littérale la partie gauche Litterale* l2=fl.newLitteraleExpression(m[3])->eval(); // On converti en littérale la partie droite // Création de l'opérateur OperateurNumerique* op=fo.newOperateurNumerique(m[2]); // Application du résultat Litterale* l3=op->applyBinaire(l1, l2); return l3; } // On vérifie que ce n'est pas tout simplement une littérale if(inter.isLitterale(s)) { return inter.toLitterale(s); } return nullptr; }
Litterale* Expression::evaluer() const{ QString s = value; //On vire les ' s=s.remove(0,1); s=s.remove(s.length()-1,s.length()); QString::iterator it = s.begin(); //QString contenant le résultat QString postfix; //Stack d'opérations QStack<QString> stack; //Map des opérateurs const QMap<QString, Operateur*> op_map = OperateurFactory::getMap(); //Map de tous les symboles const QMap<QString,WordIdentifier*>& interpretation_map = Controleur::getInterpretationMap(); //Traduction de Infix vers Postfix QString tmp; bool found; while(it!=s.end()){ found=false; if(*it==' ' || *it==','){ it++; continue; } //Verification que ce n'est pas une litterale avec 2 symboles exemple : Expression ou Programme if(tmp == "" && interpretation_map.find(*it)!=interpretation_map.end()){ WordIdentifier *identifier = interpretation_map.find(*it).value(); WordIdentifier *try1; WordIdentifier *try2; try1=dynamic_cast<RecursiveEncapsulatorIdentifier*>(identifier); try2=dynamic_cast<EncapsulatorIdentifier*>(identifier); if(try1 || try2) { throw LitteraleException("Litterale "+ QString(*it) +" non permise","Inconnu"); } } //On tombe dans le cas ou on a une valeur while(it!=s.end() && ((*it<='9' && *it>='0') || (interpretation_map.find(*it)!=interpretation_map.end()))){ tmp+=*it; if(it!=s.end()) it++; } //Pour vider ce qu'on a trouvé if(tmp!=""){ postfix+=tmp+" "; tmp.clear(); found=true; } //On tombe dans le cas d'un morçeau de texte if((*it<='Z' && *it>='A')){ while(it!=s.end() && ((*it<='Z' && *it>='A') || (*it<='9' && *it>='0'))){ tmp+=* it; if(it!=s.end()) it++; } if(isOperator(tmp)){ found=true; while(!stack.empty() && stack.top() != "(" && CompareOperators(stack.top(),tmp)<=0){ postfix += stack.top()+" "; stack.pop(); } stack.push(tmp); tmp.clear(); } else if(isVariable(tmp)){ found=true; Litterale* l = VariablesManager::getVariable(tmp); if(estdeType<Programme>(l)) throw OperateurException("Un programme est dans l'expression !"); QString rep = l->toString(); int length_it = s.indexOf(tmp); s.replace(tmp,rep); it = s.begin(); for(int i=0; i<length_it;i++,it++); tmp.clear(); } else throw(LitteraleException("Le mot "+tmp+" est inconnu","Inconnu")); } if(*it=='('){ stack.push(*it); if(it!=s.end()) it++; found=true; } if(*it==')'){ while(stack.top()!="("){ postfix+= stack.top()+" "; stack.pop(); } stack.pop(); if(it!=s.end()) it++; found=true; } //On tombe dans le cas d'un opérateur à caractère if(!found){ while(it!=s.end() && !op_map.contains(tmp)){ tmp+=*it++; } if(it==s.end() && !op_map.contains(tmp)) throw LitteraleException("Expression non valide dès "+tmp,"Expression"); while(!stack.empty() && stack.top() != "(" && CompareOperators(stack.top(),tmp)<=0){ postfix += stack.top()+" "; stack.pop(); } stack.push(tmp); tmp.clear(); } } while(!stack.empty()){ postfix+= stack.top() + " "; stack.pop(); } MainWindow::getInstanceMainWindow()->getNextCommande(postfix,"INFIX"); return nullptr; }