Skip to content

Commit bca0c64

Browse files
authored
Simpler capts (#154)
1 parent 7abf6a3 commit bca0c64

File tree

3 files changed

+32
-69
lines changed

3 files changed

+32
-69
lines changed

src/regex/nfafindall2.nim

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func add(ms: var RegexMatches2, m: MatchItem) {.inline.} =
8383
if max(msm[i].bounds.b, msm[i].bounds.a) < m.bounds.a:
8484
size = i+1
8585
break
86-
#for i in size .. msm.len-1:
86+
for i in size .. msm.len-1:
8787
if msm[i].capt != -1:
8888
capts.recyclable msm[i].capt
8989
msm.setLen size
@@ -159,8 +159,6 @@ func nextState(
159159
var eoeFound = false
160160
var smi = 0
161161
while smi < smA.len:
162-
if capt != -1:
163-
capts.keepAlive capt
164162
let L = nfa[n].next.len
165163
var nti = 0
166164
while nti < L:
@@ -189,7 +187,11 @@ func nextState(
189187
smB.add initPstate(nt0, captx, bounds.a .. i-1)
190188
inc smi
191189
swap smA, smB
192-
capts.recycle()
190+
if mfNoCaptures notin flags:
191+
for pstate in items smA:
192+
if pstate.ci != -1:
193+
capts.keepAlive pstate.ci
194+
capts.recycle()
193195

194196
func findSomeImpl*(
195197
text: string,

src/regex/nfamatch2.nim

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ func nextState(
142142
var matched = true
143143
smB.clear()
144144
for pstate in items smA:
145-
if capt != -1:
146-
capts.keepAlive capt
147145
if anchored and nfa[n].kind == reEoe:
148146
if n notin smB:
149147
smB.add initPstate(n, capt, bounds)
@@ -165,7 +163,11 @@ func nextState(
165163
if matched:
166164
smB.add initPstate(nt0, captx, bounds2)
167165
swap smA, smB
168-
capts.recycle()
166+
if mfNoCaptures notin flags:
167+
for pstate in items smA:
168+
if capt != -1:
169+
capts.keepAlive capt
170+
capts.recycle()
169171

170172
func matchImpl(
171173
smA, smB: var Pstates,

src/regex/nfatype.nim

Lines changed: 21 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ const nonCapture* = -1 .. -2
1414
# XXX limit lookarounds to int8.high per regex
1515
type CaptState* = uint8
1616
const
17-
stsInitial = 0.CaptState
18-
stsKeepAlive = 1.CaptState
19-
stsRecyclable = 2.CaptState
20-
stsRecycled = 3.CaptState
21-
stsNotRecyclable = 4.CaptState
22-
stsFrozen = 5.CaptState .. CaptState.high
17+
stsKeepAlive = 0.CaptState
18+
stsRecycle = 1.CaptState
19+
stsNotRecyclable = 2.CaptState
20+
stsFrozen = 3.CaptState .. CaptState.high
2321

2422
type
2523
# XXX int16 same as max parallel states or max regex len
@@ -81,72 +79,31 @@ func reset*(capts: var Capts3, groupsLen: int) =
8179
func initCapts3*(groupsLen: int): Capts3 =
8280
reset(result, groupsLen)
8381

84-
func check(curr, next: CaptState): bool =
85-
## Check if transition from state curr to next is allowed
86-
result = case next:
87-
of stsInitial:
88-
curr == stsInitial or
89-
curr == stsRecycled or
90-
curr == stsNotRecyclable or
91-
curr in stsFrozen
92-
of stsKeepAlive:
93-
curr == stsInitial or
94-
curr == stsRecyclable
95-
of stsRecyclable:
96-
curr == stsInitial or
97-
curr == stsKeepAlive
98-
of stsRecycled:
99-
curr == stsRecyclable or
100-
curr == stsRecycled
101-
of stsNotRecyclable:
102-
curr == stsInitial or
103-
curr == stsKeepAlive or
104-
curr in stsFrozen
105-
else:
106-
doAssert next in stsFrozen
107-
curr == stsInitial or
108-
curr == stsKeepAlive or
109-
curr == stsRecyclable
110-
111-
proc to(a: var CaptState, b: CaptState) {.inline.} =
112-
doAssert check(a, b), $a.int & " " & $b.int
113-
a = b
114-
115-
func keepAlive*(capts: var Capts3, captIdx: CaptIdx) {.inline.} =
116-
template state: untyped = capts.states[captIdx]
117-
doAssert state != stsRecycled
118-
if state == stsInitial or
119-
state == stsRecyclable:
120-
state.to stsKeepAlive
121-
12282
func freeze*(capts: var Capts3): CaptState =
12383
## Freeze all in use capts.
12484
## Return freezeId
12585
doAssert capts.freezeId < stsFrozen.b
12686
inc capts.freezeId
12787
result = capts.freezeId
12888
for state in mitems capts.states:
129-
if state == stsInitial or
130-
state == stsKeepAlive or
131-
state == stsRecyclable:
132-
state.to result
89+
if state == stsRecycle:
90+
state = result
13391

13492
func unfreeze*(capts: var Capts3, freezeId: CaptState) =
13593
doAssert freezeId in stsFrozen
13694
doAssert freezeId == capts.freezeId, "Unordered freeze/unfreeze call"
13795
for state in mitems capts.states:
13896
if state == freezeId:
139-
state.to stsInitial
97+
state = stsRecycle
14098
dec capts.freezeId
14199

142100
func diverge*(capts: var Capts3, captIdx: CaptIdx): CaptIdx =
143101
if capts.free.len > 0:
144102
result = capts.free.pop
145-
capts.states[result].to stsInitial
146103
else:
147104
result = capts.len.CaptIdx
148105
capts.s.setLen(capts.s.len+capts.blockSize)
149-
capts.states.add stsInitial
106+
capts.states.add stsRecycle
150107
doAssert result == capts.states.len-1
151108
let idx = capts.blockIdx(result)
152109
if captIdx != -1:
@@ -162,19 +119,20 @@ func recycle*(capts: var Capts3) =
162119
## Set initial/keepAlive entries to recyclable
163120
capts.free.setLen 0
164121
for i, state in mpairs capts.states:
165-
if state == stsRecyclable or
166-
state == stsRecycled:
122+
if state == stsRecycle:
167123
capts.free.add i.int16
168-
state.to stsRecycled
169-
if state == stsInitial or
170-
state == stsKeepAlive:
171-
state.to stsRecyclable
124+
if state == stsKeepAlive:
125+
state = stsRecycle
172126

173-
func notRecyclable*(capts: var Capts3, captIdx: CaptIdx) =
174-
capts.states[captIdx].to stsNotRecyclable
127+
func keepAlive*(capts: var Capts3, captIdx: CaptIdx) {.inline.} =
128+
if capts.states[captIdx] == stsRecycle:
129+
capts.states[captIdx] = stsKeepAlive
130+
131+
func notRecyclable*(capts: var Capts3, captIdx: CaptIdx) {.inline.} =
132+
capts.states[captIdx] = stsNotRecyclable
175133

176134
func recyclable*(capts: var Capts3, captIdx: CaptIdx) {.inline.} =
177-
capts.states[captIdx].to stsInitial
135+
capts.states[captIdx] = stsRecycle
178136

179137
func clear*(capts: var Capts3) =
180138
capts.s.setLen 0
@@ -446,6 +404,7 @@ when isMainModule:
446404
var captx1 = capts.diverge -1
447405
capts[captx1, 0] = 1..1
448406
capts[captx1, 1] = 2..2
407+
capts.keepAlive captx1
449408
capts.recycle()
450409
var captx2 = capts.diverge -1
451410
capts[captx2, 0] = 3..3
@@ -464,7 +423,6 @@ when isMainModule:
464423
doAssert capts[captx1, 0] == 1..1
465424
doAssert capts[captx1, 1] == 2..2
466425
capts.recycle()
467-
capts.recycle()
468426
var captx2 = capts.diverge -1
469427
doAssert captx1 == captx2
470428
doAssert capts[captx1, 0] == nonCapture
@@ -476,8 +434,8 @@ when isMainModule:
476434
capts[captx1, 1] = 2..2
477435
doAssert capts[captx1, 0] == 1..1
478436
doAssert capts[captx1, 1] == 2..2
479-
capts.recycle()
480437
capts.keepAlive captx1
438+
capts.recycle()
481439
var captx2 = capts.diverge -1
482440
doAssert captx1 != captx2
483441
doAssert capts[captx1, 0] == 1..1
@@ -561,3 +519,4 @@ when isMainModule:
561519
capts.recycle()
562520
capts.recycle()
563521
doAssert capts.free.len == 1
522+
echo "ok"

0 commit comments

Comments
 (0)