| 1027 | } |
| 1028 | |
| 1029 | void FactorAlternationImpl::Round1(Regexp** sub, int nsub, |
| 1030 | Regexp::ParseFlags flags, |
| 1031 | std::vector<Splice>* splices) { |
| 1032 | // Round 1: Factor out common literal prefixes. |
| 1033 | int start = 0; |
| 1034 | Rune* rune = NULL; |
| 1035 | int nrune = 0; |
| 1036 | Regexp::ParseFlags runeflags = Regexp::NoParseFlags; |
| 1037 | for (int i = 0; i <= nsub; i++) { |
| 1038 | // Invariant: sub[start:i] consists of regexps that all |
| 1039 | // begin with rune[0:nrune]. |
| 1040 | Rune* rune_i = NULL; |
| 1041 | int nrune_i = 0; |
| 1042 | Regexp::ParseFlags runeflags_i = Regexp::NoParseFlags; |
| 1043 | if (i < nsub) { |
| 1044 | rune_i = Regexp::LeadingString(sub[i], &nrune_i, &runeflags_i); |
| 1045 | if (runeflags_i == runeflags) { |
| 1046 | int same = 0; |
| 1047 | while (same < nrune && same < nrune_i && rune[same] == rune_i[same]) |
| 1048 | same++; |
| 1049 | if (same > 0) { |
| 1050 | // Matches at least one rune in current range. Keep going around. |
| 1051 | nrune = same; |
| 1052 | continue; |
| 1053 | } |
| 1054 | } |
| 1055 | } |
| 1056 | |
| 1057 | // Found end of a run with common leading literal string: |
| 1058 | // sub[start:i] all begin with rune[0:nrune], |
| 1059 | // but sub[i] does not even begin with rune[0]. |
| 1060 | if (i == start) { |
| 1061 | // Nothing to do - first iteration. |
| 1062 | } else if (i == start+1) { |
| 1063 | // Just one: don't bother factoring. |
| 1064 | } else { |
| 1065 | Regexp* prefix = Regexp::LiteralString(rune, nrune, runeflags); |
| 1066 | for (int j = start; j < i; j++) |
| 1067 | Regexp::RemoveLeadingString(sub[j], nrune); |
| 1068 | splices->emplace_back(prefix, sub + start, i - start); |
| 1069 | } |
| 1070 | |
| 1071 | // Prepare for next iteration (if there is one). |
| 1072 | if (i < nsub) { |
| 1073 | start = i; |
| 1074 | rune = rune_i; |
| 1075 | nrune = nrune_i; |
| 1076 | runeflags = runeflags_i; |
| 1077 | } |
| 1078 | } |
| 1079 | } |
| 1080 | |
| 1081 | void FactorAlternationImpl::Round2(Regexp** sub, int nsub, |
| 1082 | Regexp::ParseFlags flags, |
nothing calls this directly
no test coverage detected