From bc3464ede77bba781928b7b0f425373a520077a4 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Tue, 21 Oct 2014 16:49:29 -0400 Subject: [PATCH 1/2] Modify pegs.nim such that no match will return nil An empty match will return "" A zero-length match will return nil Add test cases Add news information --- lib/pure/pegs.nim | 18 +++++++++++++++++- web/news.txt | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index b2d8a2a4ff..6eb7dee786 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -737,7 +737,12 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. template fillMatches(s, caps, c: expr) = for k in 0..c.ml-1: - caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) + let startIdx = c.matches[k][0] + let endIdx = c.matches[k][1] + if startIdx != -1: + caps[k] = substr(s, startIdx, endIdx) + else: + caps[k] = nil proc match*(s: string, pattern: Peg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = @@ -1767,3 +1772,14 @@ when isMainModule: assert match("prefix/start", peg"^start$", 7) + if "foo" =~ peg"{'a'}?.*": + assert matches[0] == nil + else: assert false + + if "foo" =~ peg"{''}.*": + assert matches[0] == "" + else: assert false + + if "foo" =~ peg"{'foo'}": + assert matches[0] == "foo" + else: assert false diff --git a/web/news.txt b/web/news.txt index c9374558af..c79eb55cc7 100644 --- a/web/news.txt +++ b/web/news.txt @@ -20,6 +20,8 @@ News - String case (or any non-ordinal case) statements without 'else' are deprecated. - Recursive tuple types are not allowed anymore. Use ``object`` instead. + - The PEGS module returns ``nil`` instead of ``""`` when an optional capture + fails to match Language Additions ------------------ From 218cb7587a351c9a29a7de5961f168a5cdbb5a70 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Sun, 26 Oct 2014 09:31:21 -0400 Subject: [PATCH 2/2] re module returns nil on failed captures - tests included - news.txt updated --- lib/impure/re.nim | 16 +++++++++++++--- web/news.txt | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index fc9ed3ce06..6e3a69c62c 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -92,7 +92,7 @@ proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string], var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return rawMatches[1] - rawMatches[0] proc findBounds*(s: string, pattern: Regex, matches: var openArray[string], @@ -110,7 +110,7 @@ proc findBounds*(s: string, pattern: Regex, matches: var openArray[string], var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return (rawMatches[0].int, rawMatches[1].int - 1) proc findBounds*(s: string, pattern: Regex, @@ -190,7 +190,7 @@ proc find*(s: string, pattern: Regex, matches: var openArray[string], var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return rawMatches[0] proc find*(s: string, pattern: Regex, start = 0): int = @@ -310,6 +310,8 @@ proc replacef*(s: string, sub: Regex, by: string): string = while true: var match = findBounds(s, sub, caps, prev) if match.first < 0: break + assert result != nil + assert s != nil add(result, substr(s, prev, match.first-1)) addf(result, by, caps) prev = match.last + 1 @@ -450,6 +452,14 @@ when isMainModule: assert matches[1] == "abc" else: assert false + + if "abc" =~ re"(cba)?.*": + assert matches[0] == nil + else: assert false + + if "abc" =~ re"().*": + assert matches[0] == "" + else: assert false assert "var1=key; var2=key2".endsWith(re"\w+=\w+") assert("var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") == diff --git a/web/news.txt b/web/news.txt index c79eb55cc7..b4316c989c 100644 --- a/web/news.txt +++ b/web/news.txt @@ -22,6 +22,8 @@ News - Recursive tuple types are not allowed anymore. Use ``object`` instead. - The PEGS module returns ``nil`` instead of ``""`` when an optional capture fails to match + - The re module returns ``nil`` instead of ``""`` when an optional capture + fails to match Language Additions ------------------