Skip to content

Commit

Permalink
JTD parsing: sckip whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Feb 23, 2021
1 parent 749401a commit 48715a5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
9 changes: 8 additions & 1 deletion lib/compile/jtd/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import N from "../names"
import {isOwnProperty, hasPropFunc} from "../../vocabularies/code"
import {hasRef} from "../../vocabularies/jtd/ref"
import {intRange, IntType} from "../../vocabularies/jtd/type"
import {parseJson, parseJsonNumber, parseJsonString} from "../../runtime/parseJson"
import {parseJson, parseJsonNumber, parseJsonString, skipWhitespace} from "../../runtime/parseJson"
import {func} from "../util"
import validTimestamp from "../timestamp"

Expand Down Expand Up @@ -84,6 +84,7 @@ function parserFunction(cxt: ParseCxt, parseName: Name): void {
gen.assign(N.jsonPos, _`${N.jsonPos} || 0`)
gen.const(N.jsonLen, _`${N.json}.length`)
parseCode(cxt)
whitespace(gen)
gen.if(N.jsonPart, () => gen.return(_`[${N.data}, ${N.jsonPos}]`))
gen.if(_`${N.jsonPos} === ${N.jsonLen}`, () => gen.return(N.data))
jsonSyntaxError(cxt)
Expand Down Expand Up @@ -298,6 +299,7 @@ function parseEnum(cxt: ParseCxt): void {

function parseNumber(cxt: ParseCxt, maxDigits?: number): void {
const {gen} = cxt
gen.assign(N.jsonPos, _`${func(gen, skipWhitespace)}(${N.json}, ${N.jsonPos})`)
gen.if(
_`"-0123456789".indexOf(${jsonSlice(1)}) < 0`,
() => jsonSyntaxError(cxt),
Expand Down Expand Up @@ -360,6 +362,7 @@ function parseToken(cxt: ParseCxt, tok: string): void {
function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, success?: GenParse): void {
const {gen} = cxt
const n = tok.length
whitespace(gen)
gen.if(
_`${jsonSlice(n)} === ${tok}`,
() => {
Expand All @@ -370,6 +373,10 @@ function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, success?: Gen
)
}

function whitespace(gen: CodeGen): void {
gen.assign(N.jsonPos, _`${func(gen, skipWhitespace)}(${N.json}, ${N.jsonPos})`)
}

function jsonSlice(len: number | Name): Code {
return len === 1
? _`${N.json}[${N.jsonPos}]`
Expand Down
8 changes: 8 additions & 0 deletions lib/runtime/parseJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ export function parseJsonString(s: string, pos: number): [string, number] {

parseJsonString.code = _`require("ajv/dist/runtime/parseJson").parseJsonString`

export function skipWhitespace(s: string, pos: number): number {
let c: string
while (((c = s[pos]), c === " " || c === "\n" || c === "\r" || c === "\t")) pos++
return pos
}

skipWhitespace.code = _`require("ajv/dist/runtime/parseJson").skipWhitespace`

function unexpectedEnd(): never {
throw new SyntaxError("Unexpected end of JSON input")
}
Expand Down
4 changes: 3 additions & 1 deletion spec/jtd-schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe("JSON Type Definition", () => {
}
})

describe("parse", () => {
describe.only("parse", () => {
const ajv = new _AjvJTD()

for (const testName in jtdValidationTests) {
Expand All @@ -123,12 +123,14 @@ describe("JSON Type Definition", () => {
const parse = ajv.compileParser(schema)
// console.log(schema, instance, `"${JSON.stringify(instance)}"`, parse.toString())
assert.deepStrictEqual(parse(JSON.stringify(instance)), instance)
assert.deepStrictEqual(parse(` ${JSON.stringify(instance, null, 2)} `), instance)
})
} else {
it(`should throw exception on invalid JSON string`, () => {
const parse = ajv.compileParser(schema)
// console.log(parse.toString())
assert.throws(() => parse(JSON.stringify(instance)))
assert.throws(() => parse(` ${JSON.stringify(instance, null, 2)} `))
})
}
})
Expand Down

0 comments on commit 48715a5

Please sign in to comment.