From 971218314e0439561f908ff10ce55f66697bf29f Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Sat, 23 Jan 2016 17:44:50 +0100 Subject: [PATCH] fastparse: made it pass the parsing tests * Scan for implicit map key as soon as a property is encountered * Proper handling of node properties throughout parser * Fixed an issue where plain scalars sometimes contained garbage when yielded * Catch reserved chars @ and ` * Fixed some test cases * Made parser test cases use fastparse --- private/fastparse.nim | 214 ++++++++++++++--------------- test/parsing.nim | 310 +++++++++++++++++++----------------------- 2 files changed, 241 insertions(+), 283 deletions(-) diff --git a/private/fastparse.nim b/private/fastparse.nim index e31855a..92c2d6f 100644 --- a/private/fastparse.nim +++ b/private/fastparse.nim @@ -63,10 +63,13 @@ template yieldLevelEnd() {.dirty.} = anchor = yAnchorNone yield endMapEvent() of fplScalar: - applyObjectProperties() yield scalarEvent(content, tag, anchor) + tag = yTagQuestionMark + anchor = yAnchorNone of fplUnknown: - yield scalarEvent("") + yield scalarEvent("", tag, anchor) + tag = yTagQuestionMark + anchor = yAnchorNone template handleLineEnd(insideDocument: bool) {.dirty.} = case lexer.buf[lexer.bufpos] @@ -99,31 +102,24 @@ template handleObjectEnd(nextState: FastParseState) {.dirty.} = of fplUnknown, fplScalar: assert(false) -template handleObjectStart(k: YamlStreamEventKind, isFlow: bool) {.dirty.} = +template handleObjectStart(k: YamlStreamEventKind) {.dirty.} = assert(level.kind == fplUnknown) when k == yamlStartMap: - when isFlow: - yield startMapEvent(tag, anchor) - else: - yield startMapEvent(objectTag, objectAnchor) - debug("started map at " & $indentation) + yield startMapEvent(tag, anchor) + debug("started map at " & (if level.indentation == -1: $indentation else: + $level.indentation)) level.kind = fplMapKey else: - when isFlow: - yield startSeqEvent(tag, anchor) - else: - yield startSeqEvent(objectTag, objectAnchor) - debug("started sequence at " & $indentation) + yield startSeqEvent(tag, anchor) + debug("started sequence at " & (if level.indentation == -1: $indentation else: + $level.indentation)) level.kind = fplSequence - when isFlow: - tag = yTagQuestionmark - anchor = yAnchorNone - else: - objectTag = yTagQuestionmark - objectAnchor = yAnchorNone - level.indentation = indentation + tag = yTagQuestionmark + anchor = yAnchorNone + if level.indentation == -1: + level.indentation = indentation ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) template closeMoreIndentedLevels() {.dirty.} = while ancestry.len > 0: @@ -145,23 +141,22 @@ template closeEverything() {.dirty.} = template handleBlockSequenceIndicator() {.dirty.} = case level.kind of fplUnknown: - handleObjectStart(yamlStartSequence, false) + handleObjectStart(yamlStartSequence) of fplSequence: if level.indentation != indentation: raiseError("Invalid indentation of block sequence indicator", lexer.bufpos) ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) else: raiseError("Illegal sequence item in map") lexer.skipWhitespace() indentation = lexer.getColNumber(lexer.bufpos) - level.indentation = indentation template handleMapKeyIndicator() {.dirty.} = case level.kind of fplUnknown: - handleObjectStart(yamlStartMap, false) + handleObjectStart(yamlStartMap) of fplMapValue: if level.indentation != indentation: raiseError("Invalid indentation of map key indicator", @@ -169,26 +164,31 @@ template handleMapKeyIndicator() {.dirty.} = yield scalarEvent("", yTagQuestionmark, yAnchorNone) level.kind = fplMapKey ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplMapKey: if level.indentation != indentation: raiseError("Invalid indentation of map key indicator", lexer.bufpos) ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplSequence: raiseError("Unexpected map key indicator (expected '- ')") of fplScalar: raiseError("Unexpected map key indicator (expected multiline scalar end)") lexer.skipWhitespace() indentation = lexer.getColNumber(lexer.bufpos) - level.indentation = indentation template handleMapValueIndicator() {.dirty.} = case level.kind of fplUnknown: - handleObjectStart(yamlStartMap, false) - yield scalarEvent("", yTagQuestionmark, yAnchorNone) + if level.indentation == -1: + handleObjectStart(yamlStartMap) + yield scalarEvent("", yTagQuestionmark, yAnchorNone) + else: + yield scalarEvent("", tag, anchor) + tag = yTagQuestionmark + anchor = yAnchorNone + ancestry[ancestry.high].kind = fplMapValue of fplMapKey: if level.indentation != indentation: raiseError("Invalid indentation of map key indicator", @@ -196,32 +196,19 @@ template handleMapValueIndicator() {.dirty.} = yield scalarEvent("", yTagQuestionmark, yAnchorNone) level.kind = fplMapValue ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplMapValue: if level.indentation != indentation: raiseError("Invalid indentation of map key indicator", lexer.bufpos) ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplSequence: raiseError("Unexpected map value indicator (expected '- ')") of fplScalar: raiseError("Unexpected map value indicator (expected multiline scalar end)") lexer.skipWhitespace() indentation = lexer.getColNumber(lexer.bufpos) - level.indentation = indentation - -template propsToObjectProps() {.dirty.} = - if objectTag == yTagQuestionmark: - objectTag = tag - tag = yTagQuestionmark - elif tag != yTagQuestionMark: - raiseError("Only one tag is allowed per node") - if objectAnchor == yAnchorNone: - objectAnchor = anchor - anchor = yAnchorNone - elif anchor != yAnchorNone: - raiseError("Only one anchor is allowed per node") template initDocValues() {.dirty.} = shorthands = initTable[string, string]() @@ -229,26 +216,9 @@ template initDocValues() {.dirty.} = shorthands["!"] = "!" shorthands["!!"] = "tag:yaml.org,2002:" nextAnchorId = 0.AnchorId - level = FastParseLevel(kind: fplUnknown, indentation: 0) + level = FastParseLevel(kind: fplUnknown, indentation: -1) tag = yTagQuestionmark - objectTag = yTagQuestionmark anchor = yAnchorNone - objectAnchor = yAnchorNone - -template applyObjectProperties() {.dirty.} = - if objectTag != yTagQuestionmark: - if tag != yTagQuestionmark: - debug("tag = " & $tag & ", object = " & $objectTag) - raiseError("Only one tag is allowed per node") - else: - tag = objectTag - objectTag = yTagQuestionmark - if objectAnchor != yAnchorNone: - if anchor != yAnchorNone: - raiseError("Only one anchor is allowed per node") - else: - anchor = objectAnchor - objectAnchor = yAnchorNone template handleTagHandle() {.dirty.} = if level.kind != fplUnknown: @@ -309,43 +279,47 @@ template leaveFlowLevel() {.dirty.} = handleObjectEnd(fpFlowAfterObject) template handlePossibleMapStart() {.dirty.} = - var flowDepth = 0 - for p in countup(lexer.bufpos, lexer.bufpos + 1024): - case lexer.buf[p] - of ':': - if flowDepth == 0 and lexer.buf[p + 1] in spaceOrLineEnd: - handleObjectStart(yamlStartMap, false) + if level.indentation == -1: + var flowDepth = 0 + for p in countup(lexer.bufpos, lexer.bufpos + 1024): + case lexer.buf[p] + of ':': + if flowDepth == 0 and lexer.buf[p + 1] in spaceOrLineEnd: + handleObjectStart(yamlStartMap) + break + of lineEnd: break - of lineEnd: - break - of '[', '{': - flowDepth.inc() - of '}', ']': - flowDepth.inc(-1) - of '?': - if flowDepth == 0: break - of '#': - if lexer.buf[p - 1] in space: break - else: - discard + of '[', '{': + flowDepth.inc() + of '}', ']': + flowDepth.inc(-1) + of '?': + if flowDepth == 0: break + of '#': + if lexer.buf[p - 1] in space: + break + else: + discard + if level.indentation == -1: + level.indentation = indentation template handleBlockItemStart() {.dirty.} = case level.kind of fplUnknown: - discard + handlePossibleMapStart() of fplSequence: raiseError("Unexpected token (expected block sequence indicator)", lexer.bufpos) of fplMapKey: ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: indentation) of fplMapValue: yield scalarEvent("", tag, anchor) tag = yTagQuestionmark anchor = yAnchorNone level.kind = fplMapKey ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: indentation) of fplScalar: assert(false) @@ -815,10 +789,8 @@ template anchorName(lexer: FastLexer, content: var string) = lexer.bufpos.inc() let c = lexer.buf[lexer.bufpos] case c - of spaceOrLineEnd: + of spaceOrLineEnd, '[', ']', '{', '}', ',': break - of '[', ']', '{', '}', ',': - raiseError("Illegal character in anchor", lexer.bufpos) else: content.add(c) @@ -998,8 +970,8 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = anchors: Table[string, AnchorId] nextAnchorId: AnchorId content: string - tag, objectTag: TagId - anchor, objectAnchor: AnchorId + tag: TagId + anchor: AnchorId ancestry = newSeq[FastParseLevel]() level: FastParseLevel indentation: int @@ -1040,12 +1012,30 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = lexer.finishLine() handleLineEnd(false) of ' ', '\t': - lexer.bufpos.inc() + while true: + lexer.bufpos.inc() + case lexer.buf[lexer.bufpos] + of ' ', '\t': + discard + of '\x0A': + lexer.bufpos = lexer.handleLF(lexer.bufpos) + break + of '\c': + lexer.bufpos = lexer.handleCR(lexer.bufpos) + break + of '#', EndOfFile: + lexer.lineEnding() + handleLineEnd(false) + break + else: + indentation = lexer.getColNumber(lexer.bufpos) + yield startDocEvent() + state = fpBlockObjectStart + break of '\x0A': lexer.bufpos = lexer.handleLF(lexer.bufpos) of '\c': lexer.bufpos = lexer.handleCR(lexer.bufpos) - lexer.bufpos.inc() of EndOfFile: return of '#': @@ -1099,7 +1089,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = else: ensureCorrectIndentation() ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) content = "" lexer.plainScalar(content, cBlockOut) state = fpBlockAfterPlainScalar @@ -1124,7 +1114,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = else: ensureCorrectIndentation() ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) content = "" lexer.plainScalar(content, cBlockOut) state = fpBlockAfterPlainScalar @@ -1140,9 +1130,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplScalar: state = fpBlockContinueScalar of fplUnknown: - handlePossibleMapStart() state = fpBlockObjectStart - level.indentation = indentation else: ensureCorrectIndentation() state = fpBlockObjectStart @@ -1153,9 +1141,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplScalar: state = fpBlockContinueScalar of fplUnknown: - handlePossibleMapStart() state = fpBlockObjectStart - level.indentation = indentation else: ensureCorrectIndentation() state = fpBlockObjectStart @@ -1219,16 +1205,16 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of ':': case level.kind of fplUnknown: - handleObjectStart(yamlStartMap, false) + handleObjectStart(yamlStartMap) of fplMapKey: yield scalarEvent("", yTagQuestionMark, yAnchorNone) level.kind = fplMapValue ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplMapValue: level.kind = fplMapValue ancestry.add(level) - level.kind = fplUnknown + level = FastParseLevel(kind: fplUnknown, indentation: -1) of fplSequence: raiseError("Illegal token (expected sequence item)") of fplScalar: @@ -1236,10 +1222,8 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = lexer.bufpos.inc() lexer.skipWhitespace() indentation = lexer.getColNumber(lexer.bufpos) - level.indentation = indentation state = fpBlockObjectStart of '#': - applyObjectProperties() lexer.lineEnding() handleLineEnd(true) handleObjectEnd(fpBlockLineStart) @@ -1253,13 +1237,13 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = let objectStart = lexer.getColNumber(lexer.bufpos) case lexer.buf[lexer.bufpos] of '\x0A': - propsToObjectProps() lexer.bufpos = lexer.handleLF(lexer.bufpos) state = fpBlockLineStart + level.indentation = -1 of '\c': - propsToObjectProps() lexer.bufpos = lexer.handleCR(lexer.bufpos) state = fpBlockLineStart + level.indentation = -1 of EndOfFile: closeEverything() return @@ -1283,8 +1267,11 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = yield scalarEvent(content, tag, anchor) handleObjectEnd(fpBlockAfterObject) of '|', '>': + # TODO: this will scan for possible map start, which is not + # neccessary in this case handleBlockItemStart() var stateAfter: FastParseState + content = "" lexer.blockScalar(content, stateAfter) if tag == yTagQuestionmark: tag = yTagExclamationmark @@ -1293,6 +1280,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of '-': if lexer.isPlainSafe(lexer.bufpos + 1, cBlockOut): handleBlockItemStart() + content = "" lexer.tokenstart = lexer.getColNumber(lexer.bufpos) lexer.plainScalar(content, cBlockOut) state = fpBlockAfterPlainScalar @@ -1310,11 +1298,11 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = handleAlias() of '[', '{': handleBlockItemStart() - applyObjectProperties() state = fpFlow of '?': if lexer.isPlainSafe(lexer.bufpos + 1, cBlockOut): handleBlockItemStart() + content = "" lexer.tokenstart = lexer.getColNumber(lexer.bufpos) lexer.plainScalar(content, cBlockOut) state = fpBlockAfterPlainScalar @@ -1324,12 +1312,16 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of ':': if lexer.isPlainSafe(lexer.bufpos + 1, cBlockOut): handleBlockItemStart() + content = "" lexer.tokenstart = lexer.getColNumber(lexer.bufpos) lexer.plainScalar(content, cBlockOut) state = fpBlockAfterPlainScalar else: lexer.bufpos.inc() handleMapValueIndicator() + of '@', '`': + raiseError("Reserved characters cannot start a plain scalar", + lexer.bufpos) else: handleBlockItemStart() content = "" @@ -1376,12 +1368,12 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = lexer.skipWhitespaceAndNewlines() case lexer.buf[lexer.bufpos] of '{': - handleObjectStart(yamlStartMap, true) + handleObjectStart(yamlStartMap) flowdepth.inc() lexer.bufpos.inc() explicitFlowKey = false of '[': - handleObjectStart(yamlStartSequence, true) + handleObjectStart(yamlStartSequence) flowdepth.inc() lexer.bufpos.inc() of '}': @@ -1444,7 +1436,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplUnknown, fplScalar: assert(false) ancestry.add(level) - level = FastParseLevel(kind: fplUnknown) + level = FastParseLevel(kind: fplUnknown, indentation: -1) lexer.bufpos.inc() of ':': assert(level.kind == fplUnknown) @@ -1461,7 +1453,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplUnknown, fplScalar: assert(false) ancestry.add(level) - level = FastParseLevel(kind: fplUnknown) + level = FastParseLevel(kind: fplUnknown, indentation: -1) lexer.bufpos.inc() else: handleFlowPlainScalar() @@ -1533,7 +1525,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplUnknown, fplScalar: assert(false) ancestry.add(level) - level = FastParseLevel(kind: fplUnknown) + level = FastParseLevel(kind: fplUnknown, indentation: -1) state = fpFlow lexer.bufpos.inc() of ':': @@ -1545,7 +1537,7 @@ proc fastparse*(tagLib: TagLibrary, s: Stream): YamlStream = of fplUnknown, fplScalar: assert(false) ancestry.add(level) - level = FastParseLevel(kind: fplUnknown) + level = FastParseLevel(kind: fplUnknown, indentation: -1) state = fpFlow lexer.bufpos.inc() of '#': diff --git a/test/parsing.nim b/test/parsing.nim index bc1c4e7..0bc608e 100644 --- a/test/parsing.nim +++ b/test/parsing.nim @@ -2,39 +2,6 @@ import "../yaml" import unittest -proc startDoc(): YamlStreamEvent = - result.kind = yamlStartDocument - -proc endDoc(): YamlStreamEvent = - result.kind = yamlEndDocument - -proc scalar(content: string, - tag: TagId = yTagQuestionMark, anchor: AnchorId = yAnchorNone): - YamlStreamEvent = scalarEvent(content, tag, anchor) - -proc startSequence(tag: TagId = yTagQuestionMark, - anchor: AnchorId = yAnchorNone): - YamlStreamEvent = - result.kind = yamlStartSequence - result.seqAnchor = anchor - result.seqTag = tag - -proc endSequence(): YamlStreamEvent = - result.kind = yamlEndSequence - -proc startMap(tag: TagId = yTagQuestionMark, anchor: AnchorId = yAnchorNone): - YamlStreamEvent = - result.kind = yamlStartMap - result.mapAnchor = anchor - result.mapTag = tag - -proc endMap(): YamlStreamEvent = - result.kind = yamlEndMap - -proc alias(target: AnchorId): YamlStreamEvent = - result.kind = yamlAlias - result.aliasTarget = target - proc printDifference(expected, actual: YamlStreamEvent) = if expected.kind != actual.kind: echo "expected " & $expected.kind & ", got " & $actual.kind @@ -45,10 +12,10 @@ proc printDifference(expected, actual: YamlStreamEvent) = echo "[\"", actual.scalarContent, "\".tag] expected tag ", expected.scalarTag, ", got ", actual.scalarTag elif expected.scalarAnchor != actual.scalarAnchor: - echo "[scalar] expected anchor ", expected.scalarAnchor, + echo "[scalarEvent] expected anchor ", expected.scalarAnchor, ", got ", actual.scalarAnchor elif expected.scalarContent != actual.scalarContent: - let msg = "[scalar] expected content \"" & + let msg = "[scalarEvent] expected content \"" & expected.scalarContent & "\", got \"" & actual.scalarContent & "\" " if expected.scalarContent.len != actual.scalarContent.len: @@ -63,7 +30,7 @@ proc printDifference(expected, actual: YamlStreamEvent) = cast[int](actual.scalarContent[i]), ")" break else: - echo "[scalar] Unknown difference" + echo "[scalarEvent] Unknown difference" of yamlStartMap: if expected.mapTag != actual.mapTag: echo "[map.tag] expected ", expected.mapTag, ", got ", @@ -85,9 +52,8 @@ proc printDifference(expected, actual: YamlStreamEvent) = template ensure(input: string, expected: varargs[YamlStreamEvent]) {.dirty.} = var - parser = newParser(tagLib) i = 0 - events = parser.parse(newStringStream(input)) + events = fastparse(tagLib, newStringStream(input)) try: for token in events(): if i >= expected.len: @@ -113,183 +79,183 @@ suite "Parsing": teardown: discard - test "Parsing: Simple Scalar": - ensure("Scalar", startDoc(), scalar("Scalar"), endDoc()) + test "Parsing: Simple scalarEvent": + ensure("scalarEvent", startDocEvent(), scalarEvent("scalarEvent"), endDocEvent()) test "Parsing: Simple Sequence": - ensure("- off", startDoc(), startSequence(), - scalar("off"), endSequence(), endDoc()) + ensure("- off", startDocEvent(), startSeqEvent(), + scalarEvent("off"), endSeqEvent(), endDocEvent()) test "Parsing: Simple Map": - ensure("42: value\nkey2: -7.5", startDoc(), startMap(), - scalar("42"), scalar("value"), scalar("key2"), - scalar("-7.5"), endMap(), endDoc()) + ensure("42: value\nkey2: -7.5", startDocEvent(), startMapEvent(), + scalarEvent("42"), scalarEvent("value"), scalarEvent("key2"), + scalarEvent("-7.5"), endMapEvent(), endDocEvent()) test "Parsing: Explicit Map": - ensure("? null\n: value\n? ON\n: value2", startDoc(), startMap(), - scalar("null"), scalar("value"), - scalar("ON"), scalar("value2"), - endMap(), endDoc()) + ensure("? null\n: value\n? ON\n: value2", startDocEvent(), startMapEvent(), + scalarEvent("null"), scalarEvent("value"), + scalarEvent("ON"), scalarEvent("value2"), + endMapEvent(), endDocEvent()) test "Parsing: Mixed Map (explicit to implicit)": - ensure("? a\n: 13\n1.5: d", startDoc(), startMap(), scalar("a"), - scalar("13"), scalar("1.5"), - scalar("d"), endMap(), endDoc()) + ensure("? a\n: 13\n1.5: d", startDocEvent(), startMapEvent(), scalarEvent("a"), + scalarEvent("13"), scalarEvent("1.5"), + scalarEvent("d"), endMapEvent(), endDocEvent()) test "Parsing: Mixed Map (implicit to explicit)": - ensure("a: 4.2\n? 23\n: d", startDoc(), startMap(), scalar("a"), - scalar("4.2"), scalar("23"), - scalar("d"), endMap(), endDoc()) + ensure("a: 4.2\n? 23\n: d", startDocEvent(), startMapEvent(), scalarEvent("a"), + scalarEvent("4.2"), scalarEvent("23"), + scalarEvent("d"), endMapEvent(), endDocEvent()) test "Parsing: Missing values in map": - ensure("? a\n? b\nc:", startDoc(), startMap(), scalar("a"), scalar(""), - scalar("b"), scalar(""), scalar("c"), scalar(""), endMap(), - endDoc()) + ensure("? a\n? b\nc:", startDocEvent(), startMapEvent(), scalarEvent("a"), scalarEvent(""), + scalarEvent("b"), scalarEvent(""), scalarEvent("c"), scalarEvent(""), endMapEvent(), + endDocEvent()) test "Parsing: Missing keys in map": - ensure(": a\n: b", startDoc(), startMap(), scalar(""), scalar("a"), - scalar(""), scalar("b"), endMap(), endDoc()) - test "Parsing: Multiline scalars in explicit map": - ensure("? a\n true\n: null\n d\n? e\n 42", startDoc(), startMap(), - scalar("a true"), scalar("null d"), scalar("e 42"), scalar(""), - endMap(), endDoc()) + ensure(": a\n: b", startDocEvent(), startMapEvent(), scalarEvent(""), scalarEvent("a"), + scalarEvent(""), scalarEvent("b"), endMapEvent(), endDocEvent()) + test "Parsing: Multiline scalarEvents in explicit map": + ensure("? a\n true\n: null\n d\n? e\n 42", startDocEvent(), startMapEvent(), + scalarEvent("a true"), scalarEvent("null d"), scalarEvent("e 42"), scalarEvent(""), + endMapEvent(), endDocEvent()) test "Parsing: Map in Sequence": ensure(" - key: value\n key2: value2\n -\n key3: value3", - startDoc(), startSequence(), startMap(), scalar("key"), - scalar("value"), scalar("key2"), scalar("value2"), endMap(), - startMap(), scalar("key3"), scalar("value3"), endMap(), - endSequence(), endDoc()) + startDocEvent(), startSeqEvent(), startMapEvent(), scalarEvent("key"), + scalarEvent("value"), scalarEvent("key2"), scalarEvent("value2"), endMapEvent(), + startMapEvent(), scalarEvent("key3"), scalarEvent("value3"), endMapEvent(), + endSeqEvent(), endDocEvent()) test "Parsing: Sequence in Map": - ensure("key:\n - item1\n - item2", startDoc(), startMap(), - scalar("key"), startSequence(), scalar("item1"), scalar("item2"), - endSequence(), endMap(), endDoc()) + ensure("key:\n - item1\n - item2", startDocEvent(), startMapEvent(), + scalarEvent("key"), startSeqEvent(), scalarEvent("item1"), scalarEvent("item2"), + endSeqEvent(), endMapEvent(), endDocEvent()) test "Parsing: Sequence in Sequence": - ensure("- - l1_i1\n - l1_i2\n- l2_i1", startDoc(), startSequence(), - startSequence(), scalar("l1_i1"), scalar("l1_i2"), endSequence(), - scalar("l2_i1"), endSequence(), endDoc()) + ensure("- - l1_i1\n - l1_i2\n- l2_i1", startDocEvent(), startSeqEvent(), + startSeqEvent(), scalarEvent("l1_i1"), scalarEvent("l1_i2"), endSeqEvent(), + scalarEvent("l2_i1"), endSeqEvent(), endDocEvent()) test "Parsing: Flow Sequence": - ensure("[2, b]", startDoc(), startSequence(), scalar("2"), - scalar("b"), endSequence(), endDoc()) + ensure("[2, b]", startDocEvent(), startSeqEvent(), scalarEvent("2"), + scalarEvent("b"), endSeqEvent(), endDocEvent()) test "Parsing: Flow Map": - ensure("{a: Y, 1.337: d}", startDoc(), startMap(), scalar("a"), - scalar("Y"), scalar("1.337"), - scalar("d"), endMap(), endDoc()) + ensure("{a: Y, 1.337: d}", startDocEvent(), startMapEvent(), scalarEvent("a"), + scalarEvent("Y"), scalarEvent("1.337"), + scalarEvent("d"), endMapEvent(), endDocEvent()) test "Parsing: Flow Sequence in Flow Sequence": - ensure("[a, [b, c]]", startDoc(), startSequence(), scalar("a"), - startSequence(), scalar("b"), scalar("c"), endSequence(), - endSequence(), endDoc()) + ensure("[a, [b, c]]", startDocEvent(), startSeqEvent(), scalarEvent("a"), + startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(), + endSeqEvent(), endDocEvent()) test "Parsing: Flow Sequence in Flow Map": - ensure("{a: [b, c], [d, e]: f}", startDoc(), startMap(), scalar("a"), - startSequence(), scalar("b"), scalar("c"), endSequence(), - startSequence(), scalar("d"), scalar("e"), endSequence(), - scalar("f"), endMap(), endDoc()) + ensure("{a: [b, c], [d, e]: f}", startDocEvent(), startMapEvent(), scalarEvent("a"), + startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(), + startSeqEvent(), scalarEvent("d"), scalarEvent("e"), endSeqEvent(), + scalarEvent("f"), endMapEvent(), endDocEvent()) test "Parsing: Flow Sequence in Map": - ensure("a: [b, c]", startDoc(), startMap(), scalar("a"), - startSequence(), scalar("b"), scalar("c"), endSequence(), - endMap(), endDoc()) + ensure("a: [b, c]", startDocEvent(), startMapEvent(), scalarEvent("a"), + startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(), + endMapEvent(), endDocEvent()) test "Parsing: Flow Map in Sequence": - ensure("- {a: b}", startDoc(), startSequence(), startMap(), scalar("a"), - scalar("b"), endMap(), endSequence(), endDoc()) + ensure("- {a: b}", startDocEvent(), startSeqEvent(), startMapEvent(), scalarEvent("a"), + scalarEvent("b"), endMapEvent(), endSeqEvent(), endDocEvent()) test "Parsing: Multiline scalar (top level)": - ensure("a\nb \n c\nd", startDoc(), scalar("a b c d"), endDoc()) + ensure("a\nb \n c\nd", startDocEvent(), scalarEvent("a b c d"), endDocEvent()) test "Parsing: Multiline scalar (in map)": - ensure("a: b\n c\nd:\n e\n f", startDoc(), startMap(), scalar("a"), - scalar("b c"), scalar("d"), scalar("e f"), endMap(), endDoc()) + ensure("a: b\n c\nd:\n e\n f", startDocEvent(), startMapEvent(), scalarEvent("a"), + scalarEvent("b c"), scalarEvent("d"), scalarEvent("e f"), endMapEvent(), endDocEvent()) test "Parsing: Block scalar (literal)": - ensure("a: |\x0A ab\x0A \x0A cd\x0A ef\x0A \x0A", startDoc(), - startMap(), scalar("a"), scalar("ab\x0A\x0Acd\x0Aef\x0A"), - endMap(), endDoc()) + ensure("a: |\x0A ab\x0A \x0A cd\x0A ef\x0A \x0A", startDocEvent(), + startMapEvent(), scalarEvent("a"), scalarEvent("ab\x0A\x0Acd\x0Aef\x0A", yTagExclamationmark), + endMapEvent(), endDocEvent()) test "Parsing: Block scalar (folded)": - ensure("a: >\x0A ab\x0A cd\x0A \x0Aef\x0A\x0A\x0Agh\x0A", startDoc(), - startMap(), scalar("a"), scalar("ab cd\x0Aef\x0Agh\x0A"), - endMap(), endDoc()) + ensure("a: >\x0A ab\x0A cd\x0A \x0A ef\x0A\x0A\x0A gh\x0A", startDocEvent(), + startMapEvent(), scalarEvent("a"), scalarEvent("ab cd\x0Aef\x0A\x0Agh\x0A", yTagExclamationmark), + endMapEvent(), endDocEvent()) test "Parsing: Block scalar (keep)": - ensure("a: |+\x0A ab\x0A \x0A \x0A", startDoc(), startMap(), - scalar("a"), scalar("ab\x0A\x0A \x0A"), endMap(), endDoc()) + ensure("a: |+\x0A ab\x0A \x0A \x0A", startDocEvent(), startMapEvent(), + scalarEvent("a"), scalarEvent("ab\x0A\x0A \x0A", yTagExclamationmark), endMapEvent(), endDocEvent()) test "Parsing: Block scalar (strip)": - ensure("a: |-\x0A ab\x0A \x0A \x0A", startDoc(), startMap(), - scalar("a"), scalar("ab"), endMap(), endDoc()) + ensure("a: |-\x0A ab\x0A \x0A \x0A", startDocEvent(), startMapEvent(), + scalarEvent("a"), scalarEvent("ab", yTagExclamationmark), endMapEvent(), endDocEvent()) test "Parsing: non-specific tags of quoted strings": - ensure("\"a\"", startDoc(), - scalar("a", yTagExclamationMark), endDoc()) + ensure("\"a\"", startDocEvent(), + scalarEvent("a", yTagExclamationMark), endDocEvent()) test "Parsing: explicit non-specific tag": - ensure("! a", startDoc(), scalar("a", yTagExclamationMark), endDoc()) + ensure("! a", startDocEvent(), scalarEvent("a", yTagExclamationMark), endDocEvent()) test "Parsing: secondary tag handle resolution": - ensure("!!str a", startDoc(), scalar("a", yTagString), endDoc()) + ensure("!!str a", startDocEvent(), scalarEvent("a", yTagString), endDocEvent()) test "Parsing: resolving custom tag handles": let fooId = tagLib.registerUri("tag:example.com,2015:foo") - ensure("%TAG !t! tag:example.com,2015:\n---\n!t!foo a", startDoc(), - scalar("a", fooId), endDoc()) + ensure("%TAG !t! tag:example.com,2015:\n---\n!t!foo a", startDocEvent(), + scalarEvent("a", fooId), endDocEvent()) test "Parsing: tags in sequence": - ensure(" - !!str a\n - b\n - !!int c\n - d", startDoc(), - startSequence(), scalar("a", yTagString), scalar("b"), - scalar("c", yTagInteger), scalar("d"), endSequence(), endDoc()) + ensure(" - !!str a\n - b\n - !!int c\n - d", startDocEvent(), + startSeqEvent(), scalarEvent("a", yTagString), scalarEvent("b"), + scalarEvent("c", yTagInteger), scalarEvent("d"), endSeqEvent(), endDocEvent()) test "Parsing: tags in implicit map": - ensure("!!str a: b\nc: !!int d\ne: !!str f\ng: h", startDoc(), startMap(), - scalar("a", yTagString), scalar("b"), scalar("c"), - scalar("d", yTagInteger), scalar("e"), scalar("f", yTagString), - scalar("g"), scalar("h"), endMap(), endDoc()) + ensure("!!str a: b\nc: !!int d\ne: !!str f\ng: h", startDocEvent(), startMapEvent(), + scalarEvent("a", yTagString), scalarEvent("b"), scalarEvent("c"), + scalarEvent("d", yTagInteger), scalarEvent("e"), scalarEvent("f", yTagString), + scalarEvent("g"), scalarEvent("h"), endMapEvent(), endDocEvent()) test "Parsing: tags in explicit map": - ensure("? !!str a\n: !!int b\n? c\n: !!str d", startDoc(), startMap(), - scalar("a", yTagString), scalar("b", yTagInteger), scalar("c"), - scalar("d", yTagString), endMap(), endDoc()) + ensure("? !!str a\n: !!int b\n? c\n: !!str d", startDocEvent(), startMapEvent(), + scalarEvent("a", yTagString), scalarEvent("b", yTagInteger), scalarEvent("c"), + scalarEvent("d", yTagString), endMapEvent(), endDocEvent()) test "Parsing: tags for block objects": ensure("--- !!map\nfoo: !!seq\n - a\n - !!str b\n!!str bar: !!str baz", - startDoc(), startMap(yTagMap), scalar("foo"), - startSequence(yTagSequence), scalar("a"), scalar("b", yTagString), - endSequence(), scalar("bar", yTagString), - scalar("baz", yTagString), endMap(), endDoc()) + startDocEvent(), startMapEvent(yTagMap), scalarEvent("foo"), + startSeqEvent(yTagSequence), scalarEvent("a"), scalarEvent("b", yTagString), + endSeqEvent(), scalarEvent("bar", yTagString), + scalarEvent("baz", yTagString), endMapEvent(), endDocEvent()) test "Parsing: root tag for block sequence": - ensure("--- !!seq\n- a", startDoc(), startSequence(yTagSequence), - scalar("a"), endSequence(), endDoc()) + ensure("--- !!seq\n- a", startDocEvent(), startSeqEvent(yTagSequence), + scalarEvent("a"), endSeqEvent(), endDocEvent()) test "Parsing: root tag for explicit block map": - ensure("--- !!map\n? a\n: b", startDoc(), startMap(yTagMap), - scalar("a"), scalar("b"), endMap(), endDoc()) + ensure("--- !!map\n? a\n: b", startDocEvent(), startMapEvent(yTagMap), + scalarEvent("a"), scalarEvent("b"), endMapEvent(), endDocEvent()) test "Parsing: tags for flow objects": - ensure("!!map { k: !!seq [ a, !!str b] }", startDoc(), startMap(yTagMap), - scalar("k"), startSequence(yTagSequence), scalar("a"), - scalar("b", yTagString), endSequence(), endMap(), endDoc()) + ensure("!!map { k: !!seq [ a, !!str b] }", startDocEvent(), startMapEvent(yTagMap), + scalarEvent("k"), startSeqEvent(yTagSequence), scalarEvent("a"), + scalarEvent("b", yTagString), endSeqEvent(), endMapEvent(), endDocEvent()) test "Parsing: Tag after directives end": - ensure("--- !!str\nfoo", startDoc(), scalar("foo", yTagString), endDoc()) + ensure("--- !!str\nfoo", startDocEvent(), scalarEvent("foo", yTagString), endDocEvent()) test "Parsing: Simple Anchor": - ensure("&a str", startDoc(), scalar("str", yTagQuestionMark, - 0.AnchorId), endDoc()) + ensure("&a str", startDocEvent(), scalarEvent("str", yTagQuestionMark, + 0.AnchorId), endDocEvent()) test "Parsing: Anchors in sequence": - ensure(" - &a a\n - b\n - &c c\n - &a d", startDoc(), startSequence(), - scalar("a", yTagQuestionMark, 0.AnchorId), scalar("b"), - scalar("c", yTagQuestionMark, 1.AnchorId), - scalar("d", yTagQuestionMark, 0.AnchorId), endSequence(), - endDoc()) + ensure(" - &a a\n - b\n - &c c\n - &a d", startDocEvent(), startSeqEvent(), + scalarEvent("a", yTagQuestionMark, 0.AnchorId), scalarEvent("b"), + scalarEvent("c", yTagQuestionMark, 1.AnchorId), + scalarEvent("d", yTagQuestionMark, 2.AnchorId), endSeqEvent(), + endDocEvent()) test "Parsing: Anchors in map": - ensure("&a a: b\nc: &d d", startDoc(), startMap(), - scalar("a", yTagQuestionMark, 0.AnchorId), - scalar("b"), scalar("c"), - scalar("d", yTagQuestionMark, 1.AnchorId), - endMap(), endDoc()) + ensure("&a a: b\nc: &d d", startDocEvent(), startMapEvent(), + scalarEvent("a", yTagQuestionMark, 0.AnchorId), + scalarEvent("b"), scalarEvent("c"), + scalarEvent("d", yTagQuestionMark, 1.AnchorId), + endMapEvent(), endDocEvent()) test "Parsing: Anchors and tags": - ensure(" - &a !!str a\n - !!int b\n - &c !!int c\n - &d d", startDoc(), - startSequence(), scalar("a", yTagString, 0.AnchorId), - scalar("b", yTagInteger), scalar("c", yTagInteger, 1.AnchorId), - scalar("d", yTagQuestionMark, 2.AnchorId), endSequence(), - endDoc()) + ensure(" - &a !!str a\n - !!int b\n - &c !!int c\n - &d d", startDocEvent(), + startSeqEvent(), scalarEvent("a", yTagString, 0.AnchorId), + scalarEvent("b", yTagInteger), scalarEvent("c", yTagInteger, 1.AnchorId), + scalarEvent("d", yTagQuestionMark, 2.AnchorId), endSeqEvent(), + endDocEvent()) test "Parsing: Aliases in sequence": - ensure(" - &a a\n - &b b\n - *a\n - *b", startDoc(), startSequence(), - scalar("a", yTagQuestionMark, 0.AnchorId), - scalar("b", yTagQuestionMark, 1.AnchorId), alias(0.AnchorId), - alias(1.AnchorId), endSequence(), endDoc()) + ensure(" - &a a\n - &b b\n - *a\n - *b", startDocEvent(), startSeqEvent(), + scalarEvent("a", yTagQuestionMark, 0.AnchorId), + scalarEvent("b", yTagQuestionMark, 1.AnchorId), aliasEvent(0.AnchorId), + aliasEvent(1.AnchorId), endSeqEvent(), endDocEvent()) test "Parsing: Aliases in map": - ensure("&a a: &b b\n*a: *b", startDoc(), startMap(), - scalar("a", yTagQuestionMark, 0.AnchorId), - scalar("b", yTagQuestionMark, 1.AnchorId), alias(0.AnchorId), - alias(1.AnchorId), endMap(), endDoc()) + ensure("&a a: &b b\n*a : *b", startDocEvent(), startMapEvent(), + scalarEvent("a", yTagQuestionMark, 0.AnchorId), + scalarEvent("b", yTagQuestionMark, 1.AnchorId), aliasEvent(0.AnchorId), + aliasEvent(1.AnchorId), endMapEvent(), endDocEvent()) test "Parsing: Aliases in flow": - ensure("{ &a [a, &b b]: *b, *a: [c, *b, d]}", startDoc(), startMap(), - startSequence(yTagQuestionMark, 0.AnchorId), scalar("a"), - scalar("b", yTagQuestionMark, 1.AnchorId), endSequence(), - alias(1.AnchorId), alias(0.AnchorId), startSequence(), - scalar("c"), alias(1.AnchorId), scalar("d"), endSequence(), - endMap(), endDoc()) + ensure("{ &a [a, &b b]: *b, *a : [c, *b, d]}", startDocEvent(), startMapEvent(), + startSeqEvent(yTagQuestionMark, 0.AnchorId), scalarEvent("a"), + scalarEvent("b", yTagQuestionMark, 1.AnchorId), endSeqEvent(), + aliasEvent(1.AnchorId), aliasEvent(0.AnchorId), startSeqEvent(), + scalarEvent("c"), aliasEvent(1.AnchorId), scalarEvent("d"), endSeqEvent(), + endMapEvent(), endDocEvent()) test "Parsing: Tags on empty scalars": - ensure("!!str : a\nb: !!int\n!!str : !!str", startDoc(), startMap(), - scalar("", yTagString), scalar("a"), scalar("b"), - scalar("", yTagInteger), scalar("", yTagString), - scalar("", yTagString), endMap(), endDoc()) + ensure("!!str : a\nb: !!int\n!!str : !!str", startDocEvent(), startMapEvent(), + scalarEvent("", yTagString), scalarEvent("a"), scalarEvent("b"), + scalarEvent("", yTagInteger), scalarEvent("", yTagString), + scalarEvent("", yTagString), endMapEvent(), endDocEvent()) test "Parsing: Anchors on empty scalars": - ensure("&a : a\nb: &b\n&c : &a", startDoc(), startMap(), - scalar("", yTagQuestionMark, 0.AnchorId), scalar("a"), - scalar("b"), scalar("", yTagQuestionMark, 1.AnchorId), - scalar("", yTagQuestionMark, 2.AnchorId), - scalar("", yTagQuestionMark, 0.AnchorId), endMap(), endDoc()) \ No newline at end of file + ensure("&a : a\nb: &b\n&c : &a", startDocEvent(), startMapEvent(), + scalarEvent("", yTagQuestionMark, 0.AnchorId), scalarEvent("a"), + scalarEvent("b"), scalarEvent("", yTagQuestionMark, 1.AnchorId), + scalarEvent("", yTagQuestionMark, 2.AnchorId), + scalarEvent("", yTagQuestionMark, 3.AnchorId), endMapEvent(), endDocEvent()) \ No newline at end of file