Called after traversing the node's children during the walk. Given their frags, build and return the frag for this re.
| 814 | // Called after traversing the node's children during the walk. |
| 815 | // Given their frags, build and return the frag for this re. |
| 816 | Frag Compiler::PostVisit(Regexp* re, Frag, Frag, Frag* child_frags, |
| 817 | int nchild_frags) { |
| 818 | // If a child failed, don't bother going forward, especially |
| 819 | // since the child_frags might contain Frags with NULLs in them. |
| 820 | if (failed_) |
| 821 | return NoMatch(); |
| 822 | |
| 823 | // Given the child fragments, return the fragment for this node. |
| 824 | switch (re->op()) { |
| 825 | case kRegexpRepeat: |
| 826 | // Should not see; code at bottom of function will print error |
| 827 | break; |
| 828 | |
| 829 | case kRegexpNoMatch: |
| 830 | return NoMatch(); |
| 831 | |
| 832 | case kRegexpEmptyMatch: |
| 833 | return Nop(); |
| 834 | |
| 835 | case kRegexpHaveMatch: { |
| 836 | Frag f = Match(re->match_id()); |
| 837 | if (anchor_ == RE2::ANCHOR_BOTH) { |
| 838 | // Append \z or else the subexpression will effectively be unanchored. |
| 839 | // Complemented by the UNANCHORED case in CompileSet(). |
| 840 | f = Cat(EmptyWidth(kEmptyEndText), f); |
| 841 | } |
| 842 | return f; |
| 843 | } |
| 844 | |
| 845 | case kRegexpConcat: { |
| 846 | Frag f = child_frags[0]; |
| 847 | for (int i = 1; i < nchild_frags; i++) |
| 848 | f = Cat(f, child_frags[i]); |
| 849 | return f; |
| 850 | } |
| 851 | |
| 852 | case kRegexpAlternate: { |
| 853 | Frag f = child_frags[0]; |
| 854 | for (int i = 1; i < nchild_frags; i++) |
| 855 | f = Alt(f, child_frags[i]); |
| 856 | return f; |
| 857 | } |
| 858 | |
| 859 | case kRegexpStar: |
| 860 | return Star(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0); |
| 861 | |
| 862 | case kRegexpPlus: |
| 863 | return Plus(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0); |
| 864 | |
| 865 | case kRegexpQuest: |
| 866 | return Quest(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0); |
| 867 | |
| 868 | case kRegexpLiteral: |
| 869 | return Literal(re->rune(), (re->parse_flags()&Regexp::FoldCase) != 0); |
| 870 | |
| 871 | case kRegexpLiteralString: { |
| 872 | // Concatenation of literals. |
| 873 | if (re->nrunes() == 0) |