| 539 | } |
| 540 | |
| 541 | FieldGeneratorPtr ExpressionParser::parseBinOpRHS(LexInfo& lex, int ExprPrec, |
| 542 | FieldGeneratorPtr lhs) const { |
| 543 | |
| 544 | while (true) { |
| 545 | // Check for end of input |
| 546 | if ((lex.curtok == 0) || (lex.curtok == ')') || (lex.curtok == ',') |
| 547 | || (lex.curtok == ']')) { |
| 548 | return lhs; |
| 549 | } |
| 550 | |
| 551 | // Next token should be a binary operator |
| 552 | auto it = bin_op.find(lex.curtok); |
| 553 | |
| 554 | if (it == bin_op.end()) { |
| 555 | throw ParseException("Unexpected binary operator '{:c}'", |
| 556 | static_cast<char>(lex.curtok)); |
| 557 | } |
| 558 | |
| 559 | FieldGeneratorPtr op = it->second.first; |
| 560 | int TokPrec = it->second.second; |
| 561 | |
| 562 | if (TokPrec < ExprPrec) { |
| 563 | return lhs; |
| 564 | } |
| 565 | |
| 566 | lex.nextToken(); // Eat binop |
| 567 | |
| 568 | FieldGeneratorPtr rhs = parsePrimary(lex); |
| 569 | |
| 570 | if ((lex.curtok == 0) || (lex.curtok == ')') || (lex.curtok == ',') |
| 571 | || (lex.curtok == ']')) { |
| 572 | // Done |
| 573 | |
| 574 | list<FieldGeneratorPtr> args; |
| 575 | args.push_front(lhs); |
| 576 | args.push_back(rhs); |
| 577 | return op->clone(args); |
| 578 | } |
| 579 | |
| 580 | // Find next binop |
| 581 | it = bin_op.find(lex.curtok); |
| 582 | |
| 583 | if (it == bin_op.end()) { |
| 584 | throw ParseException("Unexpected character '{:c}' ({:d})", |
| 585 | static_cast<char>(lex.curtok), static_cast<int>(lex.curtok)); |
| 586 | } |
| 587 | |
| 588 | int NextPrec = it->second.second; |
| 589 | if (TokPrec < NextPrec) { |
| 590 | rhs = parseBinOpRHS(lex, TokPrec + 1, rhs); |
| 591 | } |
| 592 | |
| 593 | // Merge lhs and rhs into new lhs |
| 594 | list<FieldGeneratorPtr> args; |
| 595 | args.push_front(lhs); |
| 596 | args.push_back(rhs); |
| 597 | lhs = op->clone(args); |
| 598 | } |