| 555 | }; |
| 556 | |
| 557 | size_t TExpressionImpl::BuildExpression(TStringBuf str) { |
| 558 | TStack<TFrame> stk; |
| 559 | stk.push({str, Operations.size()}); |
| 560 | |
| 561 | size_t result = 0; |
| 562 | |
| 563 | while (!stk.empty()) { |
| 564 | auto& frame = stk.top(); |
| 565 | |
| 566 | if (!frame.Processed) { |
| 567 | TStringBuf s = StripString(frame.Str); |
| 568 | frame.Order = Operations.size(); |
| 569 | frame.Processed = true; |
| 570 | |
| 571 | std::array<TStringBuf, MaxOperands> args; |
| 572 | size_t numArgs = FindOperation(s, args, frame.Operation); |
| 573 | if (numArgs) { |
| 574 | Operations.push_back(TOperator(frame.Operation)); |
| 575 | frame.NumArgs = numArgs; |
| 576 | frame.Args = TVector<TStringBuf>(args.begin(), args.begin() + numArgs); |
| 577 | frame.ArgIndex = 0; |
| 578 | frame.ArgResults.clear(); |
| 579 | stk.emplace(frame.Args[0], Operations.size()); |
| 580 | continue; |
| 581 | } else if (s.size() == 0) { |
| 582 | Operations.push_back(TOperator(O_TOKEN)); |
| 583 | Operations[frame.Order].Input.push_back(InsertOrUpdate(Tokens, ToString(s))); |
| 584 | result = frame.Order; |
| 585 | stk.pop(); |
| 586 | continue; |
| 587 | } else if (s[0] == '(') { |
| 588 | Y_ENSURE(s.back() == ')', "CalcExpression error: missing closing bracket."); |
| 589 | stk.emplace(s.substr(1, s.size() - 2), Operations.size()); |
| 590 | continue; |
| 591 | } else if (s[0] == '"') { |
| 592 | Y_ENSURE(s.back() == '"' && s.size() >= 2, "CalcExpression error: missing closing quote."); |
| 593 | Operations.push_back(TOperator(O_CONST)); |
| 594 | Operations[frame.Order].Input.push_back(InsertOrUpdate(Consts, ToString(s.substr(1, s.size() - 2)))); |
| 595 | result = frame.Order; |
| 596 | stk.pop(); |
| 597 | continue; |
| 598 | } else if (s[0] == '\'') { |
| 599 | Y_ENSURE(s.back() == '\'' && s.size() >= 2, "CalcExpression error: missing closing singular quote."); |
| 600 | Operations.push_back(TOperator(O_TOKEN)); |
| 601 | Operations[frame.Order].Input.push_back(InsertOrUpdate(Tokens, ToString(s.substr(1, s.size() - 2)))); |
| 602 | result = frame.Order; |
| 603 | stk.pop(); |
| 604 | continue; |
| 605 | } else if (s[0] == '-') { |
| 606 | Operations.push_back(TOperator(O_MINUS)); |
| 607 | frame.Args = {s.substr(1)}; |
| 608 | frame.ArgIndex = 0; |
| 609 | frame.NumArgs = 1; |
| 610 | frame.ArgResults.clear(); |
| 611 | stk.emplace(frame.Args[0], Operations.size()); |
| 612 | continue; |
| 613 | } else if (s[0] == '!') { |
| 614 | Operations.push_back(TOperator(O_NOT)); |
nothing calls this directly
no test coverage detected