Source File
exec.go
Belonging Package
regexp
package regexp
import (
)
if .bytes.str != nil {
.bytes.str = nil
} else if .reader.r != nil {
.reader.r = nil
} else {
.string.str = ""
}
}
func ( *inputs) ( io.RuneReader, []byte, string) (input, int) {
if != nil {
return .newReader(), 0
}
if != nil {
return .newBytes(), len()
}
return .newString(), len()
}
func ( *machine) ( int) {
for , := range .pool {
.cap = .cap[:]
}
.matchcap = .matchcap[:]
}
type lazyFlag uint64
func (, rune) lazyFlag {
return lazyFlag(uint64()<<32 | uint64(uint32()))
}
func ( lazyFlag) ( syntax.EmptyOp) bool {
if == 0 {
return true
}
:= rune( >> 32)
if &syntax.EmptyBeginLine != 0 {
if != '\n' && >= 0 {
return false
}
&^= syntax.EmptyBeginLine
}
if &syntax.EmptyBeginText != 0 {
if >= 0 {
return false
}
&^= syntax.EmptyBeginText
}
if == 0 {
return true
}
:= rune()
if &syntax.EmptyEndLine != 0 {
if != '\n' && >= 0 {
return false
}
&^= syntax.EmptyEndLine
}
if &syntax.EmptyEndText != 0 {
if >= 0 {
return false
}
&^= syntax.EmptyEndText
}
if == 0 {
return true
}
if syntax.IsWordChar() != syntax.IsWordChar() {
&^= syntax.EmptyWordBoundary
} else {
&^= syntax.EmptyNoWordBoundary
}
return == 0
}
func ( *machine) ( input, int) bool {
:= .re.cond
if == ^syntax.EmptyOp(0) { // impossible
return false
}
.matched = false
for := range .matchcap {
.matchcap[] = -1
}
, := &.q0, &.q1
, := endOfText, endOfText
, := 0, 0
, = .step()
if != endOfText {
, = .step( + )
}
var lazyFlag
if == 0 {
= newLazyFlag(-1, )
} else {
= .context()
}
for {
if len(.dense) == 0 {
break
}
break
}
func ( *machine) (, *queue, , int, rune, *lazyFlag) {
:= .re.longest
for := 0; < len(.dense); ++ {
:= &.dense[]
:= .t
if == nil {
continue
}
if && .matched && len(.cap) > 0 && .matchcap[0] < .cap[0] {
.pool = append(.pool, )
continue
}
:= .inst
:= false
switch .Op {
default:
panic("bad inst")
case syntax.InstMatch:
if len(.cap) > 0 && (! || !.matched || .matchcap[1] < ) {
.cap[1] =
copy(.matchcap, .cap)
}
for , := range .dense[+1:] {
if .t != nil {
.pool = append(.pool, .t)
}
}
.dense = .dense[:0]
}
.matched = true
case syntax.InstRune:
= .MatchRune()
case syntax.InstRune1:
= == .Rune[0]
case syntax.InstRuneAny:
= true
case syntax.InstRuneAnyNotNL:
= != '\n'
}
if {
= .add(, .Out, , .cap, , )
}
if != nil {
.pool = append(.pool, )
}
}
.dense = .dense[:0]
}
func ( *machine) ( *queue, uint32, int, []int, *lazyFlag, *thread) *thread {
:
if == 0 {
return
}
if := .sparse[]; < uint32(len(.dense)) && .dense[].pc == {
return
}
:= len(.dense)
.dense = .dense[:+1]
:= &.dense[]
.t = nil
.pc =
.sparse[] = uint32()
:= &.p.Inst[]
switch .Op {
default:
panic("unhandled")
case syntax.InstAlt, syntax.InstAltMatch:
= .(, .Out, , , , )
= .Arg
goto
case syntax.InstEmptyWidth:
if .match(syntax.EmptyOp(.Arg)) {
= .Out
goto
}
case syntax.InstNop:
= .Out
goto
case syntax.InstCapture:
if int(.Arg) < len() {
:= [.Arg]
[.Arg] =
.(, .Out, , , , nil)
[.Arg] =
} else {
= .Out
goto
}
case syntax.InstMatch, syntax.InstRune, syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
if == nil {
= .alloc()
} else {
.inst =
}
if len() > 0 && &.cap[0] != &[0] {
copy(.cap, )
}
.t =
= nil
}
return
}
type onePassMachine struct {
inputs inputs
matchcap []int
}
var onePassPool sync.Pool
func () *onePassMachine {
, := onePassPool.Get().(*onePassMachine)
if ! {
= new(onePassMachine)
}
return
}
func ( *onePassMachine) {
.inputs.clear()
onePassPool.Put()
}
func ( *Regexp) ( io.RuneReader, []byte, string, , int, []int) []int {
:= .cond
if == ^syntax.EmptyOp(0) { // impossible
return nil
}
:= newOnePassMachine()
if cap(.matchcap) < {
.matchcap = make([]int, )
} else {
.matchcap = .matchcap[:]
}
:= false
for := range .matchcap {
.matchcap[] = -1
}
, := .inputs.init(, , )
, := endOfText, endOfText
, := 0, 0
, = .step()
if != endOfText {
, = .step( + )
}
var lazyFlag
if == 0 {
= newLazyFlag(-1, )
} else {
= .context()
}
:= .onepass.Start
if !.hasPrefix() {
goto
}
+= len(.prefix)
, = .step()
, = .step( + )
= .context()
= int(.prefixEnd)
}
for {
= .onepass.Inst[]
= int(.Out)
switch .Op {
default:
panic("bad inst")
case syntax.InstMatch:
= true
if len(.matchcap) > 0 {
.matchcap[0] = 0
.matchcap[1] =
}
goto
case syntax.InstRune:
if !.MatchRune() {
goto
}
case syntax.InstRune1:
if != .Rune[0] {
goto
}
case syntax.InstRuneAnyNotNL:
if == '\n' {
goto
case syntax.InstAlt, syntax.InstAltMatch:
= int(onePassNext(&, ))
continue
case syntax.InstFail:
goto
case syntax.InstNop:
continue
case syntax.InstEmptyWidth:
if !.match(syntax.EmptyOp(.Arg)) {
goto
}
continue
case syntax.InstCapture:
if int(.Arg) < len(.matchcap) {
.matchcap[.Arg] =
}
continue
}
if == 0 {
break
}
= newLazyFlag(, )
+=
, = ,
if != endOfText {
, = .step( + )
}
}
:
if ! {
freeOnePassMachine()
return nil
}
= append(, .matchcap...)
freeOnePassMachine()
return
}
= arrayNoInts[:0:0]
}
if == nil && len()+len() < .minInputLen {
return nil
}
if .onepass != nil {
return .doOnePass(, , , , , )
}
if == nil && len()+len() < .maxBitStateLen {
return .backtrack(, , , , )
}
:= .get()
, := .inputs.init(, , )
.init()
if !.match(, ) {
.put()
return nil
}
= append(, .matchcap...)
.put()
return
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |