module JsonParsing {
import { ../Json; ../JsonScanning; }
// JsonParser
pub mut struct JsonParser {
scanner: JsonScanner;
}
pub constructor(text : string) : JsonParser => {
return JsonParser(JsonScanner(text));
}
pub parseValue(this : JsonParser) : JsonValue => {
let token = this.scanner.scan();
return this.parseToken(token);
}
parseToken(this : JsonParser, token : JsonToken) : JsonValue => {
match (token) {
JsonNullToken => none;
JsonNumberToken(@val) => val;
JsonBoolToken(@val) => val;
JsonStringToken(@val) => val;
JsonLeftBraceToken => this.parseObject();
JsonLeftBracketToken => this.parseArray();
_ => throw JsonUnexpectedToken(token);
}
}
parseArray(this : JsonParser) : JsonArray => {
let array : mut JsonValue[] = [];
loop {
let token = this.scanner.scan();
if (token == JsonRightBracketToken) {
break;
}
array.append(this.parseToken(token));
}
return array.take();
}
parseObject(this : JsonParser) : JsonObject => {
let object : mut JsonMap = {};
loop {
let token = this.scanner.scan();
if (token == JsonRightBraceToken) {
break;
}
let field = token.verify{JsonStringToken}().val;
token = this.scanner.scan();
token.verify{JsonColonToken}();
token = this.scan.scan();
let value = parseToken(token);
object[field] = value;
}
return object.take();
}
// Helpers
verify{T}(token : JsonToken) : T => {
if (!(token is T)) {
throw JsonUnexpectedToken(token);
}
return token::T;
}
}