pegs: don't rely on terminating zero

This commit is contained in:
Andreas Rumpf 2018-04-29 07:43:11 +02:00
commit 4375dfd9d0

View file

@ -534,15 +534,15 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
case p.kind case p.kind
of pkEmpty: result = 0 # match of length 0 of pkEmpty: result = 0 # match of length 0
of pkAny: of pkAny:
if s[start] != '\0': result = 1 if start < s.len: result = 1
else: result = -1 else: result = -1
of pkAnyRune: of pkAnyRune:
if s[start] != '\0': if start < s.len:
result = runeLenAt(s, start) result = runeLenAt(s, start)
else: else:
result = -1 result = -1
of pkLetter: of pkLetter:
if s[start] != '\0': if start < s.len:
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
@ -551,7 +551,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
else: else:
result = -1 result = -1
of pkLower: of pkLower:
if s[start] != '\0': if start < s.len:
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
@ -560,7 +560,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
else: else:
result = -1 result = -1
of pkUpper: of pkUpper:
if s[start] != '\0': if start < s.len:
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
@ -569,7 +569,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
else: else:
result = -1 result = -1
of pkTitle: of pkTitle:
if s[start] != '\0': if start < s.len:
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
@ -578,7 +578,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
else: else:
result = -1 result = -1
of pkWhitespace: of pkWhitespace:
if s[start] != '\0': if start < s.len:
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
@ -589,15 +589,15 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
of pkGreedyAny: of pkGreedyAny:
result = len(s) - start result = len(s) - start
of pkNewLine: of pkNewLine:
if s[start] == '\L': result = 1 if start < s.len and s[start] == '\L': result = 1
elif s[start] == '\C': elif start < s.len and s[start] == '\C':
if s[start+1] == '\L': result = 2 if start+1 < s.len and s[start+1] == '\L': result = 2
else: result = 1 else: result = 1
else: result = -1 else: result = -1
of pkTerminal: of pkTerminal:
result = len(p.term) result = len(p.term)
for i in 0..result-1: for i in 0..result-1:
if p.term[i] != s[start+i]: if start+i >= s.len or p.term[i] != s[start+i]:
result = -1 result = -1
break break
of pkTerminalIgnoreCase: of pkTerminalIgnoreCase:
@ -606,6 +606,9 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
a, b: Rune a, b: Rune
result = start result = start
while i < len(p.term): while i < len(p.term):
if i >= s.len:
result = -1
break
fastRuneAt(p.term, i, a) fastRuneAt(p.term, i, a)
fastRuneAt(s, result, b) fastRuneAt(s, result, b)
if toLower(a) != toLower(b): if toLower(a) != toLower(b):
@ -621,18 +624,23 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
while true: while true:
fastRuneAt(p.term, i, a) fastRuneAt(p.term, i, a)
if a != Rune('_'): break if a != Rune('_'): break
while true: while result < s.len:
fastRuneAt(s, result, b) fastRuneAt(s, result, b)
if b != Rune('_'): break if b != Rune('_'): break
if toLower(a) != toLower(b): if result >= s.len:
if i >= p.term.len: break
else:
result = -1
break
elif toLower(a) != toLower(b):
result = -1 result = -1
break break
dec(result, start) dec(result, start)
of pkChar: of pkChar:
if p.ch == s[start]: result = 1 if start < s.len and p.ch == s[start]: result = 1
else: result = -1 else: result = -1
of pkCharChoice: of pkCharChoice:
if contains(p.charChoice[], s[start]): result = 1 if start < s.len and contains(p.charChoice[], s[start]): result = 1
else: result = -1 else: result = -1
of pkNonTerminal: of pkNonTerminal:
var oldMl = c.ml var oldMl = c.ml
@ -695,10 +703,10 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
of pkGreedyRepChar: of pkGreedyRepChar:
result = 0 result = 0
var ch = p.ch var ch = p.ch
while ch == s[start+result]: inc(result) while start+result < s.len and ch == s[start+result]: inc(result)
of pkGreedyRepSet: of pkGreedyRepSet:
result = 0 result = 0
while contains(p.charChoice[], s[start+result]): inc(result) while start+result < s.len and contains(p.charChoice[], s[start+result]): inc(result)
of pkOption: of pkOption:
result = max(0, rawMatch(s, p.sons[0], start, c)) result = max(0, rawMatch(s, p.sons[0], start, c))
of pkAndPredicate: of pkAndPredicate: