8 // A patchList is a list of instruction pointers that need to be filled in (patched).
9 // Because the pointers haven't been filled in yet, we can reuse their storage
10 // to hold the list. It's kind of sleazy, but works well in practice.
11 // See http://swtch.com/~rsc/regexp/regexp1.html for inspiration.
13 // These aren't really pointers: they're integers, so we can reinterpret them
14 // this way without using package unsafe. A value l denotes
15 // p.inst[l>>1].Out (l&1==0) or .Arg (l&1==1).
16 // l == 0 denotes the empty list, okay because we start every program
17 // with a fail instruction, so we'll never want to point at its output link.
20 func (l patchList) next(p *Prog) patchList {
23 return patchList(i.Out)
25 return patchList(i.Arg)
28 func (l patchList) patch(p *Prog, val uint32) {
41 func (l1 patchList) append(p *Prog, l2 patchList) patchList {
67 // A frag represents a compiled program fragment.
69 i uint32 // index of first instruction
70 out patchList // where to record end instruction
73 type compiler struct {
77 // Compile compiles the regexp into a program to be executed.
78 // The regexp should have been simplified already (returned from re.Simplify).
79 func Compile(re *Regexp) (*Prog, os.Error) {
83 f.out.patch(c.p, c.inst(InstMatch).i)
88 func (c *compiler) init() {
90 c.p.NumCap = 2 // implicit ( and ) for whole match $0
94 var anyRuneNotNL = []int{0, '\n' - 1, '\n' + 1, unicode.MaxRune}
95 var anyRune = []int{0, unicode.MaxRune}
97 func (c *compiler) compile(re *Regexp) frag {
104 if len(re.Rune) == 0 {
108 for j := range re.Rune {
109 f1 := c.rune(re.Rune[j:j+1], re.Flags)
118 return c.rune(re.Rune, re.Flags)
120 return c.rune(anyRuneNotNL, 0)
122 return c.rune(anyRune, 0)
124 return c.empty(EmptyBeginLine)
126 return c.empty(EmptyEndLine)
128 return c.empty(EmptyBeginText)
130 return c.empty(EmptyEndText)
132 return c.empty(EmptyWordBoundary)
133 case OpNoWordBoundary:
134 return c.empty(EmptyNoWordBoundary)
136 bra := c.cap(uint32(re.Cap << 1))
137 sub := c.compile(re.Sub[0])
138 ket := c.cap(uint32(re.Cap<<1 | 1))
139 return c.cat(c.cat(bra, sub), ket)
141 return c.star(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
143 return c.plus(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
145 return c.quest(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
147 if len(re.Sub) == 0 {
151 for i, sub := range re.Sub {
155 f = c.cat(f, c.compile(sub))
161 for _, sub := range re.Sub {
162 f = c.alt(f, c.compile(sub))
166 panic("regexp: unhandled case in compile")
169 func (c *compiler) inst(op InstOp) frag {
170 // TODO: impose length limit
171 f := frag{i: uint32(len(c.p.Inst))}
172 c.p.Inst = append(c.p.Inst, Inst{Op: op})
176 func (c *compiler) nop() frag {
178 f.out = patchList(f.i << 1)
182 func (c *compiler) fail() frag {
186 func (c *compiler) cap(arg uint32) frag {
187 f := c.inst(InstCapture)
188 f.out = patchList(f.i << 1)
189 c.p.Inst[f.i].Arg = arg
191 if c.p.NumCap < int(arg)+1 {
192 c.p.NumCap = int(arg) + 1
197 func (c *compiler) cat(f1, f2 frag) frag {
198 // concat of failure is failure
199 if f1.i == 0 || f2.i == 0 {
205 f1.out.patch(c.p, f2.i)
206 return frag{f1.i, f2.out}
209 func (c *compiler) alt(f1, f2 frag) frag {
210 // alt of failure is other
222 f.out = f1.out.append(c.p, f2.out)
226 func (c *compiler) quest(f1 frag, nongreedy bool) frag {
231 f.out = patchList(f.i << 1)
234 f.out = patchList(f.i<<1 | 1)
236 f.out = f.out.append(c.p, f1.out)
240 func (c *compiler) star(f1 frag, nongreedy bool) frag {
245 f.out = patchList(f.i << 1)
248 f.out = patchList(f.i<<1 | 1)
250 f1.out.patch(c.p, f.i)
254 func (c *compiler) plus(f1 frag, nongreedy bool) frag {
255 return frag{f1.i, c.star(f1, nongreedy).out}
258 func (c *compiler) empty(op EmptyOp) frag {
259 f := c.inst(InstEmptyWidth)
260 c.p.Inst[f.i].Arg = uint32(op)
261 f.out = patchList(f.i << 1)
265 func (c *compiler) rune(rune []int, flags Flags) frag {
266 f := c.inst(InstRune)
269 flags &= FoldCase // only relevant flag is FoldCase
270 if len(rune) != 1 || unicode.SimpleFold(rune[0]) == rune[0] {
271 // and sometimes not even that
274 i.Arg = uint32(flags)
275 f.out = patchList(f.i << 1)
277 // Special cases for exec machine.
279 case flags&FoldCase == 0 && (len(rune) == 1 || len(rune) == 2 && rune[0] == rune[1]):
281 case len(rune) == 2 && rune[0] == 0 && rune[1] == unicode.MaxRune:
283 case len(rune) == 4 && rune[0] == 0 && rune[1] == '\n'-1 && rune[2] == '\n'+1 && rune[3] == unicode.MaxRune:
284 i.Op = InstRuneAnyNotNL