| 560 | } |
| 561 | |
| 562 | forceinline MiniModel::PosSet* |
| 563 | REG::Exp::followpos(MiniModel::PosSetAllocator& psm, |
| 564 | MiniModel::PosInfo* pi) { |
| 565 | int p=0; |
| 566 | |
| 567 | using MiniModel::PosSet; |
| 568 | using MiniModel::NodeInfo; |
| 569 | using MiniModel::ExpInfo; |
| 570 | |
| 571 | Region region; |
| 572 | |
| 573 | Support::DynamicStack<ExpInfo,Region> todo(region); |
| 574 | Support::DynamicStack<NodeInfo,Region> done(region); |
| 575 | |
| 576 | // Start with first expression to be processed |
| 577 | todo.push(ExpInfo(this)); |
| 578 | |
| 579 | do { |
| 580 | if (todo.top().exp == nullptr) { |
| 581 | todo.pop(); |
| 582 | done.push(NodeInfo(true,nullptr,nullptr)); |
| 583 | } else { |
| 584 | switch (todo.top().exp->type) { |
| 585 | case ET_SYMBOL: |
| 586 | { |
| 587 | pi[p].symbol = todo.pop().exp->data.symbol; |
| 588 | PosSet* ps = new (psm) PosSet(p++); |
| 589 | done.push(NodeInfo(false,ps,ps)); |
| 590 | } |
| 591 | break; |
| 592 | case ET_STAR: |
| 593 | if (todo.top().open) { |
| 594 | // Evaluate subexpression recursively |
| 595 | todo.top().open = false; |
| 596 | todo.push(todo.top().exp->data.kids[0]); |
| 597 | } else { |
| 598 | todo.pop(); |
| 599 | NodeInfo ni = done.pop(); |
| 600 | for (PosSet* ps = ni.lastpos; ps != nullptr; ps = ps->next) |
| 601 | pi[ps->pos].followpos = |
| 602 | PosSet::cup(psm,pi[ps->pos].followpos,ni.firstpos); |
| 603 | done.push(NodeInfo(true,ni.firstpos,ni.lastpos)); |
| 604 | } |
| 605 | break; |
| 606 | case ET_CONC: |
| 607 | if (todo.top().open) { |
| 608 | // Evaluate subexpressions recursively |
| 609 | todo.top().open = false; |
| 610 | REG::Exp* e = todo.top().exp; |
| 611 | todo.push(e->data.kids[1]); |
| 612 | todo.push(e->data.kids[0]); |
| 613 | } else { |
| 614 | todo.pop(); |
| 615 | NodeInfo ni1 = done.pop(); |
| 616 | NodeInfo ni0 = done.pop(); |
| 617 | for (PosSet* ps = ni0.lastpos; ps != nullptr; ps = ps->next) |
| 618 | pi[ps->pos].followpos = |
| 619 | PosSet::cup(psm,pi[ps->pos].followpos,ni1.firstpos); |