fix(parsing): bound a block sequence to its own column for siblings
A compact nested block sequence (`- - x`) carries no indent or dedent tokens, only block entries at their source columns. The sibling-entry loop in parseBlockSequence collected every following block entry by kind alone, so the inner sequence absorbed an entry that belonged to an enclosing one: `- - x` then `- - y` parsed as a single outer item `[[x, [y]]]` instead of two items `[[x], [y]]`. Record the first entry's column as the sequence's column and continue the sibling loop only while the next entry sits at it. An entry at a smaller column ends this sequence and is handled by the enclosing one; entries at the same column still group, and flat sequences are unchanged. Raises yaml-test-suite value-level conformance to 190/194 (97.9%) with the parse-level and should-error rejection rates unchanged. 460 tests pass.
This commit is contained in:
parent
2b3d95d214
commit
a33be7c37a
@ -84,6 +84,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compact nested block sequences (`- - x`) now separate their outer items correctly. Such a sequence
|
||||
carries no indent/dedent tokens, only block entries at their columns, but the sibling-entry loop
|
||||
collected every following block entry regardless of column, so `- - x` then `- - y` became one
|
||||
outer item holding both rather than two. A sequence now collects siblings only at its own column, so
|
||||
an entry at a smaller column ends it and belongs to the enclosing sequence. Raises yaml-test-suite
|
||||
value-level conformance to 190/194 (97.9%), with the parse and should-error rates unchanged.
|
||||
|
||||
- A block scalar whose only lines are blank now carries those blank lines through chomping at stream
|
||||
end. Such a scalar never establishes a content indentation, so its blank lines stayed buffered and
|
||||
were dropped, making `keep: |+` over a blank line resolve to the empty string instead of a line
|
||||
|
||||
@ -5,6 +5,10 @@ extension PureYAML.Parsing.TokenEventParser {
|
||||
) throws -> PureYAML.Parsing.NodeResult {
|
||||
let start = try expect("block sequence entry") { $0.isBlockEntry }
|
||||
try enforceBlockSequenceNotInlineAfterProperty(properties, firstEntry: start)
|
||||
// A compact nested sequence (`- - x`) carries no indent/dedent tokens, only block entries at
|
||||
// their columns, so the sibling-entry loop must stay at this sequence's own column: a later
|
||||
// entry at a smaller column belongs to an enclosing sequence and ends this one.
|
||||
let sequenceColumn = start.mark.column
|
||||
let startMark = properties.mark ?? start.mark
|
||||
var endMark = start.endMark
|
||||
try emit(.sequenceStart(
|
||||
@ -21,7 +25,7 @@ extension PureYAML.Parsing.TokenEventParser {
|
||||
)
|
||||
try consumeSequenceItemBoundaryDedent(sequenceIndentWidth: start.mark.column - 1)
|
||||
try consumeSequenceItemBoundaryIndent(sequenceIndentWidth: start.mark.column - 1)
|
||||
while cursor.current?.kind.isBlockEntry == true {
|
||||
while cursor.current?.kind.isBlockEntry == true, cursor.current?.mark.column == sequenceColumn {
|
||||
let entry = try expect("block sequence entry") { $0.isBlockEntry }
|
||||
try parseBlockSequenceItem(
|
||||
after: entry,
|
||||
|
||||
37
Tests/CompactNestedSequenceTests.swift
Normal file
37
Tests/CompactNestedSequenceTests.swift
Normal file
@ -0,0 +1,37 @@
|
||||
@testable import PureYAML
|
||||
import Testing
|
||||
|
||||
/// A compact nested block sequence (`- - x`) carries no indent/dedent tokens, only block entries at
|
||||
/// their columns. A sequence collects sibling items only at its own column, so a later entry at a
|
||||
/// smaller column ends it and belongs to the enclosing sequence: `- - x` then `- - y` is `[[x], [y]]`,
|
||||
/// two outer items, not one outer item holding both.
|
||||
@Suite("Compact nested sequence")
|
||||
struct CompactNestedSequenceTests {
|
||||
@Test("Two compact nested entries are two outer items")
|
||||
func test_twoNestedItems() throws {
|
||||
#expect(try PureYAML.parse("- - x\n- - y\n") == .sequence([
|
||||
.sequence([.string("x")]),
|
||||
.sequence([.string("y")]),
|
||||
]))
|
||||
}
|
||||
|
||||
@Test("Three levels of compact nesting separate at the outer column")
|
||||
func test_threeLevels() throws {
|
||||
#expect(try PureYAML.parse("- - - []\n- - - {}\n") == .sequence([
|
||||
.sequence([.sequence([.sequence([])])]),
|
||||
.sequence([.sequence([.mapping(.init([]))])]),
|
||||
]))
|
||||
}
|
||||
|
||||
@Test("Entries at the same column stay one sequence")
|
||||
func test_sameColumnSiblings() throws {
|
||||
#expect(try PureYAML.parse("- - a\n - b\n") == .sequence([
|
||||
.sequence([.string("a"), .string("b")]),
|
||||
]))
|
||||
}
|
||||
|
||||
@Test("A flat sequence is unchanged")
|
||||
func test_flatSequence() throws {
|
||||
#expect(try PureYAML.parse("- a\n- b\n") == .sequence([.string("a"), .string("b")]))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user