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; }
long double Calculation::Resolve(const list<Token*>& tokens) const throw(invalid_argument) { stack<Token*> operators; stack<long double> operands; Token *_operator; long double operand1, operand2; bool error; for (list<Token*>::const_iterator i = tokens.begin(); i != tokens.end(); ++i) { if ((*i)->GetType() == TOK_number) { operands.push((*i)->GetNumber()); continue; } if ((*i)->GetType() == TOK_leftParen) { operators.push(*i); continue; } if ((*i)->GetType() == TOK_rightParen) { error = true; while (!operators.empty()) { _operator = operators.top(); operators.pop(); if (_operator->GetType() == TOK_leftParen) { error = false; break; } if (PopOperands(operands, operand1, operand2)) { try { operands.push(ApplyOperator(_operator, operand1, operand2)); } catch (invalid_argument& e) { throw e; } } else { throw invalid_argument("Too few operands"); } } if (error) throw invalid_argument("The left parenthesis was not found"); if (!operators.empty()) { if (operators.top()->GetType() == TOK_func) { long double value = operands.top(); operands.pop(); operands.push(CallFunction(operators.top(), value)); operators.pop(); } } continue; } if ((*i)->IsOperator()) { if (operators.empty()) { operators.push(*i); continue; } if (operators.top()->GetType() == TOK_leftParen) { operators.push(*i); continue; } try { while (!operators.empty()) { if (operators.top()->GetType() == TOK_leftParen) break; if (CompareOperators(operators.top(), *i)) { if (PopOperands(operands, operand1, operand2)) { operands.push(ApplyOperator(operators.top(), operand1, operand2)); } else throw invalid_argument("Too few operands"); operators.pop(); } else break; } operators.push(*i); } catch (invalid_argument& e) { throw e; } continue; } if ((*i)->GetType() == TOK_func) { operators.push(*i); continue; } throw invalid_argument("Unknown token"); } while (!operators.empty()) { if (PopOperands(operands, operand1, operand2)) { try { operands.push(ApplyOperator(operators.top(), operand1, operand2)); } catch (invalid_argument& e) { throw e; } operators.pop(); } else { throw invalid_argument("Too few operands"); } } if (operands.size() == 0) throw invalid_argument("Something's wrong"); if (operands.size() > 1) throw invalid_argument("The values stack are at least two operands and" " operators stack is empty"); else return operands.top(); }