JSON parser implementation.
class json parser
import ideal • machine • channels • string writer
auto constructor class parse result
json parser(character handler the character handler)
this • the character handler = the character handler
private nonnegative scan(string input, nonnegative start)
if the character handler • is whitespace(next)
if the character handler • is digit(next)
if next == '-'
if next == json token • OPEN BRACE • the character
if next == json token • CLOSE BRACE • the character
if next == json token • OPEN BRACKET • the character
if next == json token • CLOSE BRACKET • the character
if next == json token • COMMA • the character
if next == json token • COLON • the character
if next == 't'
if next == 'f'
if next == 'n'
while index < input • size && the character handler • is whitespace(input[index])
if next == '"'
index += 1
return index
result : string writer • new()
while index < input • size
if next in input == '"'
else if next in input == '\\'
if index >= input • size
else if escaped character == 'b'
else if escaped character == 'f'
else if escaped character == 'n'
else if escaped character == 'r'
else if escaped character == 't'
else if escaped character == 'u'
else
report error("Escape at the end of input")
return index
index += 1
if escaped character == '"' || escaped character == '\\' || escaped character == '/'
result • write('\b')
result • write('\f')
result • write('\n')
result • write('\r')
result • write('\t')
if index + 4 >= input • size
else
report error("Unicode escape at the end of input")
return index
index += 4
report error("Unrecognized escape character: " ++ escaped character)
return index
index += 1
report error("No closing quote in a string")
return index
return index
return index
return index
return index
return index
return index
report error("Unrecognized character in a string: " ++ next)
return index
private nonnegative hex digit(character the character)
if result is nonnegative
else
return result
report error("Unrecognized character in hex escape: " ++ the character)
return 0
private nonnegative scan number(string input, nonnegative start, boolean negate)
if !the character handler • is digit(next)
report error("Unrecognized digit: " ++ next)
return start
assert digit is nonnegative
var index : start + 1
while index < input • size && the character handler • is digit(input[index])
assert next digit is nonnegative
index += 1
return index
private nonnegative scan symbol(string input, nonnegative start, string symbol, deeply immutable data value)
private parse result parse value(nonnegative start)
if start >= tokens • size
if next == json token • OPEN BRACE
else if next == json token • OPEN BRACKET
if next is json token
return parse error("End of tokens when parsing value")
return parse object(start)
return parse array(start)
return parse error("Unexpected token: " ++ next)
private parse result parse object(nonnegative start)
if tokens[start] != json token • OPEN BRACE
return parse error("Open brace expected")
var index : start + 1
while index < tokens • size
if next == json token • CLOSE BRACE
if next is_not string
if index >= tokens • size
if tokens[index] == json token • CLOSE BRACE
if tokens[index] != json token • COMMA
return parse error("Expected string identifier in object")
index += 1
while index >= tokens • size || tokens[index] != json token • COLON
return parse error("Expected colon in object")
index += 1
if has error()
return element
return parse error("No closing brace in object")
return parse error("Expected comma in object")
index += 1
return parse error("No closing brace in object")
private parse result parse array(nonnegative start)
if tokens[start] != json token • OPEN BRACKET
return parse error("Open bracket expected")
var index : start + 1
while index < tokens • size
if tokens[index] == json token • CLOSE BRACKET
if has error()
if index >= tokens • size
if tokens[index] == json token • CLOSE BRACKET
if tokens[index] != json token • COMMA
return element
return parse error("No closing bracket in array")
return parse error("Expected comma in array")
index += 1
return parse error("No closing bracket in array")
private parse result parse error(string message)
report error(message)
return parse result • new(message, 0)