Compiler from Regexp (RE2 abstract syntax) to RE2 (compiled regular expression). The only entry point is #compileRegexp.
| 15 | * The only entry point is {@link #compileRegexp}. |
| 16 | */ |
| 17 | class Compiler { |
| 18 | |
| 19 | /** |
| 20 | * A fragment of a compiled regular expression program. |
| 21 | * |
| 22 | * @see http://swtch.com/~rsc/regexp/regexp1.html |
| 23 | */ |
| 24 | private static class Frag { |
| 25 | final int i; // an instruction address (pc). |
| 26 | int out; // a patch list; see explanation in Prog.java |
| 27 | boolean nullable; // whether the fragment can match the empty string |
| 28 | |
| 29 | Frag() { |
| 30 | this(0, 0); |
| 31 | } |
| 32 | |
| 33 | Frag(int i) { |
| 34 | this(i, 0); |
| 35 | } |
| 36 | |
| 37 | Frag(int i, int out) { |
| 38 | this(i, out, false); |
| 39 | } |
| 40 | |
| 41 | Frag(int i, int out, boolean nullable) { |
| 42 | this.i = i; |
| 43 | this.out = out; |
| 44 | this.nullable = nullable; |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | private final Prog prog = new Prog(); // Program being built |
| 49 | |
| 50 | private Compiler() { |
| 51 | newInst(Inst.FAIL); // always the first instruction |
| 52 | } |
| 53 | |
| 54 | static Prog compileRegexp(Regexp re) { |
| 55 | Compiler c = new Compiler(); |
| 56 | Frag f = c.compile(re); |
| 57 | c.prog.patch(f.out, c.newInst(Inst.MATCH).i); |
| 58 | c.prog.start = f.i; |
| 59 | return c.prog; |
| 60 | } |
| 61 | |
| 62 | private Frag newInst(int op) { |
| 63 | // TODO(rsc): impose length limit. |
| 64 | prog.addInst(op); |
| 65 | return new Frag(prog.numInst() - 1, 0, true); |
| 66 | } |
| 67 | |
| 68 | // Returns a no-op fragment. Sometimes unavoidable. |
| 69 | private Frag nop() { |
| 70 | Frag f = newInst(Inst.NOP); |
| 71 | f.out = f.i << 1; |
| 72 | return f; |
| 73 | } |
| 74 |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…