Implement regex execution
This commit is contained in:
parent
613d12c7bf
commit
2db1a54710
2 changed files with 32 additions and 4 deletions
|
|
@ -1,9 +1,11 @@
|
||||||
[Package]
|
[Package]
|
||||||
name = "nre"
|
name = "nre"
|
||||||
|
author = "Flaviu Tamas"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Yet another PCRE library"
|
description = "Yet another PCRE library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
|
|
||||||
[Deps]
|
[Deps]
|
||||||
Requires: "nim >= 0.10.1"
|
Requires: "nim >= 0.10.0"
|
||||||
|
Requires: "optional_t >= 1.0"
|
||||||
|
|
|
||||||
32
src/nre.nim
32
src/nre.nim
|
|
@ -3,6 +3,8 @@ import private.util
|
||||||
import tables
|
import tables
|
||||||
import unsigned
|
import unsigned
|
||||||
from strutils import toLower, `%`
|
from strutils import toLower, `%`
|
||||||
|
from math import ceil
|
||||||
|
import optional_t
|
||||||
|
|
||||||
# PCRE Options {{{
|
# PCRE Options {{{
|
||||||
|
|
||||||
|
|
@ -70,7 +72,9 @@ type
|
||||||
|
|
||||||
RegexMatch* = object
|
RegexMatch* = object
|
||||||
pattern: Regex
|
pattern: Regex
|
||||||
matchBounds: Slice[int]
|
matchBounds: seq[Slice[cint]] ## First item is the bounds of the match
|
||||||
|
## Other items are the captures
|
||||||
|
## `a` is inclusive start, `b` is exclusive end
|
||||||
|
|
||||||
SyntaxError* = ref object of Exception
|
SyntaxError* = ref object of Exception
|
||||||
pos*: int ## the location of the syntax error in bytes
|
pos*: int ## the location of the syntax error in bytes
|
||||||
|
|
@ -141,5 +145,27 @@ proc getNameToNumberTable(self: Regex): Table[string, int] =
|
||||||
|
|
||||||
result[name] = num
|
result[name] = num
|
||||||
|
|
||||||
proc exec*(self: Regex, str: string): RegexMatch =
|
proc exec*(self: Regex, str: string, start = 0): Option[RegexMatch] =
|
||||||
discard
|
var result: RegexMatch
|
||||||
|
result.pattern = self
|
||||||
|
# See PCRE man pages.
|
||||||
|
# 2x capture count to make room for start-end pairs
|
||||||
|
# 1x capture count as slack space for PCRE
|
||||||
|
let vecsize = (self.getCaptureCount() + 1) * 3
|
||||||
|
# div 2 because each element is 2 cints long
|
||||||
|
result.matchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int)
|
||||||
|
result.matchBounds.setLen(vecsize div 3)
|
||||||
|
|
||||||
|
let execRet = pcre.exec(self.pcreObj,
|
||||||
|
self.pcreExtra,
|
||||||
|
cstring(str),
|
||||||
|
cint(str.len),
|
||||||
|
cint(start),
|
||||||
|
cint(0),
|
||||||
|
cast[ptr cint](addr result.matchBounds[0]), cint(vecsize))
|
||||||
|
if execRet >= 0:
|
||||||
|
return Some(result)
|
||||||
|
elif execRet == pcre.ERROR_NOMATCH:
|
||||||
|
return None[RegexMatch]()
|
||||||
|
else:
|
||||||
|
raise newException(AssertionError, "Internal error: errno " & $execRet)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue