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
func Compile(re *Regexp) (*Prog, os.Error) {
82
f.out.patch(c.p, c.inst(InstMatch).i)
87
func (c *compiler) init() {
92
var anyRuneNotNL = []int{0, '\n' - 1, '\n' - 1, unicode.MaxRune}
93
var anyRune = []int{0, unicode.MaxRune}
95
func (c *compiler) compile(re *Regexp) frag {
102
if len(re.Rune) == 0 {
106
for j := range re.Rune {
107
f1 := c.rune(re.Rune[j : j+1])
116
return c.rune(re.Rune)
118
return c.rune(anyRuneNotNL)
120
return c.rune(anyRune)
122
return c.empty(EmptyBeginLine)
124
return c.empty(EmptyEndLine)
126
return c.empty(EmptyBeginText)
128
return c.empty(EmptyEndText)
130
return c.empty(EmptyWordBoundary)
131
case OpNoWordBoundary:
132
return c.empty(EmptyNoWordBoundary)
134
bra := c.cap(uint32(re.Cap << 1))
135
sub := c.compile(re.Sub[0])
136
ket := c.cap(uint32(re.Cap<<1 | 1))
137
return c.cat(c.cat(bra, sub), ket)
139
return c.star(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
141
return c.plus(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
143
return c.quest(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0)
145
if len(re.Sub) == 0 {
149
for i, sub := range re.Sub {
153
f = c.cat(f, c.compile(sub))
159
for _, sub := range re.Sub {
160
f = c.alt(f, c.compile(sub))
164
panic("regexp: unhandled case in compile")
167
func (c *compiler) inst(op InstOp) frag {
168
// TODO: impose length limit
169
f := frag{i: uint32(len(c.p.Inst))}
170
c.p.Inst = append(c.p.Inst, Inst{Op: op})
174
func (c *compiler) nop() frag {
176
f.out = patchList(f.i << 1)
180
func (c *compiler) fail() frag {
184
func (c *compiler) cap(arg uint32) frag {
185
f := c.inst(InstCapture)
186
f.out = patchList(f.i << 1)
187
c.p.Inst[f.i].Arg = arg
191
func (c *compiler) cat(f1, f2 frag) frag {
192
// concat of failure is failure
193
if f1.i == 0 || f2.i == 0 {
199
f1.out.patch(c.p, f2.i)
200
return frag{f1.i, f2.out}
203
func (c *compiler) alt(f1, f2 frag) frag {
204
// alt of failure is other
216
f.out = f1.out.append(c.p, f2.out)
220
func (c *compiler) quest(f1 frag, nongreedy bool) frag {
225
f.out = patchList(f.i << 1)
228
f.out = patchList(f.i<<1 | 1)
230
f.out = f.out.append(c.p, f1.out)
234
func (c *compiler) star(f1 frag, nongreedy bool) frag {
239
f.out = patchList(f.i << 1)
242
f.out = patchList(f.i<<1 | 1)
244
f1.out.patch(c.p, f.i)
248
func (c *compiler) plus(f1 frag, nongreedy bool) frag {
249
return frag{f1.i, c.star(f1, nongreedy).out}
252
func (c *compiler) empty(op EmptyOp) frag {
253
f := c.inst(InstEmptyWidth)
254
c.p.Inst[f.i].Arg = uint32(op)
255
f.out = patchList(f.i << 1)
259
func (c *compiler) rune(rune []int) frag {
260
f := c.inst(InstRune)
261
c.p.Inst[f.i].Rune = rune
262
f.out = patchList(f.i << 1)