00001 #pragma ident "$Id: Expression.cpp 2944 2011-10-27 08:04:41Z yanweignss $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032 #include <sstream>
00033 #include <map>
00034 #include <list>
00035 #include <vector>
00036 #include <string>
00037 #include <ctype.h>
00038 #include <math.h>
00039
00040 #include "icd_200_constants.hpp"
00041 #include "StringUtils.hpp"
00042 #include "Expression.hpp"
00043
00044 namespace gpstk
00045 {
00046
00047 double Expression::BinOpNode::getValue()
00048 throw (ExpressionException)
00049 {
00050
00051
00052
00053 double leftVal = left->getValue();
00054 double rightVal = right->getValue();
00055
00056 if (op=="+") return leftVal + rightVal;
00057 if (op=="-") return leftVal - rightVal;
00058 if (op=="*") return leftVal * rightVal;
00059 if (op=="/") return leftVal / rightVal;
00060
00061
00062 GPSTK_THROW(ExpressionException());
00063
00064 }
00065
00066 double Expression::FuncOpNode::getValue()
00067 throw (ExpressionException)
00068 {
00069
00070 double rightVal = right->getValue();
00071
00072 if (op=="cos") return ::cos(rightVal);
00073 if (op=="sin") return ::sin(rightVal);
00074 if (op=="tan") return ::tan(rightVal);
00075 if (op=="acos") return ::acos(rightVal);
00076 if (op=="asin") return ::asin(rightVal);
00077 if (op=="atan") return ::atan(rightVal);
00078 if (op=="exp") return ::exp(rightVal);
00079 if (op=="abs") return ::fabs(rightVal);
00080 if (op=="sqrt") return ::sqrt(rightVal);
00081 if (op=="log") return ::log(rightVal);
00082 if (op=="log10") return ::log10(rightVal);
00083
00084
00085 GPSTK_THROW(ExpressionException());
00086 }
00087
00088 std::ostream& Expression::FuncOpNode::print(std::ostream& ostr) {
00089 ostr << op;
00090 right->print(ostr);
00091
00092 return ostr;
00093 }
00094
00095 std::ostream& Expression::BinOpNode::print(std::ostream& ostr) {
00096 ostr << "(";
00097 left->print(ostr);
00098 ostr << op;
00099 right->print(ostr);
00100 ostr << ")";
00101
00102 return ostr;
00103 }
00104
00105 void Expression::VarNode::setValue(double newValue)
00106 {
00107 value=newValue;
00108 hasValue=true;
00109 };
00110
00111 double Expression::VarNode::getValue(void)
00112 throw (ExpressionException)
00113 {
00114 if (!hasValue)
00115 {
00116 ExpressionException ee("Variable " + name + " undefined.");
00117 GPSTK_THROW(ee);
00118 }
00119
00120 return value;
00121 }
00122
00123 Expression::Token::Token(std::string iValue, int iPriority,
00124 bool isOp=false)
00125 :
00126 value(iValue), priority(iPriority), used(false), resolved(false),
00127 expNode(0), isOperator(isOp)
00128 {
00129 }
00130
00131 void Expression::Token::print(std::ostream& ostr)
00132 {
00133 ostr <<" Value '" << value;
00134 ostr << "', operation priority " << priority << ", ";
00135
00136 if (isOperator) ostr << "operator";
00137 else ostr << "not operator";
00138
00139 ostr << ", ";
00140
00141 if (used) ostr << "used,";
00142 else ostr << "not used,";
00143
00144 if (resolved) ostr << "resolved";
00145 else ostr << "not resolved ";
00146
00147 return;
00148 }
00149
00150 bool Expression::operatorsDefined = false;
00151 std::map<std::string,int> Expression::operatorMap;
00152 std::map<std::string,std::string> Expression::argumentPatternMap;
00153
00154 Expression::Expression(const std::string& istr)
00155 : root(0)
00156 {
00157 defineOperators();
00158 setExpression(istr);
00159 }
00160
00161 void Expression::setExpression(const std::string& istr)
00162 {
00163 dumpLists();
00164 tokenize(istr);
00165 buildExpressionTree();
00166 }
00167
00168 Expression::Expression(void)
00169 : root(0)
00170 {
00171 defineOperators();
00172 setExpression("0");
00173 }
00174
00175 Expression::Expression(const Expression& rhs)
00176 {
00177 defineOperators();
00178 std::ostringstream ostr;
00179 rhs.print(ostr);
00180 setExpression(ostr.str());
00181 }
00182
00183 Expression& Expression::operator=(const Expression& rhs)
00184 {
00185 std::ostringstream ostr;
00186 rhs.print(ostr);
00187 setExpression(ostr.str());
00188 return (*this);
00189 }
00190
00191 void Expression::dumpLists(void)
00192 {
00193
00194 std::list<ExpNode *>::iterator i= eList.begin(), itemp;
00195 while (i!= eList.end())
00196 {
00197 itemp=i;
00198 itemp++;
00199 delete(*i);
00200 i=itemp;
00201 }
00202 std::list<ExpNode *> emptyENodeList;
00203 eList = emptyENodeList;
00204 std::list<Token> emptyTokenList;
00205 tList = emptyTokenList;
00206 root =0;
00207 }
00208
00209
00210 void Expression::defineOperators(void)
00211 {
00212 if (!operatorsDefined)
00213 {
00214 operatorMap["+"]=1;
00215 operatorMap["-"]=1;
00216 operatorMap["*"]=2;
00217 operatorMap["/"]=2;
00218 operatorMap["^"]=3;
00219 operatorMap["cos"]=4;
00220 operatorMap["sin"]=4;
00221 operatorMap["tan"]=4;
00222 operatorMap["acos"]=4;
00223 operatorMap["asin"]=4;
00224 operatorMap["atan"]=4;
00225 operatorMap["exp"]=4;
00226 operatorMap["abs"]=4;
00227 operatorMap["sqrt"]=4;
00228 operatorMap["log"]=4;
00229 operatorMap["log10"]=4;
00230
00231 argumentPatternMap["+"]="RL";
00232 argumentPatternMap["-"]="RL";
00233 argumentPatternMap["*"]="RL";
00234 argumentPatternMap["/"]="RL";
00235 argumentPatternMap["^"]="RL";
00236 argumentPatternMap["cos"]="R";
00237 argumentPatternMap["sin"]="R";
00238 argumentPatternMap["tan"]="R";
00239 argumentPatternMap["acos"]="R";
00240 argumentPatternMap["asin"]="R";
00241 argumentPatternMap["atan"]="R";
00242 argumentPatternMap["exp"]="R";
00243 argumentPatternMap["abs"]="R";
00244 argumentPatternMap["sqrt"]="R";
00245 argumentPatternMap["log"]="R";
00246 argumentPatternMap["log10"]="R";
00247
00248 operatorsDefined = true;
00249 }
00250 }
00251
00252 Expression::~Expression(void)
00253 {
00254 std::list<ExpNode *>::iterator i;
00255 for (i=eList.begin(); i!=eList.end(); i++)
00256 delete (*i);
00257 }
00258
00259 void Expression::tokenize(const std::string& istr)
00260 {
00261 using namespace std;
00262
00263
00264
00265 stringstream ss(istr);
00266 string str;
00267 char tempc;
00268 vector<int> baseOrder;
00269 int currentOrder = 0;
00270
00271 while (ss >> skipws >> tempc)
00272 {
00273 bool strip=false;
00274
00275 if (tempc == '(')
00276 {
00277 currentOrder+=10;
00278 strip=true;
00279 }
00280
00281 if (tempc == ')')
00282 {
00283 currentOrder-=10;
00284 strip=true;
00285 }
00286
00287 if (!strip)
00288 {
00289 baseOrder.push_back(currentOrder);
00290 str.append(&tempc,1);
00291 }
00292 }
00293
00294 map<string, int>::iterator it;
00295 list<int> breaks;
00296 breaks.push_back(0);
00297
00298
00299
00300
00301
00302
00303 map<int,int> breakPriority;
00304
00305
00306
00307
00308 map<int, bool> breakType;
00309
00310 for (it=operatorMap.begin(); it!=operatorMap.end(); it++)
00311 {
00312 int position = 0;
00313 while ((position=str.find(it->first,position+1))!=string::npos)
00314 {
00315
00316 bool sciNotation=false;
00317 if ((it->first=="+") || (it->first=="-"))
00318 {
00319 sciNotation =
00320 ( ( (str.substr(position-1,1)=="E") ||
00321 (str.substr(position-1,1)=="e") ) &&
00322 (isdigit(str.substr(position-2,1).c_str()[0])) &&
00323 (isdigit(str.substr(position+1,1).c_str()[0])) );
00324 }
00325
00326 if (!sciNotation)
00327 {
00328 breaks.push_back(position);
00329 breakPriority[position] = it->second + baseOrder[position];
00330 breakType[position] = true;
00331
00332 int operandPos = position+(it->first.size());
00333 breaks.push_back(operandPos);
00334 breakPriority[operandPos] = baseOrder[operandPos];
00335 breakType[operandPos] = false;
00336 }
00337 }
00338
00339 }
00340 breaks.push_back(str.size());
00341
00342
00343
00344
00345
00346 breaks.sort();
00347
00348 list<string> tokens;
00349 list<int>::iterator ls = breaks.begin(), rs = ls;
00350
00351 for (rs++ ;rs!=breaks.end(); rs++, ls++)
00352 {
00353 if (*rs!=*ls)
00354 {
00355 string thisToken = str.substr(*ls,(*rs)-(*ls));
00356 int thisOop = breakPriority[*ls];
00357 bool isOp = breakType[*ls];
00358
00359
00360 Token tok(thisToken,thisOop, isOp);
00361
00362 if ( tok.getOperator() )
00363 tok.setArgumentPattern( argumentPatternMap[thisToken] );
00364
00365
00366 ExpNode *expNode;
00367
00368
00369 if (!isOp)
00370 {
00371 char testChar = thisToken.c_str()[0];
00372 if (isalpha(testChar))
00373 expNode = new VarNode(thisToken);
00374 else
00375 expNode = new ConstNode(StringUtils::asDouble(thisToken));
00376 eList.push_back(expNode);
00377 tok.setNode(expNode);
00378 tok.setResolved(true);
00379 }
00380
00381
00382 tList.push_back(tok);
00383 }
00384 }
00385 }
00386
00387
00388 int Expression::countResolvedTokens(void)
00389 {
00390 using namespace std;
00391
00392 list<Token>::iterator itt;
00393
00394
00395 int totalResolved=0;
00396 for (itt = tList.begin(); itt!=tList.end(); itt++)
00397 {
00398 if (itt->getResolved()) totalResolved++;
00399 }
00400 return totalResolved;
00401 }
00402
00403
00404 void Expression::buildExpressionTree(void)
00405 {
00406 using namespace std;
00407
00408 list<Token>::iterator itt, targetToken;
00409
00410 if ((tList.size()==1)&&(tList.begin()->getResolved()))
00411 {
00412 root = tList.begin()->getNode();
00413 return;
00414 }
00415
00416 int totalResolved = countResolvedTokens();
00417
00418 while (totalResolved<tList.size())
00419 {
00420
00421
00422
00423
00424
00425
00426
00427 itt=tList.begin();
00428 int highestP = -1;
00429
00430 for (itt = tList.begin(); itt !=tList.end(); itt++)
00431 {
00432 if ( itt->getOperator() && !itt->getResolved() )
00433 {
00434 if (itt->getPriority()>highestP)
00435 {
00436 targetToken = itt;
00437 highestP=itt->getPriority();
00438 }
00439 }
00440 }
00441
00442 if ( targetToken->getOperator() )
00443 {
00444
00445 list<Token>::iterator leftArg=targetToken, rightArg=leftArg;
00446
00447 stringstream argstr(targetToken->getArgumentPattern());
00448 char thisArg;
00449 bool searching;
00450
00451 while (argstr >> thisArg)
00452 {
00453 switch (thisArg) {
00454 case 'R':
00455 searching = true;
00456
00457 while (searching)
00458 {
00459 if (rightArg==tList.end())
00460 cout << "Mistake, no right arg for " << targetToken->getValue() << endl;
00461 else
00462 rightArg++;
00463
00464 searching = (rightArg->getUsed());
00465 }
00466
00467 break;
00468
00469 case 'L':
00470
00471
00472 searching=true;
00473
00474 while (searching)
00475 {
00476 if (leftArg == tList.begin())
00477 cout << "Mistake - no right argument for operator?!" << endl;
00478 else
00479 leftArg--;
00480
00481 searching = (leftArg->getUsed());
00482 }
00483
00484 break;
00485 }
00486 }
00487
00488
00489 if (targetToken->getArgumentPattern()=="RL")
00490 {
00491 ExpNode *opNode =
00492 new BinOpNode(targetToken->getValue(),leftArg->getNode(), rightArg->getNode());
00493 targetToken->setNode(opNode);
00494 eList.push_back(opNode);
00495
00496 targetToken->setResolved(true);
00497 root = targetToken->getNode();
00498
00499 leftArg->setUsed();
00500 rightArg->setUsed();
00501 }
00502
00503 if (targetToken->getArgumentPattern()=="R")
00504 {
00505 ExpNode *opNode =
00506 new FuncOpNode(targetToken->getValue(),rightArg->getNode());
00507 targetToken->setNode(opNode);
00508
00509 eList.push_back(opNode);
00510
00511 targetToken->setResolved(true);
00512 root = targetToken->getNode();
00513
00514 rightArg->setUsed();
00515 }
00516
00517 }
00518
00519
00520 totalResolved = countResolvedTokens();
00521 }
00522
00523 }
00524
00525
00526 bool Expression::set(const std::string name, double value)
00527 {
00528 using namespace std;
00529
00530 bool gotSet;
00531
00532 std::list<ExpNode *>::iterator i;
00533 int t;
00534
00535 for (t=0, i=eList.begin(); i!=eList.end(); t++, i++)
00536 {
00537 VarNode *vnode = dynamic_cast<VarNode *> (*i);
00538 if (vnode!=0)
00539 {
00540 if (StringUtils::upperCase(vnode->name) ==
00541 StringUtils::upperCase(name))
00542 {
00543 vnode->setValue(value);
00544 gotSet = true;
00545 }
00546 }
00547 }
00548
00549 return gotSet;
00550 }
00551
00552
00553 bool Expression::canEvaluate(void)
00554 {
00555 using namespace std;
00556
00557 bool areSet=true;
00558
00559 std::list<ExpNode *>::iterator i;
00560 int t;
00561
00562 for (t=0, i=eList.begin(); i!=eList.end(); t++, i++)
00563 {
00564 VarNode *vnode = dynamic_cast<VarNode *> (*i);
00565 if (vnode!=0)
00566 {
00567 areSet &= vnode->hasValue;
00568 }
00569 }
00570
00571 return areSet;
00572 }
00573
00574 bool Expression::setGPSConstants(void)
00575 {
00576 bool gotSet = false;
00577
00578 gotSet |= set("gamma",(L1_FREQ / L2_FREQ)*(L1_FREQ / L2_FREQ));
00579 gotSet |= set("pi",PI);
00580 gotSet |= set("c",C_GPS_M);
00581 gotSet |= set("c_gps_m",C_GPS_M);
00582 gotSet |= set("l0",OSC_FREQ);
00583 gotSet |= set("f1",L1_MULT);
00584 gotSet |= set("f2",L2_MULT);
00585 gotSet |= set("l1",L1_FREQ);
00586 gotSet |= set("l2",L2_FREQ);
00587 gotSet |= set("wl1",C_GPS_M/L1_FREQ);
00588 gotSet |= set("wl2",C_GPS_M/L2_FREQ);
00589 return gotSet;
00590 }
00591
00592 bool Expression::setRinexObs(const RinexObsData::RinexObsTypeMap& rotm)
00593 {
00594 bool gotSet = false;
00595
00596 RinexObsData::RinexObsTypeMap::const_iterator i;
00597 for (i=rotm.begin(); i!=rotm.end(); i++)
00598 gotSet |= set(i->first.type, i->second.data);
00599
00600 return gotSet;
00601 }
00602
00603
00604
00605
00606 bool Expression::setSvObsEpoch(const SvObsEpoch& soe)
00607 {
00608 bool gotSet = false;
00609 for (SvObsEpoch::const_iterator i=soe.begin(); i != soe.end(); i++)
00610 {
00611
00612
00613
00614
00615
00616 std::string type, band, attribute;
00617 bool ignore=false;
00618 switch (i->first.type)
00619 {
00620 case ObsID::otRange: type = "C"; break;
00621 case ObsID::otPhase: type = "L"; break;
00622 case ObsID::otDoppler: type = "D"; break;
00623 case ObsID::otSNR: type = "S"; break;
00624 case ObsID::otSSI: ignore = true; break;
00625 case ObsID::otLLI: ignore = true; break;
00626 case ObsID::otTrackLen: ignore = true; break;
00627 }
00628
00629 switch (i->first.band)
00630 {
00631 case ObsID::cbL1: band = "1"; break;
00632 case ObsID::cbL2: band = "2"; break;
00633 case ObsID::cbL5: band = "5"; break;
00634 case ObsID::cbE6: band = "6"; break;
00635 case ObsID::cbE5b: band = "7"; break;
00636 case ObsID::cbE5ab: band = "8"; break;
00637 }
00638
00639 switch (i->first.code)
00640 {
00641 case ObsID::tcCA: attribute = "C"; break;
00642 case ObsID::tcP: attribute = "P"; break;
00643 case ObsID::tcY: attribute = "Y"; break;
00644 case ObsID::tcW: attribute = "W"; break;
00645 case ObsID::tcN: attribute = "N"; break;
00646 case ObsID::tcM: attribute = "M"; break;
00647 case ObsID::tcC2M: attribute = "S"; break;
00648 case ObsID::tcC2L: attribute = "L"; break;
00649 case ObsID::tcC2LM: attribute = "X"; break;
00650 case ObsID::tcI5: attribute = "I"; break;
00651 case ObsID::tcQ5: attribute = "Q"; break;
00652 case ObsID::tcIQ5: attribute = "X"; break;
00653 case ObsID::tcA: attribute = "A"; break;
00654 case ObsID::tcB: attribute = "B"; break;
00655 case ObsID::tcC: attribute = "C"; break;
00656 case ObsID::tcBC: attribute = "X"; break;
00657 case ObsID::tcABC: attribute = "Z"; break;
00658 }
00659 if (ignore)
00660 continue;
00661
00662 std::string id = type + band + attribute;
00663
00664 if (id.length() != 3)
00665 std::cout << "Unimplimented ObsID:" << i->first << std::endl;
00666
00667 gotSet |= set(id, i->second);
00668 }
00669 return gotSet;
00670 }
00671
00672 }