Skip to content

Commit

Permalink
solve #123 (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethosa authored Sep 1, 2023
1 parent 693ed8b commit 199e696
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
32 changes: 16 additions & 16 deletions src/regex.nim
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func re2*(s: string): Regex2 {.raises: [RegexError].} =
let pat = r"abc\w"
let abcx3 = re2(pat)

Regex2(reImpl(s))
reImpl(s).toRegex2

# Workaround Nim/issues/14515
# ideally only `re2(string): Regex`
Expand All @@ -342,9 +342,9 @@ when not defined(forceRegexAtRuntime):
func re2*(s: static string): static[Regex2] {.inline.} =
## Parse and compile a regular expression at compile-time
when canUseMacro: # VM dies on Nim < 1.1
Regex2(reCt(s))
reCt(s).toRegex2
else:
Regex2(reImpl(s))
reImpl(s).toRegex2

func group*(m: RegexMatch2, i: int): Slice[int] {.inline, raises: [].} =
## return slice for a given group.
Expand Down Expand Up @@ -430,11 +430,11 @@ func match*(
doAssert "abcd".match(re2"abcd", m)
doAssert not "abcd".match(re2"abc", m)

result = matchImpl(s, pattern.Regex, m, start)
result = matchImpl(s, pattern.toRegex, m, start)

func match*(s: string, pattern: Regex2): bool {.inline, raises: [].} =
var m: RegexMatch2
result = matchImpl(s, pattern.Regex, m)
result = matchImpl(s, pattern.toRegex, m)

when defined(noRegexOpt):
template findSomeOptTpl(s, pattern, ms, i): untyped =
Expand Down Expand Up @@ -470,11 +470,11 @@ iterator findAll*(
var ms: RegexMatches2
while i <= len(s):
doAssert(i > i2); i2 = i
i = findSomeOptTpl(s, pattern.Regex, ms, i)
i = findSomeOptTpl(s, pattern.toRegex, ms, i)
#debugEcho i
if i < 0: break
for mi in ms:
fillMatchImpl(m, mi, ms, pattern.Regex)
fillMatchImpl(m, mi, ms, pattern.toRegex)
yield m
if i == len(s):
break
Expand Down Expand Up @@ -507,7 +507,7 @@ iterator findAllBounds*(
var ms: RegexMatches2
while i <= len(s):
doAssert(i > i2); i2 = i
i = findSomeOptTpl(s, pattern.Regex, ms, i)
i = findSomeOptTpl(s, pattern.toRegex, ms, i)
#debugEcho i
if i < 0: break
for ab in ms.bounds:
Expand Down Expand Up @@ -573,7 +573,7 @@ iterator split*(s: string, sep: Regex2): string {.inline, raises: [].} =
ms: RegexMatches2
while not done:
doAssert(i > i2); i2 = i
i = findSomeOptTpl(s, sep.Regex, ms, i)
i = findSomeOptTpl(s, sep.toRegex, ms, i)
done = i < 0 or i >= len(s)
if done: ms.dummyMatch(s.len)
for ab in ms.bounds:
Expand Down Expand Up @@ -608,11 +608,11 @@ func splitIncl*(s: string, sep: Regex2): seq[string] {.inline, raises: [].} =
ms: RegexMatches2
while not done:
doAssert(i > i2); i2 = i
i = findSomeOptTpl(s, sep.Regex, ms, i)
i = findSomeOptTpl(s, sep.toRegex, ms, i)
done = i < 0 or i >= len(s)
if done: ms.dummyMatch(s.len)
for mi in ms:
fillMatchImpl(m, mi, ms, sep.Regex)
fillMatchImpl(m, mi, ms, sep.toRegex)
last = ab.a
if ab.a > 0 or ab.a <= ab.b: # skip first empty match
result.add substr(s, first, last-1)
Expand All @@ -630,7 +630,7 @@ func startsWith*(
doAssert "abc".startsWith(re2"\w")
doAssert not "abc".startsWith(re2"\d")

startsWithImpl2(s, pattern.Regex, start)
startsWithImpl2(s, pattern.toRegex, start)

template runeIncAt(s: string, n: var int) =
## increment ``n`` up to
Expand Down Expand Up @@ -703,7 +703,7 @@ func replace*(
result = ""
var
i, j = 0
capts = newSeqOfCap[string](pattern.Regex.groupsCount)
capts = newSeqOfCap[string](pattern.toRegex.groupsCount)
for m in findAll(s, pattern):
result.addsubstr(s, i, m.boundaries.a-1)
capts.setLen 0
Expand Down Expand Up @@ -758,7 +758,7 @@ func isInitialized*(re: Regex2): bool {.inline, raises: [].} =
re = re2"foo"
doAssert re.isInitialized

re.Regex.nfa.s.len > 0
re.toRegex.nfa.s.len > 0

func escapeRe*(s: string): string {.raises: [].} =
## Escape special regex characters in ``s``
Expand Down Expand Up @@ -793,7 +793,7 @@ proc toString(
result = "[...]"
return
visited.incl(nIdx)
let n = pattern.Regex.nfa.s[nIdx]
let n = pattern.toRegex.nfa.s[nIdx]
result = "["
result.add($n)
for nn in n.next:
Expand Down Expand Up @@ -1366,7 +1366,7 @@ when isMainModule:
doAssert(not match("A", re2"((?xi)) a"))
doAssert(not match("A", re2"(?xi:(?xi) )a"))

doAssert graph(Regex(re2"^a+$")) == """digraph graphname {
doAssert graph(re2"^a+$".toRegex) == """digraph graphname {
0 [label="q0";color=blue];
1 [label="q1";color=black];
2 [label="q2";color=blue];
Expand Down
31 changes: 29 additions & 2 deletions src/regex/nfatype.nim
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ type
namedGroups*: OrderedTable[string, int16]
#flags*: set[RegexFlag]
litOpt*: LitOpt
Regex2* = distinct Regex
## a compiled regular expression
MatchFlag* = enum
mfShortestMatch
mfNoCaptures
Expand All @@ -248,6 +246,35 @@ type
namedGroups*: OrderedTable[string, int16]
boundaries*: Slice[int]

when defined(js) and (NimMajor, NimMinor) >= (1, 6) and (NimMajor, NimMinor) <= (1, 7):
type
Regex2* = object
## a compiled regular expression
nfa*: Nfa
groupsCount*: int16
namedGroups*: OrderedTable[string, int16]
#flags*: set[RegexFlag]
litOpt*: LitOpt

{.push inline, noSideEffect.}
converter toRegex2*(r: Regex): Regex2 =
Regex2(nfa: r.nfa, groupsCount: r.groupsCount, namedGroups: r.namedGroups, litOpt: r.litOpt)

converter toRegex*(r: Regex2): Regex =
Regex(nfa: r.nfa, groupsCount: r.groupsCount, namedGroups: r.namedGroups, litOpt: r.litOpt)
{.pop.}
else:
type
Regex2* = distinct Regex
## a compiled regular expression

{.push inline, noSideEffect.}
converter toRegex2*(r: Regex): Regex2 = Regex2(r)

converter toRegex*(r: Regex2): Regex = Regex(r)
{.pop.}


func clear*(m: var RegexMatch) {.inline.} =
if m.captures.len > 0:
m.captures.setLen(0)
Expand Down

0 comments on commit 199e696

Please sign in to comment.