Interprets the postfix command sequence to create a regular expression passed to HandleRegexp. The results of operators like %s|%s are wrapped in (?: ) to avoid needing to maintain a precedence table.
| 190 | // passed to HandleRegexp. The results of operators like %s|%s are wrapped |
| 191 | // in (?: ) to avoid needing to maintain a precedence table. |
| 192 | void RegexpGenerator::RunPostfix(const std::vector<std::string>& post) { |
| 193 | std::stack<std::string> regexps; |
| 194 | for (size_t i = 0; i < post.size(); i++) { |
| 195 | switch (CountArgs(post[i])) { |
| 196 | default: |
| 197 | LOG(FATAL) << "Bad operator: " << post[i]; |
| 198 | case 0: |
| 199 | regexps.push(post[i]); |
| 200 | break; |
| 201 | case 1: { |
| 202 | std::string a = regexps.top(); |
| 203 | regexps.pop(); |
| 204 | regexps.push("(?:" + StringPrintf(post[i].c_str(), a.c_str()) + ")"); |
| 205 | break; |
| 206 | } |
| 207 | case 2: { |
| 208 | std::string b = regexps.top(); |
| 209 | regexps.pop(); |
| 210 | std::string a = regexps.top(); |
| 211 | regexps.pop(); |
| 212 | regexps.push("(?:" + |
| 213 | StringPrintf(post[i].c_str(), a.c_str(), b.c_str()) + |
| 214 | ")"); |
| 215 | break; |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | if (regexps.size() != 1) { |
| 221 | // Internal error - should never happen. |
| 222 | printf("Bad regexp program:\n"); |
| 223 | for (size_t i = 0; i < post.size(); i++) { |
| 224 | printf(" %s\n", CEscape(post[i]).c_str()); |
| 225 | } |
| 226 | printf("Stack after running program:\n"); |
| 227 | while (!regexps.empty()) { |
| 228 | printf(" %s\n", CEscape(regexps.top()).c_str()); |
| 229 | regexps.pop(); |
| 230 | } |
| 231 | LOG(FATAL) << "Bad regexp program."; |
| 232 | } |
| 233 | |
| 234 | HandleRegexp(regexps.top()); |
| 235 | HandleRegexp("^(?:" + regexps.top() + ")$"); |
| 236 | HandleRegexp("^(?:" + regexps.top() + ")"); |
| 237 | HandleRegexp("(?:" + regexps.top() + ")$"); |
| 238 | } |
| 239 | |
| 240 | // Split s into an vector of strings, one for each UTF-8 character. |
| 241 | std::vector<std::string> Explode(const StringPiece& s) { |