Changeset 2512 in Sophya
- Timestamp:
- Mar 16, 2004, 12:49:33 AM (22 years ago)
- Location:
- trunk/SophyaLib/SysTools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/SysTools/cexpre.h
r2510 r2512 15 15 16 16 //! Exception class used by CExpressionEvaluator 17 class CExprException : PException {17 class CExprException : public PException { 18 18 public: 19 19 explicit CExprException(const char * m) : PException(m) {} -
trunk/SophyaLib/SysTools/commander.cc
r2483 r2512 7 7 #include "strutil.h" 8 8 #include "strutilxx.h" 9 #include "cexpre.h" 10 #include "rpneval.h" 9 11 #include "srandgen.h" 10 12 … … 831 833 } 832 834 else if ((tokens.size() > 0) && (tokens[0] == "=")) { 833 // x = RPNExpression (Evaluation d'expression RPN) 834 tokens[0] = kw; 835 int rcev = EvalRPNExpr(tokens, s); 836 if (rcev) { 837 cerr << "Commander::Interpret() evaluation (RPN) syntax Error ! " << "line: " << s << endl; 835 // x = Expression 836 try { 837 CExpressionEvaluator cex(tokens[1]); 838 double res = cex.Value(); 839 char cbuff[64]; 840 sprintf(cbuff,"%g",res); 841 string vv = cbuff; 842 SetVariable(kw, vv); 843 } 844 catch (CExprException& cexerr) { 845 cerr << "Commander::Interpret() evaluation Error : \n " << "line: " << s 846 << " \n Msg=" << cexerr.Msg() << endl; 838 847 _xstatus = 98; 839 848 return(98); 840 849 } 841 return(0);842 850 } 843 851 else if (kw == "defscript") { // definition de script … … 1236 1244 else { 1237 1245 if (idx >= (*it).second.size()) 1238 for(int j=(*it).second.size(); j< idx; j++) (*it).second.push_back("");1239 (*it).second .push_back(val);1246 for(int j=(*it).second.size(); j<=idx; j++) (*it).second.push_back(""); 1247 (*it).second[idx] = val; 1240 1248 fg = true; 1241 1249 } … … 1404 1412 } 1405 1413 1406 /* Operations sur le stack RPN */1407 inline bool Check_myRPNStack_(stack<double>& s, double& x, string& line)1408 {1409 if (s.empty()) {1410 cerr << "Commander::EvalRPNExpr: syntax error / empty RPN stack " << line << endl;1411 return true;1412 }1413 else x = s.top();1414 return false;1415 }1416 inline bool Check_myRPNStack_(stack<double>& s, double& x, double& y, string& line)1417 {1418 if (s.size() < 2) {1419 cerr << "Commander::EvalRPNExpr: syntax error / RPN stack size < 2 " << line << endl;1420 return true;1421 }1422 else {1423 x = s.top(); s.pop(); y = s.top();1424 }1425 return false;1426 }1427 1428 inline void Print_myRPNStack_(stack<double> s)1429 {1430 if (s.empty())1431 cout << "Commander::EvalRPNExpr/PrintStack: Empty stack " << endl;1432 else {1433 int k = 0;1434 cout << "Commander::EvalRPNExpr/PrintStack: Size()= " << s.size() << endl;1435 while( !s.empty() ) {1436 cout << " " << k << ": " << s.top() << " ";1437 if (k == 0) cout << " (x) " << endl;1438 else if (k == 1) cout << " (y) " << endl;1439 else if (k == 2) cout << " (z) " << endl;1440 else cout << endl;1441 s.pop(); k++;1442 }1443 }1444 1414 1445 }1446 1447 int Sum_RPNStack_(stack<double>& s, double& sx, double& sx2, string& line)1448 {1449 sx = sx2 = 0.;1450 int nn = 0;1451 double x = 0.;1452 while( !s.empty() ) {1453 x = s.top(); s.pop();1454 sx += x; sx2 += x*x;1455 nn++;1456 }1457 return(nn);1458 }1459 1460 int Product_RPNStack_(stack<double>& s, double& px, string& line)1461 {1462 px = 1.;1463 int nn = 0;1464 double x = 0.;1465 while( !s.empty() ) {1466 x = s.top(); s.pop();1467 px *= x; nn++;1468 }1469 return(nn);1470 }1471 1472 1415 /* --Methode-- */ 1473 1416 int Commander::EvalRPNExpr(vector<string> & args, string & line) 1474 1417 { 1475 1476 if (args.size() < 2) { 1477 cerr << "Commander::EvalRPNExpr: syntax error / missing arguments " << line << endl; 1478 return(1); 1479 } 1480 else if (args.size() == 2) { 1481 SetVariable(args[0], args[1]); 1482 return(0); 1483 } 1484 1485 double x,y; 1486 x = y = 0.; 1487 stack<double> rpnstack; // Stack des operations en RPN 1488 for(int k=1; k<args.size(); k++) { 1489 // Les 4 operations de base + - * / 1490 if (args[k] == "+") { 1491 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1492 rpnstack.top() = y+x; 1493 } 1494 else if (args[k] == "-") { 1495 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1496 rpnstack.top() = y-x; 1497 } 1498 else if (args[k] == "*") { 1499 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1500 rpnstack.top() = y*x; 1501 } 1502 else if (args[k] == "/") { 1503 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1504 rpnstack.top() = y/x; 1505 } 1506 else if (args[k] == "%") { 1507 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1508 rpnstack.top() = (int)y % (int)x; 1509 } 1510 // Les constantes : e , pi 1511 else if (args[k] == "e") { 1512 rpnstack.push(M_E); 1513 } 1514 else if (args[k] == "pi") { 1515 rpnstack.push(M_PI); 1516 } 1517 // Les fonctions usuelles a 1 argument f(x) 1518 else if (args[k] == "cos") { 1519 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1520 rpnstack.top() = cos(x); 1521 } 1522 else if (args[k] == "sin") { 1523 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1524 rpnstack.top() = sin(x); 1525 } 1526 else if (args[k] == "tan") { 1527 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1528 rpnstack.top() = tan(x); 1529 } 1530 else if (args[k] == "acos") { 1531 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1532 rpnstack.top() = acos(x); 1533 } 1534 else if (args[k] == "asin") { 1535 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1536 rpnstack.top() = asin(x); 1537 } 1538 else if (args[k] == "atan") { 1539 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1540 rpnstack.top() = atan(x); 1541 } 1542 else if (args[k] == "chs") { 1543 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1544 rpnstack.top() = -x; 1545 } 1546 else if (args[k] == "sqrt") { 1547 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1548 rpnstack.top() = sqrt(x); 1549 } 1550 else if (args[k] == "sq") { // x^2 1551 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1552 rpnstack.top() = x*x; 1553 } 1554 else if (args[k] == "log") { 1555 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1556 rpnstack.top() = log(x); 1557 } 1558 else if (args[k] == "log10") { 1559 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1560 rpnstack.top() = log10(x); 1561 } 1562 else if (args[k] == "exp") { 1563 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1564 rpnstack.top() = exp(x); 1565 } 1566 else if (args[k] == "fabs") { 1567 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1568 rpnstack.top() = fabs(x); 1569 } 1570 else if (args[k] == "floor") { 1571 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1572 rpnstack.top() = floor(x); 1573 } 1574 else if (args[k] == "ceil") { 1575 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1576 rpnstack.top() = ceil(x); 1577 } 1578 // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003 1579 else if (args[k] == "deg2rad") { 1580 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1581 rpnstack.top() = x*M_PI/180.; 1582 } 1583 else if (args[k] == "rad2deg") { 1584 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1585 rpnstack.top() = x*180./M_PI; 1586 } 1587 // Les fonctions usuelles a 2 argument f(x,y) 1588 else if (args[k] == "pow") { 1589 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1590 rpnstack.top() = pow(y,x); 1591 } 1592 else if (args[k] == "atan2") { 1593 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1594 rpnstack.top() = atan2(x,y); 1595 } 1596 // generateur aleatoire 1597 else if (args[k] == "rand") { 1598 double rnd = drand01(); 1599 rpnstack.push(rnd); 1600 } 1601 else if (args[k] == "norand") { 1602 double rnd = GauRnd(0., 1.); 1603 rpnstack.push(rnd); 1604 } 1605 // Fonction a N arguments - Somme, produit, etc ... 1606 else if ((args[k] == "sum") || (args[k] == "mean") || (args[k] == "sigmean") || 1607 (args[k] == "sigma") || (args[k] == "sigma2") ) { 1608 double sx, sx2; 1609 int nn = Sum_RPNStack_(rpnstack, sx, sx2, line); 1610 if (args[k] == "sum") rpnstack.push(sx); 1611 else { 1612 if (nn == 0) { 1613 cerr << "Commander::EvalRPNExpr: mean/sigma error- RPN stack empty: " 1614 << line << endl; 1615 return(1); 1616 } 1617 double fnn = nn; 1618 if ((args[k] == "sigma") || (args[k] == "sigmean")) 1619 rpnstack.push(sqrt(sx2/fnn-(x*x/(fnn*fnn)))); 1620 else if ((args[k] == "mean") || (args[k] == "sigmean")) rpnstack.push(sx/fnn); 1621 else rpnstack.push(sx2/fnn-(x*x/(fnn*fnn))); 1622 } 1623 } 1624 else if (args[k] == "product") { 1625 double px; 1626 int nn = Product_RPNStack_(rpnstack, px, line); 1627 if (nn == 0) { 1628 cerr << "Commander::EvalRPNExpr: product error- RPN stack empty: " 1629 << line << endl; 1630 return(1); 1631 } 1632 rpnstack.push(px); 1633 } 1634 // Fonctions de manipulation de stack 1635 else if (args[k] == "print") { 1636 Print_myRPNStack_(rpnstack); 1637 } 1638 else if (args[k] == "x<>y") { 1639 if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1); 1640 rpnstack.top() = x; rpnstack.push(y); 1641 } 1642 else if (args[k] == "pop") { 1643 rpnstack.pop(); 1644 } 1645 else if (args[k] == "push") { 1646 if (rpnstack.empty()) rpnstack.push(0.); 1647 else rpnstack.push(rpnstack.top()); 1648 } 1649 // On met un nombre sur le stack 1650 else { 1651 char * esptr; 1652 x = strtod(args[k].c_str(), &esptr); 1653 // if (ctof(args[k].c_str(),&x) < 0) { 1654 if (esptr == args[k].c_str()) { 1655 cerr << "Commander::EvalRPNExpr: syntax error near " << args[k] 1656 << " in expression: \n" << line << endl; 1657 return(2); 1658 } 1659 rpnstack.push(x); 1660 } 1661 1662 } 1663 1664 if ( Check_myRPNStack_(rpnstack, x, line) ) return(1); 1665 char buff[64]; 1666 sprintf(buff, "%g", x); 1667 string res = buff; 1668 SetVariable(args[0], res); 1418 // A virer - Reza 15/03/2004 1669 1419 return(0); 1670 1420 } … … 1755 1505 } 1756 1506 // Evaluation d'expression en notation polonaise inverse 1757 else if (kw == "rpneval") { 1758 return(EvalRPNExpr(tokens, toks)); 1507 else if (kw == "rpneval") { 1508 try { 1509 RPNExpressionEvaluator rpn(tokens, 1); 1510 double res = rpn.Value(); 1511 char cbuff[64]; 1512 sprintf(cbuff,"%g",res); 1513 string vv = cbuff; 1514 SetVariable(tokens[0],vv); 1515 return 0; 1516 } 1517 catch (RPNExprException& rpnerr) { 1518 cerr << " rpneval: Syntax error - Msg=" << rpnerr.Msg() 1519 << " \n Line=" << toks << endl; 1520 return 98; 1521 } 1759 1522 } 1760 1523 else if (kw == "echo") { -
trunk/SophyaLib/SysTools/rpneval.cc
r2510 r2512 22 22 FillVStringFrString(sex, exe, ' '); 23 23 int rc = EvalRPNExpr(exe, 0); 24 if (rc != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error"); 24 if (rc < exe.size()) { 25 string msg = "RPNExpressionEvaluator() - syntax error near "; 26 msg += exe[rc]; 27 char buff[32]; 28 sprintf(buff," (word %d)",rc); 29 msg += buff; 30 throw RPNExprException(msg); 31 } 25 32 } 26 33 … … 28 35 { 29 36 int rc = EvalRPNExpr(exe, off); 30 if (rc != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error"); 37 if (rc < exe.size()) { 38 string msg = "RPNExpressionEvaluator() - syntax error near "; 39 msg += exe[rc]; 40 char buff[32]; 41 sprintf(buff," (word %d)",rc); 42 msg += buff; 43 throw RPNExprException(msg); 44 } 31 45 } 32 46 … … 49 63 { 50 64 51 if (args.size() <= off) return 0;65 if (args.size() <= off) return 1; 52 66 double x,y; 53 67 x = y = 0.; 54 stack<double> rpnstack_; // Stack des operations en RPN 68 55 69 for(int k=off; k<args.size(); k++) { 56 70 // Les 4 operations de base + - * / 57 71 if (args[k] == "+") { 58 if ( CheckStack( x, y) ) return (1);72 if ( CheckStack( x, y) ) return k; 59 73 rpnstack_.top() = y+x; 60 74 } 61 75 else if (args[k] == "-") { 62 if ( CheckStack( x, y) ) return (1);76 if ( CheckStack( x, y) ) return k; 63 77 rpnstack_.top() = y-x; 64 78 } 65 79 else if (args[k] == "*") { 66 if ( CheckStack( x, y) ) return (1);80 if ( CheckStack( x, y) ) return k; 67 81 rpnstack_.top() = y*x; 68 82 } 69 83 else if (args[k] == "/") { 70 if ( CheckStack( x, y) ) return (1);84 if ( CheckStack( x, y) ) return k; 71 85 rpnstack_.top() = y/x; 72 86 } 73 87 else if (args[k] == "%") { 74 if ( CheckStack( x, y) ) return (1);88 if ( CheckStack( x, y) ) return k; 75 89 rpnstack_.top() = (int)y % (int)x; 76 90 } … … 84 98 // Les fonctions usuelles a 1 argument f(x) 85 99 else if (args[k] == "cos") { 86 if ( CheckStack( x) ) return (1);100 if ( CheckStack( x) ) return k; 87 101 rpnstack_.top() = cos(x); 88 102 } 89 103 else if (args[k] == "sin") { 90 if ( CheckStack( x) ) return (1);104 if ( CheckStack( x) ) return k; 91 105 rpnstack_.top() = sin(x); 92 106 } 93 107 else if (args[k] == "tan") { 94 if ( CheckStack( x) ) return (1);108 if ( CheckStack( x) ) return k; 95 109 rpnstack_.top() = tan(x); 96 110 } 97 111 else if (args[k] == "acos") { 98 if ( CheckStack( x) ) return (1);112 if ( CheckStack( x) ) return k; 99 113 rpnstack_.top() = acos(x); 100 114 } 101 115 else if (args[k] == "asin") { 102 if ( CheckStack( x) ) return (1);116 if ( CheckStack( x) ) return k; 103 117 rpnstack_.top() = asin(x); 104 118 } 105 119 else if (args[k] == "atan") { 106 if ( CheckStack( x) ) return (1);120 if ( CheckStack( x) ) return k; 107 121 rpnstack_.top() = atan(x); 108 122 } 109 123 else if (args[k] == "chs") { 110 if ( CheckStack( x) ) return (1);124 if ( CheckStack( x) ) return k; 111 125 rpnstack_.top() = -x; 112 126 } 113 127 else if (args[k] == "sqrt") { 114 if ( CheckStack( x) ) return (1);128 if ( CheckStack( x) ) return k; 115 129 rpnstack_.top() = sqrt(x); 116 130 } 117 131 else if (args[k] == "sq") { // x^2 118 if ( CheckStack( x) ) return (1);132 if ( CheckStack( x) ) return k; 119 133 rpnstack_.top() = x*x; 120 134 } 121 135 else if (args[k] == "log") { 122 if ( CheckStack( x) ) return (1);136 if ( CheckStack( x) ) return k; 123 137 rpnstack_.top() = log(x); 124 138 } 125 139 else if (args[k] == "log10") { 126 if ( CheckStack( x) ) return (1);140 if ( CheckStack( x) ) return k; 127 141 rpnstack_.top() = log10(x); 128 142 } 129 143 else if (args[k] == "exp") { 130 if ( CheckStack( x) ) return (1);144 if ( CheckStack( x) ) return k; 131 145 rpnstack_.top() = exp(x); 132 146 } 133 147 else if (args[k] == "fabs") { 134 if ( CheckStack( x) ) return (1);148 if ( CheckStack( x) ) return k; 135 149 rpnstack_.top() = fabs(x); 136 150 } 137 151 else if (args[k] == "floor") { 138 if ( CheckStack( x) ) return (1);152 if ( CheckStack( x) ) return k; 139 153 rpnstack_.top() = floor(x); 140 154 } 141 155 else if (args[k] == "ceil") { 142 if ( CheckStack( x) ) return (1);156 if ( CheckStack( x) ) return k; 143 157 rpnstack_.top() = ceil(x); 144 158 } 145 159 // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003 146 160 else if (args[k] == "deg2rad") { 147 if ( CheckStack( x) ) return (1);161 if ( CheckStack( x) ) return k; 148 162 rpnstack_.top() = x*M_PI/180.; 149 163 } 150 164 else if (args[k] == "rad2deg") { 151 if ( CheckStack( x) ) return (1);165 if ( CheckStack( x) ) return k; 152 166 rpnstack_.top() = x*180./M_PI; 153 167 } 154 168 // Les fonctions usuelles a 2 argument f(x,y) 155 169 else if (args[k] == "pow") { 156 if ( CheckStack( x, y) ) return (1);170 if ( CheckStack( x, y) ) return k; 157 171 rpnstack_.top() = pow(y,x); 158 172 } 159 173 else if (args[k] == "atan2") { 160 if ( CheckStack( x, y) ) return (1);174 if ( CheckStack( x, y) ) return k; 161 175 rpnstack_.top() = atan2(x,y); 162 176 } … … 188 202 double px; 189 203 int nn = ProductStack( px); 190 if (nn == 0) return (1);204 if (nn == 0) return k; 191 205 rpnstack_.push(px); 192 206 } … … 196 210 } 197 211 else if (args[k] == "x<>y") { 198 if ( CheckStack( x, y) ) return (1);212 if ( CheckStack( x, y) ) return k; 199 213 rpnstack_.top() = x; rpnstack_.push(y); 200 214 } … … 211 225 x = strtod(args[k].c_str(), &esptr); 212 226 // if (ctof(args[k].c_str(),&x) < 0) { 213 if (esptr == args[k].c_str()) return 2;227 if (esptr == args[k].c_str()) return k; 214 228 rpnstack_.push(x); 215 229 } 216 230 217 231 } 218 return( 0);232 return(args.size()+1); 219 233 } 220 234
Note:
See TracChangeset
for help on using the changeset viewer.