introduce PsycSyntaxError and error messages
parent
87674ac5af
commit
eaeed9a16d
35
parse.nim
35
parse.nim
|
@ -27,6 +27,8 @@ type
|
||||||
cursor: int
|
cursor: int
|
||||||
remainingPartLen: int
|
remainingPartLen: int
|
||||||
|
|
||||||
|
PsycSyntaxError = object of Exception
|
||||||
|
|
||||||
Validator = proc(c: char): bool
|
Validator = proc(c: char): bool
|
||||||
|
|
||||||
proc validateTrue(c: char): bool = true
|
proc validateTrue(c: char): bool = true
|
||||||
|
@ -41,10 +43,13 @@ proc getUntil(input: string, delimiters: openArray[char], packet: var PsycPacket
|
||||||
result.complete = true
|
result.complete = true
|
||||||
if i > packet.cursor:
|
if i > packet.cursor:
|
||||||
result.value = input[packet.cursor .. i - 1]
|
result.value = input[packet.cursor .. i - 1]
|
||||||
|
else:
|
||||||
|
result.value = ""
|
||||||
packet.cursor = i
|
packet.cursor = i
|
||||||
break
|
break
|
||||||
if not validate(input[i]):
|
if not validate(input[i]):
|
||||||
raise new(ValueError)
|
raise newException(PsycSyntaxError,
|
||||||
|
"invalid character '" & input[i] & "' in " & $packet.state)
|
||||||
|
|
||||||
proc parseKeyword(input: string,
|
proc parseKeyword(input: string,
|
||||||
packet: var PsycPacket): tuple[complete: bool, value: string] =
|
packet: var PsycPacket): tuple[complete: bool, value: string] =
|
||||||
|
@ -53,8 +58,8 @@ proc parseKeyword(input: string,
|
||||||
result = input.getUntil([' ', '\t', '\n'], packet, validate)
|
result = input.getUntil([' ', '\t', '\n'], packet, validate)
|
||||||
if result.complete:
|
if result.complete:
|
||||||
packet.cursor.inc()
|
packet.cursor.inc()
|
||||||
if result.value.isNil() or result.value.len() == 0 or result.value[0] != '_':
|
if result.value.len() == 0 or result.value[0] != '_':
|
||||||
raise new(ValueError) # name does not start with '_'
|
raise newException(PsycSyntaxError, $packet.state & " does not start with '_'")
|
||||||
|
|
||||||
proc parseModifierValueLength(input: string,
|
proc parseModifierValueLength(input: string,
|
||||||
packet: var PsycPacket): tuple[complete: bool,
|
packet: var PsycPacket): tuple[complete: bool,
|
||||||
|
@ -64,10 +69,13 @@ proc parseModifierValueLength(input: string,
|
||||||
return (false, -1)
|
return (false, -1)
|
||||||
packet.cursor.inc()
|
packet.cursor.inc()
|
||||||
if value.len() == 0:
|
if value.len() == 0:
|
||||||
raise new(ValueError) # no value length
|
raise newException(PsycSyntaxError, "missing length after " & $packet.state)
|
||||||
result = (true, value.parseInt()) # may throw ValueError if invalid number
|
try:
|
||||||
|
result = (true, value.parseInt()) # may throw ValueError if invalid number
|
||||||
|
except ValueError:
|
||||||
|
raise newException(PsycSyntaxError, "invalid length after " & $packet.state)
|
||||||
if result.value < 0:
|
if result.value < 0:
|
||||||
raise new(ValueError) # negative value length
|
raise newException(PsycSyntaxError, "invalid length after " & $packet.state)
|
||||||
|
|
||||||
proc parseModifierName(input: string,
|
proc parseModifierName(input: string,
|
||||||
packet: var PsycPacket): tuple[complete: bool,
|
packet: var PsycPacket): tuple[complete: bool,
|
||||||
|
@ -84,7 +92,8 @@ proc parseModifierName(input: string,
|
||||||
packet.cursor.inc()
|
packet.cursor.inc()
|
||||||
if result.op == '?':
|
if result.op == '?':
|
||||||
if input[packet.cursor] != '\n':
|
if input[packet.cursor] != '\n':
|
||||||
raise new(ValueError) # '?' must be on a line by itself
|
raise newException(PsycSyntaxError,
|
||||||
|
$packet.state & " has invalid operator '?'")
|
||||||
result.complete = true
|
result.complete = true
|
||||||
return
|
return
|
||||||
(result.complete, result.name) = parseKeyword(input, packet)
|
(result.complete, result.name) = parseKeyword(input, packet)
|
||||||
|
@ -96,7 +105,7 @@ proc parseModifierName(input: string,
|
||||||
(result.complete, packet.remainingPartLen) = parseModifierValueLength(input,
|
(result.complete, packet.remainingPartLen) = parseModifierValueLength(input,
|
||||||
packet)
|
packet)
|
||||||
elif input[packet.cursor - 1] != '\t':
|
elif input[packet.cursor - 1] != '\t':
|
||||||
raise new(ValueError) # invalid separator
|
raise newException(PsycSyntaxError, $packet.state & " has invalid separator")
|
||||||
|
|
||||||
proc parseMethod(input: string, packet: var PsycPacket): tuple[complete: bool,
|
proc parseMethod(input: string, packet: var PsycPacket): tuple[complete: bool,
|
||||||
value: string] =
|
value: string] =
|
||||||
|
@ -126,7 +135,8 @@ proc parseModifierValue(input: string,
|
||||||
if result.complete:
|
if result.complete:
|
||||||
result.value = input[packet.cursor .. packet.cursor + packet.remainingPartLen - 1]
|
result.value = input[packet.cursor .. packet.cursor + packet.remainingPartLen - 1]
|
||||||
if input[packet.cursor + packet.remainingPartLen] != '\n':
|
if input[packet.cursor + packet.remainingPartLen] != '\n':
|
||||||
raise new(ValueError) # missing '\n' after binary-arg
|
raise newException(PsycSyntaxError,
|
||||||
|
$packet.state & " is missing '\n' after binary-arg")
|
||||||
packet.cursor += result.value.len() + 1
|
packet.cursor += result.value.len() + 1
|
||||||
packet.remainingPartLen = -1
|
packet.remainingPartLen = -1
|
||||||
else:
|
else:
|
||||||
|
@ -144,9 +154,12 @@ proc parseContentLength(input: string,
|
||||||
if value.len() == 0:
|
if value.len() == 0:
|
||||||
result.value = -1
|
result.value = -1
|
||||||
else:
|
else:
|
||||||
result.value = value.parseInt() # parseInt may throw ValueError if invalid number
|
try:
|
||||||
|
result.value = value.parseInt() # parseInt may throw ValueError if invalid number
|
||||||
|
except ValueError:
|
||||||
|
raise newException(PsycSyntaxError, "invalid length after " & $packet.state)
|
||||||
if result.value < 0:
|
if result.value < 0:
|
||||||
raise new(ValueError) # negative content length
|
raise newException(PsycSyntaxError, "invalid length after " & $packet.state)
|
||||||
|
|
||||||
proc parseData(input: string,
|
proc parseData(input: string,
|
||||||
packet: var PsycPacket): tuple[complete: bool, value: string] =
|
packet: var PsycPacket): tuple[complete: bool, value: string] =
|
||||||
|
|
Loading…
Reference in New Issue