| 208 | private static final int[] ANY_RUNE = {0, Unicode.MAX_RUNE}; |
| 209 | |
| 210 | private Frag compile(Regexp re) { |
| 211 | switch (re.op) { |
| 212 | case NO_MATCH: |
| 213 | return fail(); |
| 214 | case EMPTY_MATCH: |
| 215 | return nop(); |
| 216 | case LITERAL: |
| 217 | if (re.runes.length == 0) { |
| 218 | return nop(); |
| 219 | } else { |
| 220 | Frag f = null; |
| 221 | for (int r : re.runes) { |
| 222 | Frag f1 = rune(r, re.flags); |
| 223 | f = (f == null) ? f1 : cat(f, f1); |
| 224 | } |
| 225 | return f; |
| 226 | } |
| 227 | case CHAR_CLASS: |
| 228 | return rune(re.runes, re.flags); |
| 229 | case ANY_CHAR_NOT_NL: |
| 230 | return rune(ANY_RUNE_NOT_NL, 0); |
| 231 | case ANY_CHAR: |
| 232 | return rune(ANY_RUNE, 0); |
| 233 | case BEGIN_LINE: |
| 234 | return empty(Utils.EMPTY_BEGIN_LINE); |
| 235 | case END_LINE: |
| 236 | return empty(Utils.EMPTY_END_LINE); |
| 237 | case BEGIN_TEXT: |
| 238 | return empty(Utils.EMPTY_BEGIN_TEXT); |
| 239 | case END_TEXT: |
| 240 | return empty(Utils.EMPTY_END_TEXT); |
| 241 | case WORD_BOUNDARY: |
| 242 | return empty(Utils.EMPTY_WORD_BOUNDARY); |
| 243 | case NO_WORD_BOUNDARY: |
| 244 | return empty(Utils.EMPTY_NO_WORD_BOUNDARY); |
| 245 | case CAPTURE: |
| 246 | { |
| 247 | Frag bra = cap(re.cap << 1), sub = compile(re.subs[0]), ket = cap(re.cap << 1 | 1); |
| 248 | return cat(cat(bra, sub), ket); |
| 249 | } |
| 250 | case STAR: |
| 251 | return star(compile(re.subs[0]), (re.flags & RE2.NON_GREEDY) != 0); |
| 252 | case PLUS: |
| 253 | return plus(compile(re.subs[0]), (re.flags & RE2.NON_GREEDY) != 0); |
| 254 | case QUEST: |
| 255 | return quest(compile(re.subs[0]), (re.flags & RE2.NON_GREEDY) != 0); |
| 256 | case CONCAT: |
| 257 | if (re.subs.length == 0) { |
| 258 | return nop(); |
| 259 | } else { |
| 260 | Frag f = null; |
| 261 | for (Regexp sub : re.subs) { |
| 262 | Frag f1 = compile(sub); |
| 263 | f = (f == null) ? f1 : cat(f, f1); |
| 264 | } |
| 265 | return f; |
| 266 | } |
| 267 | case ALTERNATE: |