00001
00020 #include "jbltools/sfh/JBLParserResult.h"
00021 #include "jbltools/sfh/IntFun.h"
00022 #include "jbltools/sfh/FloatFun.h"
00023 #include "jbltools/sfh/BaseCut.h"
00024
00025 #include <iostream>
00026 #include <sstream>
00027 #include <map>
00028
00029 using namespace std;
00030
00031 static const char *ident="@(#)$Id: JBLParserResult.C,v 1.11 2005/07/21 11:20:12 blist Exp $";
00032
00033 typedef std::map<std::string, JBLParserResult::Fun_f_f > Map_f_f ;
00034 typedef std::map<std::string, JBLParserResult::Fun_f_f_f > Map_f_f_f ;
00035 typedef std::map<std::string, JBLParserResult::Fun_f_f_i > Map_f_f_i ;
00036 typedef std::map<std::string, JBLParserResult::Fun_i_i > Map_i_i ;
00037 typedef std::map<std::string, JBLParserResult::Fun_b_b > Map_b_b ;
00038 typedef std::map<std::string, JBLParserResult::Fun_FF_FF > Map_FF_FF ;
00039 typedef std::map<std::string, JBLParserResult::Fun_FF_FF_FF> Map_FF_FF_FF;
00040 typedef std::map<std::string, JBLParserResult::Fun_FF_FF_IF> Map_FF_FF_IF;
00041 typedef std::map<std::string, JBLParserResult::Fun_IF_IF > Map_IF_IF ;
00042 typedef std::map<std::string, JBLParserResult::Fun_BC_BC > Map_BC_BC ;
00043
00044 static Map_f_f *theMap_f_f = 0;
00045 static Map_f_f_f *theMap_f_f_f = 0;
00046 static Map_f_f_i *theMap_f_f_i = 0;
00047 static Map_i_i *theMap_i_i = 0;
00048 static Map_FF_FF *theMap_FF_FF = 0;
00049 static Map_FF_FF_FF *theMap_FF_FF_FF= 0;
00050 static Map_FF_FF_IF *theMap_FF_FF_IF= 0;
00051 static Map_IF_IF *theMap_IF_IF = 0;
00052
00053 JBLParserResult::JBLParserResult()
00054 : type (EMPTY),
00055 intvalue(0), floatvalue(0), boolvalue(false),
00056 intfunvalue (0), floatfunvalue (0), basecutvalue (0),
00057 name("EMPTY"), next (0)
00058 {}
00059 JBLParserResult::JBLParserResult(int intvalue_)
00060 : type (INT),
00061 intvalue(intvalue_), floatvalue(intvalue_), boolvalue(false),
00062 intfunvalue (0), floatfunvalue (0), basecutvalue (0),
00063 name(NamedO::str(intvalue_)), next (0)
00064 {}
00065 JBLParserResult::JBLParserResult(Float_FF floatvalue_)
00066 : type (FLOAT),
00067 intvalue(0), floatvalue(floatvalue_), boolvalue(false),
00068 intfunvalue (0), floatfunvalue (0), basecutvalue (0),
00069 name(NamedO::str(floatvalue_)), next (0)
00070 {}
00071 JBLParserResult::JBLParserResult(bool boolvalue_)
00072 : type (BOOL),
00073 intvalue(0), floatvalue(0), boolvalue(boolvalue_),
00074 intfunvalue (0), floatfunvalue (0), basecutvalue (0),
00075 name(NamedO::str(boolvalue_)), next (0)
00076 {}
00077 JBLParserResult::JBLParserResult(IntFun &intfunvalue_)
00078 : type (INTFUN),
00079 intvalue(0), floatvalue(0), boolvalue(false),
00080 intfunvalue (&intfunvalue_), floatfunvalue (0), basecutvalue (0),
00081 name(intfunvalue_.getName()), next (0)
00082 {}
00083 JBLParserResult::JBLParserResult(FloatFun &floatfunvalue_)
00084 : type (FLOATFUN),
00085 intvalue(0), floatvalue(0), boolvalue(false),
00086 intfunvalue (0), floatfunvalue (&floatfunvalue_), basecutvalue (0),
00087 name(floatfunvalue_.getName()), next (0)
00088 {}
00089 JBLParserResult::JBLParserResult(BaseCut &basecutvalue_)
00090 : type (BASECUT),
00091 intvalue(0), floatvalue(0), boolvalue(false),
00092 intfunvalue (0), floatfunvalue (0), basecutvalue (&basecutvalue_),
00093 name(basecutvalue_.getName()), next (0)
00094 {}
00095 JBLParserResult::JBLParserResult(const string& name_)
00096 : type (IDENTIFIER),
00097 intvalue(0), floatvalue(0), boolvalue(0),
00098 intfunvalue (0), floatfunvalue (0), basecutvalue (0),
00099 name(name_), next (0)
00100 {}
00101
00102
00103 JBLParserResult& JBLParserResult::addCopyToList(const JBLParserResult &rhs)
00104 {
00105 name += ", "+rhs.name;
00106 JBLParserResult *p = this;
00107 while (p->next) p = p->next;
00108 p->next = new JBLParserResult(rhs);
00109 return *this;
00110 }
00111
00112 JBLParserResult::JBLParserResult(const JBLParserResult &rhs)
00113 : type (rhs.type),
00114 intvalue(rhs.intvalue), floatvalue(rhs.floatvalue), boolvalue(rhs.boolvalue),
00115 intfunvalue (rhs.intfunvalue), floatfunvalue (rhs.floatfunvalue), basecutvalue (rhs.basecutvalue),
00116 name(rhs.name), next (rhs.next ? new JBLParserResult(*rhs.next) : 0)
00117 {
00118
00119
00120 }
00121
00122 JBLParserResult& JBLParserResult::operator= (const JBLParserResult &rhs) {
00123 if (this == &rhs) return *this;
00124 JBLParserResult *oldnext = next;
00125 next = 0;
00126 type =rhs.type;
00127 intvalue=rhs.intvalue;
00128 floatvalue=rhs.floatvalue;
00129 boolvalue=rhs.boolvalue;
00130 intfunvalue =rhs.intfunvalue;
00131 floatfunvalue =rhs.floatfunvalue;
00132 basecutvalue =rhs.basecutvalue;
00133 name=rhs.name;
00134
00135
00136
00137
00138 next = rhs.next ? new JBLParserResult(*rhs.next) : 0;
00139 delete oldnext;
00140 return *this;
00141 }
00142
00143 JBLParserResult::~JBLParserResult()
00144 {
00145
00146
00147
00148
00149
00150 delete next;
00151 next = 0;
00152 }
00153
00154 int JBLParserResult::listlength() const {
00155 int result = 0;
00156 for (const JBLParserResult *p = this; p && !p->isEmpty(); p=p->next, result++);
00157 return result;
00158 }
00159
00160 int JBLParserResult::getIntValue() const {
00161 if (isInt()) return intvalue;
00162 return 0;
00163 }
00164 Float_FF JBLParserResult::getFloatValue() const {
00165 if (isFloat()) return floatvalue;
00166 if (isInt()) return intvalue;
00167 return 0;
00168 }
00169 bool JBLParserResult::getBoolValue() const {
00170 if (isBool()) return boolvalue;
00171 return 0;
00172 }
00173
00174 IntFun *JBLParserResult::getIntFunValue() const {
00175 if (isIntFun()) return intfunvalue;
00176 if (isInt()) return new ConstIntFun(intvalue);
00177 return 0;
00178 }
00179 FloatFun *JBLParserResult::getFloatFunValue() const {
00180 if (isFloatFun()) return floatfunvalue;
00181 if (isIntFun()) return &Float(*intfunvalue);
00182 if (isNumber()) return new ConstFun(getFloatValue());
00183 return 0;
00184 }
00185 BaseCut *JBLParserResult::getBaseCutValue() const {
00186 if (isBaseCut()) return basecutvalue;
00187 if (isBool()) return new ConstBaseCut (boolvalue);
00188 return 0;
00189 }
00190
00191 JBLToken JBLParserResult::token;
00192
00193 JBLParserResult JBLParserResult::parseExpression (const std::string& input) {
00194 istringstream is (input);
00195 token.input(is);
00196 return expression (is);
00197 }
00198
00199 JBLParserResult JBLParserResult::parseExpression (std::istream& is) {
00200 token.input(is);
00201 return expression (is);
00202 }
00203
00204 template <class T1, class T2>
00205 JBLParserResult JBLParserResult::comparison (int op, const T1& lhs, const T2& rhs) {
00206 switch (op) {
00207 case 0: return JBLParserResult (lhs == rhs);
00208 case 1: return JBLParserResult (lhs != rhs);
00209 case 2: return JBLParserResult (lhs < rhs);
00210 case 3: return JBLParserResult (lhs <= rhs);
00211 case 4: return JBLParserResult (lhs > rhs);
00212 case 5: return JBLParserResult (lhs >= rhs);
00213 case 6: return JBLParserResult (lhs + rhs);
00214 case 7: return JBLParserResult (lhs - rhs);
00215 case 8: return JBLParserResult (lhs * rhs);
00216 case 9: return JBLParserResult (lhs / rhs);
00217 }
00218 return syntaxError ("comparison: Unknown operator!");
00219 }
00220
00221 JBLParserResult JBLParserResult::makefloatfunction (const std::string& fname, JBLParserResult& arglist) {
00222 if (arglist.listlength()==1) {
00223 JBLParserResult& arg = arglist;
00224 if (arg.isInt()) {
00225 std::cout << "makefloatfunction: looking for " << fname << " in theMap_i_i\n";
00226 Map_i_i::iterator it = theMap_i_i->find(fname);
00227 if (it != theMap_i_i->end()) {
00228 std::cout << " ...found!\n";
00229 return JBLParserResult ((*it->second)(arg.getIntValue()));
00230 }
00231 }
00232 if (arg.isNumber()) {
00233 std::cout << "makefloatfunction: looking for " << fname << " in theMap_f_f\n";
00234 Map_f_f::iterator it = theMap_f_f->find(fname);
00235 if (it != theMap_f_f->end()) {
00236 std::cout << " ...found!\n";
00237 return JBLParserResult ((*it->second)(arg.getFloatValue()));
00238 }
00239 }
00240 if (arg.isIntFun()) {
00241 std::cout << "makefloatfunction: looking for " << fname << " in theMap_IF_IF\n";
00242 Map_IF_IF::iterator it = theMap_IF_IF->find(fname);
00243 if (it != theMap_IF_IF->end()) {
00244 std::cout << " ...found!\n";
00245 return JBLParserResult ((*it->second)(*arg.getIntFunValue()));
00246 }
00247 }
00248 if (arg.isFloatFun()) {
00249 std::cout << "makefloatfunction: looking for " << fname << " in theMap_FF_FF\n";
00250 Map_FF_FF::iterator it = theMap_FF_FF->find(fname);
00251 if (it != theMap_FF_FF->end()) {
00252 std::cout << " ...found!\n";
00253 return JBLParserResult ((*it->second)(*arg.getFloatFunValue()));
00254 }
00255 }
00256 std::string error ("makefloatfunction: Cannot generate function '");
00257 error += fname+"' with argument '" + arg.getName() + "' of type " + NamedO::str((int)arg.type) + "!";
00258 return syntaxError (error);
00259 }
00260 else if (arglist.listlength()==2) {
00261 JBLParserResult& arg1 = arglist;
00262 JBLParserResult& arg2 = *arglist.next;
00263 assert (&arg2);
00264 if (arg1.isNumber() && arg2.isInt()) {
00265 std::cout << "makefloatfunction: looking for " << fname << " in theMap_f_f_i\n";
00266 Map_f_f_i::iterator it = theMap_f_f_i->find(fname);
00267 if (it != theMap_f_f_i->end()) {
00268 std::cout << " ...found!\n";
00269 return JBLParserResult ((*it->second)(arg1.getFloatValue(), arg2.getIntValue()));
00270 }
00271 }
00272 if (arg1.isNumber() && arg2.isNumber()) {
00273 std::cout << "makefloatfunction: looking for " << fname << " in theMap_f_f_f\n";
00274 Map_f_f_i::iterator it = theMap_f_f_f->find(fname);
00275 if (it != theMap_f_f_f->end()) {
00276 std::cout << " ...found!\n";
00277 return JBLParserResult ((*it->second)(arg1.getFloatValue(), arg2.getFloatValue()));
00278 }
00279 }
00280 if (arg1.isFloatFun() && arg2.isIntFun()) {
00281 std::cout << "makefloatfunction: looking for " << fname << " in theMap_FF_FF_IF\n";
00282 Map_FF_FF_IF::iterator it = theMap_FF_FF_IF->find(fname);
00283 if (it != theMap_FF_FF_IF->end()) {
00284 std::cout << " ...found!\n";
00285 return JBLParserResult ((*it->second)(*arg1.getFloatFunValue(), *arg2.getIntFunValue()));
00286 }
00287 }
00288 if (arg1.isFloatFun() && arg2.isFloatFun()) {
00289 std::cout << "makefloatfunction: looking for " << fname << " in theMap_FF_FF_FF\n";
00290 Map_FF_FF_FF::iterator it = theMap_FF_FF_FF->find(fname);
00291 if (it != theMap_FF_FF_FF->end()) {
00292 std::cout << " ...found!\n";
00293 return JBLParserResult ((*it->second)(*arg1.getFloatFunValue(), *arg2.getFloatFunValue()));
00294 }
00295 }
00296 }
00297 std::string error ("makefloatfunction: Cannot generate function '");
00298 error += fname+"' with arguments '" + arglist.getName() + "'!";
00299 return syntaxError (error);
00300 }
00301
00302 JBLParserResult JBLParserResult::expression (istream& is) {
00303 return assignment_expression (is);
00304 }
00305
00306 JBLParserResult JBLParserResult::assignment_expression (istream& is) {
00307 return conditional_expression (is);
00308 }
00309
00310 JBLParserResult JBLParserResult::conditional_expression (istream& is) {
00311 return logical_OR_expression (is);
00312 }
00313
00314
00315 JBLParserResult JBLParserResult::logical_OR_expression (istream& is) {
00316
00317 JBLParserResult lhs = logical_AND_expression(is);
00318 while (token.isOperator() && token.getStringValue() == "||") {
00319 token.input(is);
00320 JBLParserResult rhs = logical_AND_expression(is);
00321
00322 if (lhs.isBaseCut()) {
00323 BaseCut& lhsval (*lhs.getBaseCutValue());
00324 if (rhs.isBaseCut()) {
00325 BaseCut& rhsval (*rhs.getBaseCutValue());
00326 lhs = JBLParserResult (lhsval || rhsval);
00327 }
00328
00329
00330
00331
00332 }
00333 else if (lhs.isBool()) {
00334 bool lhsval = lhs.getBoolValue();
00335
00336
00337
00338
00339
00340 if (rhs.isBool()) {
00341 bool rhsval =rhs.getBoolValue();
00342 lhs = JBLParserResult (lhsval || rhsval);
00343 }
00344 }
00345 else {
00346 cerr << "JBLParserResult::logical_OR_expression: cannot OR '" << lhs.name << "' and '"
00347 << rhs.name << "'!\n";
00348 }
00349 }
00350
00351 return lhs;
00352 }
00353
00354 JBLParserResult JBLParserResult::logical_AND_expression (istream& is) {
00355
00356 JBLParserResult lhs = inclusive_OR_expression(is);
00357 while (token.isOperator() && (token.getStringValue() == "&&")) {
00358 token.input(is);
00359
00360 JBLParserResult rhs = inclusive_OR_expression(is);
00361
00362 if (lhs.isBaseCut()) {
00363 BaseCut& lhsval (*lhs.getBaseCutValue());
00364 if (rhs.isBaseCut()) {
00365 BaseCut& rhsval (*rhs.getBaseCutValue());
00366 lhs = JBLParserResult (lhsval && rhsval);
00367 }
00368
00369
00370
00371
00372 }
00373 else if (lhs.isBool()) {
00374 bool lhsval = lhs.getBoolValue();
00375
00376
00377
00378
00379
00380 if (rhs.isBool()) {
00381 bool rhsval =rhs.getBoolValue();
00382 lhs = JBLParserResult (lhsval && rhsval);
00383 }
00384 }
00385 else {
00386 cerr << "JBLParserResult::logical_AND_expression: cannot AND '" << lhs.name << "' and '"
00387 << rhs.name << "'!\n";
00388 }
00389 }
00390
00391 return lhs;
00392 }
00393
00394 JBLParserResult JBLParserResult::inclusive_OR_expression (istream& is) {
00395
00396 JBLParserResult lhs = exclusive_OR_expression(is);
00397 while (token.isOperator() && (token.getStringValue() == "|")) {
00398 token.input(is);
00399 JBLParserResult rhs = exclusive_OR_expression(is);
00400
00401 if (lhs.isIntFun()) {
00402 IntFun& lhsval (*lhs.getIntFunValue());
00403 if (rhs.isIntFun()) {
00404 IntFun& rhsval (*rhs.getIntFunValue());
00405 lhs = JBLParserResult (lhsval | rhsval);
00406 }
00407 else if (rhs.isInt()) {
00408 int rhsval = rhs.getIntValue();
00409 lhs = JBLParserResult (lhsval | rhsval);
00410 }
00411 }
00412 else if (lhs.isInt()) {
00413 int lhsval = lhs.getIntValue();
00414 if (rhs.isIntFun()) {
00415 IntFun& rhsval (*rhs.getIntFunValue());
00416 lhs = JBLParserResult (lhsval | rhsval);
00417 }
00418 else if (rhs.isInt()) {
00419 int rhsval =rhs.getIntValue();
00420 lhs = JBLParserResult (lhsval | rhsval);
00421 }
00422 }
00423 else {
00424 cerr << "JBLParserResult::inclusive_OR_expression: cannot OR '" << lhs.name << "' and '"
00425 << rhs.name << "'!\n";
00426 }
00427 }
00428
00429 return lhs;
00430 }
00431
00432 JBLParserResult JBLParserResult::exclusive_OR_expression (istream& is) {
00433
00434 JBLParserResult lhs = AND_expression(is);
00435 while (token.isOperator() && (token.getStringValue() == "^")) {
00436 token.input(is);
00437 JBLParserResult rhs = AND_expression(is);
00438
00439 if (lhs.isIntFun()) {
00440 IntFun& lhsval (*lhs.getIntFunValue());
00441 if (rhs.isIntFun()) {
00442 IntFun& rhsval (*rhs.getIntFunValue());
00443 lhs = JBLParserResult (lhsval ^ rhsval);
00444 }
00445 else if (rhs.isInt()) {
00446 int rhsval = rhs.getIntValue();
00447 lhs = JBLParserResult (lhsval ^ rhsval);
00448 }
00449 }
00450 else if (lhs.isInt()) {
00451 int lhsval = lhs.getIntValue();
00452 if (rhs.isIntFun()) {
00453 IntFun& rhsval (*rhs.getIntFunValue());
00454 lhs = JBLParserResult (lhsval ^ rhsval);
00455 }
00456 else if (rhs.isInt()) {
00457 int rhsval =rhs.getIntValue();
00458 lhs = JBLParserResult (lhsval ^ rhsval);
00459 }
00460 }
00461 else {
00462 cerr << "JBLParserResult::exclusive_OR_expression: cannot OR '" << lhs.name << "' and '"
00463 << rhs.name << "'!\n";
00464 }
00465 }
00466
00467 return lhs;
00468 }
00469
00470 JBLParserResult JBLParserResult::AND_expression (istream& is) {
00471
00472 JBLParserResult lhs = equality_expression(is);
00473 while (token.isOperator() && (token.getStringValue() == "&")) {
00474 token.input(is);
00475 JBLParserResult rhs = equality_expression(is);
00476
00477 if (lhs.isIntFun()) {
00478 IntFun& lhsval (*lhs.getIntFunValue());
00479 if (rhs.isIntFun()) {
00480 IntFun& rhsval (*rhs.getIntFunValue());
00481 lhs = JBLParserResult (lhsval & rhsval);
00482 }
00483 else if (rhs.isInt()) {
00484 int rhsval = rhs.getIntValue();
00485 lhs = JBLParserResult (lhsval & rhsval);
00486 }
00487 }
00488 else if (lhs.isInt()) {
00489 int lhsval = lhs.getIntValue();
00490 if (rhs.isIntFun()) {
00491 IntFun& rhsval (*rhs.getIntFunValue());
00492 lhs = JBLParserResult (lhsval & rhsval);
00493 }
00494 else if (rhs.isInt()) {
00495 int rhsval =rhs.getIntValue();
00496 lhs = JBLParserResult (lhsval & rhsval);
00497 }
00498 }
00499 else {
00500 cerr << "JBLParserResult::AND_expression: cannot AND '" << lhs.name << "' and '"
00501 << rhs.name << "'!\n";
00502 }
00503 }
00504
00505 return lhs;
00506 }
00507
00508 JBLParserResult JBLParserResult::makeoperation (int op, const std::string& opname, JBLParserResult& lhs, JBLParserResult& rhs) {
00509 if (lhs.isIntFun()) {
00510 if (rhs.isIntFun()) return comparison (op, *lhs.getIntFunValue(), *rhs.getIntFunValue());
00511 else if (rhs.isInt()) return comparison (op, *lhs.getIntFunValue(), rhs.getIntValue());
00512 }
00513 else if (lhs.isInt()) {
00514 if (rhs.isIntFun()) return comparison (op, lhs.getIntValue(), *rhs.getIntFunValue());
00515 else if (rhs.isInt()) return comparison (op, lhs.getIntValue(), rhs.getIntValue());
00516 else if (rhs.isFloatFun()) return comparison (op, lhs.getFloatValue(), *rhs.getFloatFunValue());
00517 else if (rhs.isFloat()) return comparison (op, lhs.getFloatValue(), rhs.getFloatValue());
00518 }
00519 else if (lhs.isFloatFun()) {
00520 if (rhs.isFloatFun()) return comparison (op, *lhs.getFloatFunValue(), *rhs.getFloatFunValue());
00521 else if (rhs.isNumber()) return comparison (op, *lhs.getFloatFunValue(), rhs.getFloatValue());
00522 }
00523 else if (lhs.isFloat()) {
00524 if (rhs.isFloatFun()) return comparison (op, lhs.getFloatValue(), *rhs.getFloatFunValue());
00525 else if (rhs.isNumber()) return comparison (op, lhs.getFloatValue(), rhs.getFloatValue());
00526 }
00527 std::string error = "makeoperation: Cannot generate operator"+opname
00528 + " between " + lhs.getName() + " and " + rhs.getName() +"!";
00529 return syntaxError (error);
00530 }
00531
00532 JBLParserResult JBLParserResult::equality_expression (istream& is) {
00533
00534 JBLParserResult lhs = relational_expression(is);
00535 while (token.isOperator()) {
00536 int op = -1;
00537 string opname = token.getStringValue();
00538 if (opname == "==") op=0;
00539 else if (opname == "!=") op=1;
00540 else return lhs;
00541 token.input(is);
00542 JBLParserResult rhs = relational_expression(is);
00543
00544 lhs = makeoperation (op, opname, lhs, rhs);
00545 }
00546
00547 return lhs;
00548 }
00549
00550 JBLParserResult JBLParserResult::relational_expression (istream& is) {
00551
00552 JBLParserResult lhs = shift_expression(is);
00553 while (token.isOperator()) {
00554 int op = -1;
00555 string opname = token.getStringValue();
00556 if (opname == "<") op=2;
00557 else if (opname == "<=") op=3;
00558 else if (opname == ">") op=4;
00559 else if (opname == ">=") op=5;
00560 else return lhs;
00561 token.input(is);
00562 JBLParserResult rhs = shift_expression(is);
00563
00564 lhs = makeoperation (op, opname, lhs, rhs);
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 return lhs;
00587 }
00588
00589 JBLParserResult JBLParserResult::shift_expression (istream& is) {
00590 return additive_expression(is);
00591 }
00592
00593
00594 JBLParserResult JBLParserResult::additive_expression (istream& is) {
00595
00596 JBLParserResult lhs;
00597 if (token.isEmpty()) return lhs;
00598 lhs = multiplicative_expression (is);
00599
00600 while (token.isOperator()) {
00601 int op = -1;
00602 string opname = token.getStringValue();
00603 if (opname == "+") op=6;
00604 else if (opname == "-") op=7;
00605 else return lhs;
00606 token.input(is);
00607 JBLParserResult rhs = multiplicative_expression (is);
00608
00609 lhs = makeoperation (op, opname, lhs, rhs);
00610 }
00611
00612 return lhs;
00613 }
00614
00615 JBLParserResult JBLParserResult::multiplicative_expression (istream& is) {
00616
00617 JBLParserResult lhs;
00618 if (token.isEmpty()) return lhs;
00619 lhs = cast_expression(is);
00620
00621 while (token.isOperator()) {
00622 int op = -1;
00623 string opname = token.getStringValue();
00624 if (opname == "*") op=8;
00625 else if (opname == "/") op=9;
00626 else return lhs;
00627 token.input(is);
00628 JBLParserResult rhs = cast_expression (is);
00629
00630 lhs = makeoperation (op, opname, lhs, rhs);
00631
00632 }
00633
00634 return lhs;
00635 }
00636
00637 JBLParserResult JBLParserResult::cast_expression (istream& is) {
00638 return unary_expression (is);
00639 }
00640
00641 JBLParserResult JBLParserResult::unary_expression (istream& is) {
00642
00643 JBLParserResult result;
00644 if (token.isEmpty()) return result;
00645 int sign = 1;
00646 if (token.isOperator()) {
00647 if (token.getStringValue() == "+" || token.getStringValue() == "-") {
00648 if (token.getStringValue() == "+") {}
00649 else if (token.getStringValue() == "-") {sign = -1;}
00650 token.input(is);
00651 result = cast_expression(is);
00652 if (sign < 0) {
00653 switch (result.type) {
00654 case JBLParserResult::INT:
00655 result = JBLParserResult(-result.getIntValue()); break;
00656 case JBLParserResult::FLOAT:
00657 result = JBLParserResult(-result.getFloatValue()); break;
00658 case JBLParserResult::FLOATFUN:
00659 result = JBLParserResult(-(*result.getFloatFunValue())); break;
00660 case JBLParserResult::INTFUN:
00661 result = JBLParserResult(-(*result.getIntFunValue())); break;
00662 default: syntaxError ("unary_expression: Unary minus not permitted here!");
00663 }
00664 }
00665 }
00666 else if (token.getStringValue() == "!") {
00667 token.input(is);
00668 result = cast_expression(is);
00669 switch (result.type) {
00670 case JBLParserResult::BOOL:
00671 result = JBLParserResult(!result.getBoolValue()); break;
00672 case JBLParserResult::BASECUT:
00673 result = JBLParserResult(!(*result.getBaseCutValue())); break;
00674 default: syntaxError ("unary_expression: Operator ! not permitted here!");
00675 }
00676 }
00677 else if (token.getStringValue() == "~") {
00678 token.input(is);
00679 result = cast_expression(is);
00680 switch (result.type) {
00681 case JBLParserResult::INT:
00682 result = JBLParserResult(~result.getIntValue()); break;
00683 case JBLParserResult::INTFUN:
00684 result = JBLParserResult(~(*result.getIntFunValue())); break;
00685 default: syntaxError ("unary_expression: Operator ~ not permitted here!");
00686 }
00687 }
00688 }
00689 else result = postfix_expression(is);
00690
00691 return result;
00692 }
00693
00694 JBLParserResult JBLParserResult::postfix_expression (istream& is) {
00695
00696 JBLParserResult result;
00697 if (token.isEmpty()) return result;
00698 result = primary_expression (is);
00699
00700
00701
00702 if (token.isParanthesis() && token.getStringValue() == "(") {
00703 token.input(is);
00704 JBLParserResult argument;
00705 if (token.isParanthesis() && token.getStringValue() == ")") {
00706
00707 }
00708 else {
00709 argument = argument_expression_list (is);
00710
00711 if (!token.isParanthesis() || !(token.getStringValue() == ")")) syntaxError ("postfix_expression: Wrong paranthesis! ) expected");
00712 }
00713 token.input(is);
00714
00715
00716
00717 if (result.isIdentifier()) {
00718 return result = makefloatfunction(result.name, argument);
00719 }
00720 }
00721
00722
00723 return result;
00724 }
00725
00726 JBLParserResult JBLParserResult::primary_expression (istream& is) {
00727
00728 JBLParserResult result;
00729 if (token.isEmpty()) return result;
00730 if (token.isIdentifier()) {
00731
00732 if (IntFun *i=IntFun::getObject (token.getStringValue())) result = JBLParserResult(*i);
00733 else if (FloatFun *f=FloatFun::getObject (token.getStringValue())) result = JBLParserResult(*f);
00734 else if (BaseCut *b=BaseCut::getObject (token.getStringValue())) result = JBLParserResult(*b);
00735 else result = JBLParserResult(token.getStringValue());
00736 }
00737 else if (token.isParanthesis()) {
00738 if (!(token.getStringValue() == "(")) result = syntaxError ("primary_expression: Wrong paranthesis! ( expected");
00739 token.input(is);
00740 result = expression(is);
00741 if (!(token.getStringValue() == ")")) syntaxError ("primary_expression: Wrong paranthesis! ) expected");
00742 }
00743 else if (token.isNumber()) {
00744
00745 if (token.isInt()) result = JBLParserResult(token.getIntValue());
00746 else result = JBLParserResult(token.getFloatValue());
00747 }
00748 else if (token.isBool()) {
00749
00750 result = JBLParserResult(token.getBoolValue());
00751 }
00752 else result = syntaxError ("primary_expression: syntax error!");
00753
00754 token.input (is);
00755 return result;
00756 }
00757
00758 JBLParserResult JBLParserResult::argument_expression_list (istream& is) {
00759
00760 JBLParserResult lhs;
00761 if (token.isEmpty()) return lhs;
00762 lhs = assignment_expression (is);
00763
00764 while (token.isOperator()) {
00765 if (!(token.getStringValue() == ",")) return lhs;
00766 token.input(is);
00767 JBLParserResult rhs = assignment_expression(is);
00768
00769 lhs.addCopyToList(rhs);
00770
00771 }
00772
00773
00774 return lhs;
00775 }
00776
00777 JBLParserResult JBLParserResult::syntaxError (const string& text) {
00778 std::cerr << text << ", next token: " << token.getStringValue() << std::endl;
00779 return JBLParserResult();
00780 }
00781
00782 void JBLParserResult::initMaps() {
00783 theMap_f_f = new Map_f_f ;
00784 theMap_f_f_f = new Map_f_f_f ;
00785 theMap_f_f_i = new Map_f_f_i ;
00786 theMap_i_i = new Map_i_i ;
00787 theMap_FF_FF = new Map_FF_FF ;
00788 theMap_FF_FF_FF = new Map_FF_FF_FF ;
00789 theMap_FF_FF_IF = new Map_FF_FF_IF ;
00790 theMap_IF_IF = new Map_IF_IF ;
00791
00792 (*theMap_f_f)["abs"] = &std::abs;
00793 (*theMap_f_f)["acos"] = &std::acos;
00794 (*theMap_f_f)["asin"] = &std::asin;
00795 (*theMap_f_f)["atan"] = &std::atan;
00796 (*theMap_f_f)["ceil"] = &std::ceil;
00797 (*theMap_f_f)["cos"] = &std::cos;
00798 (*theMap_f_f)["cosh"] = &std::cosh;
00799 (*theMap_f_f)["exp"] = &std::exp;
00800 (*theMap_f_f)["fabs"] = &std::fabs;
00801 (*theMap_f_f)["floor"] = &std::floor;
00802 (*theMap_f_f)["log"] = &std::log;
00803 (*theMap_f_f)["log10"] = &std::log10;
00804 (*theMap_f_f)["sin"] = &std::sin;
00805 (*theMap_f_f)["sinh"] = &std::sinh;
00806 (*theMap_f_f)["sqrt"] = &std::sqrt;
00807 (*theMap_f_f)["tan"] = &std::tan;
00808 (*theMap_f_f)["tanh"] = &std::tanh;
00809 (*theMap_f_f)["square"] = □
00810 (*theMap_f_f)["rad"] = &rad;
00811 (*theMap_f_f)["deg"] = °
00812
00813 (*theMap_FF_FF)["abs"] = &abs;
00814 (*theMap_FF_FF)["acos"] = &acos;
00815 (*theMap_FF_FF)["asin"] = &asin;
00816 (*theMap_FF_FF)["atan"] = &atan;
00817 (*theMap_FF_FF)["ceil"] = &ceil;
00818 (*theMap_FF_FF)["cos"] = &cos;
00819 (*theMap_FF_FF)["cosh"] = &cosh;
00820 (*theMap_FF_FF)["exp"] = &exp;
00821 (*theMap_FF_FF)["fabs"] = &fabs;
00822 (*theMap_FF_FF)["floor"] = &floor;
00823 (*theMap_FF_FF)["log"] = &log;
00824 (*theMap_FF_FF)["log10"] = &log10;
00825 (*theMap_FF_FF)["sin"] = &sin;
00826 (*theMap_FF_FF)["sinh"] = &sinh;
00827 (*theMap_FF_FF)["sqrt"] = &sqrt;
00828 (*theMap_FF_FF)["tan"] = &tan;
00829 (*theMap_FF_FF)["tanh"] = &tanh;
00830 (*theMap_FF_FF)["square"] = □
00831 (*theMap_FF_FF)["rad"] = &rad;
00832 (*theMap_FF_FF)["deg"] = °
00833
00834 (*theMap_i_i)["abs"] = &std::abs;
00835 (*theMap_i_i)["square"] = □
00836
00837 (*theMap_IF_IF)["abs"] = &abs;
00838 (*theMap_IF_IF)["square"] = □
00839
00840 (*theMap_f_f_i)["pow"] = &std::pow;
00841
00842 (*theMap_f_f_f)["atan2"] = &std::atan2;
00843 (*theMap_f_f_f)["pow"] = &std::pow;
00844
00845 (*theMap_FF_FF_FF)["atan2"] = &atan2;
00846 (*theMap_FF_FF_FF)["atan2"] = &pow;
00847
00848 std::cout << "JBLParserResult: maps initialized!" << std::endl;
00849 }
00850
00851 std::ostream& JBLParserResult::print(std::ostream& os) const {
00852 if (isEmpty()) os << "EMPTY";
00853 else if (isInt()) os << "INT " << getIntValue();
00854 else if (isFloat()) os << "FLOAT " << getFloatValue();
00855 else if (isBool()) os << "BOOL " << (getBoolValue() ? "true" : "false");
00856 else if (isIntFun()) os << "INTFUN " << getIntFunValue()->getName();
00857 else if (isFloatFun()) os << "FLOATFUN " << getFloatFunValue()->getName();
00858 else if (isBaseCut()) os << "BASECUT " << getBaseCutValue()->getName();
00859 else if (isIdentifier()) os << "IDENTIFIER '" << getName() << "'";
00860 if (next) {
00861 os << ", ";
00862 next->print (os);
00863 }
00864 return os;
00865 }
00866
00867
00868 istream& operator>> (istream& is, JBLParserResult& result) {
00869 result = JBLParserResult::parseExpression (is);
00870 return is;
00871 }
00872
00873 ostream& operator<< (ostream& os, const JBLParserResult& result) {
00874 return result.print (os);
00875 }
00876
00877 int JBLParserResult::Init::counter = 0;
00878
00879 JBLParserResult::Init::Init() {
00880 if (counter++ == 0) JBLParserResult::initMaps();
00881 }