YamlReference 0.2 → 0.3
raw patch · 149 files changed
+540/−511 lines, 149 files
Files
- Text/Yaml/Reference.hs +318/−331
- YamlReference.cabal +4/−7
- tests/c-b+block-header.n=2.s=folded.i.output +1/−1
- tests/c-b+block-header.n=2.s=folded.im.output +1/−1
- tests/c-b+block-header.n=2.s=folded.imt.output +1/−1
- tests/c-b+block-header.n=2.s=folded.it.output +1/−1
- tests/c-b+block-header.n=2.s=folded.itm.output +1/−1
- tests/c-double-quoted.n=4.c=flow-out.invalid.output +1/−1
- tests/c-double-quoted.n=4.c=flow-out.output +1/−1
- tests/c-flow-json-content.n=4.c=flow-in.double.output +1/−1
- tests/c-flow-json-content.n=4.c=flow-in.mapping.output +2/−1
- tests/c-flow-json-content.n=4.c=flow-in.sequence.output +1/−1
- tests/c-flow-json-node.n=4.c=flow-in.tagged.output +1/−1
- tests/c-flow-json-node.n=4.c=flow-in.untagged.output +1/−1
- tests/c-flow-mapping.n=4.c=flow-in.compact.output +3/−1
- tests/c-flow-mapping.n=4.c=flow-in.invalid.output +1/−1
- tests/c-flow-mapping.n=4.c=flow-in.spaced.output +3/−1
- tests/c-flow-sequence.n=4.c=flow-in.compact.output +2/−1
- tests/c-flow-sequence.n=4.c=flow-in.invalid.output +1/−1
- tests/c-flow-sequence.n=4.c=flow-in.spaced.output +2/−1
- tests/c-l+folded.n=2.indent.output +1/−1
- tests/c-l+folded.n=2.invalid.output +1/−1
- tests/c-l+folded.n=2.simple.output +1/−1
- tests/c-l+literal.n=2.invalid.output +1/−1
- tests/c-l+literal.n=2.simple.output +1/−1
- tests/c-l+literal.n=2.strip-indent.output +1/−1
- tests/c-l+literal.n=2.strip.output +1/−1
- tests/c-l-block-map-explicit-entry.n=2.output +3/−1
- tests/c-l-block-map-explicit-key.n=2.output +2/−1
- tests/c-l-block-map-implicit-value.n=2.empty.output +1/−1
- tests/c-l-block-map-implicit-value.n=2.invalid.output +1/−1
- tests/c-l-block-map-implicit-value.n=2.plain.output +2/−1
- tests/c-l-block-seq-entry.n=2.output +2/−1
- tests/c-ns-alias.output +1/−1
- tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.compact.output +2/−2
- tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.empty.output +1/−1
- tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.spaced.output +2/−2
- tests/c-ns-flow-map-implicit-json.n=4.c=flow-in.compact.output +2/−2
- tests/c-ns-flow-map-implicit-json.n=4.c=flow-in.spaced.output +2/−2
- tests/c-ns-flow-map-separate-value.n=4.c=flow-in.empty.output +1/−1
- tests/c-ns-flow-map-separate-value.n=4.c=flow-in.invalid.output +1/−1
- tests/c-ns-flow-map-separate-value.n=4.c=flow-in.value.output +2/−2
- tests/c-ns-flow-map-single-json.n=4.c=flow-in.output +2/−2
- tests/c-quoted-quote.output +1/−1
- tests/debug-leak.input +0/−1
- tests/debug-leak.output +0/−2
- tests/l+block-mapping.n=1.output +5/−1
- tests/l+block-sequence.n=1.output +6/−1
- tests/l-block-map-explicit-value.n=2.output +1/−1
- tests/l-explicit-document.invalid.output +1/−1
- tests/l-explicit-document.literal.output +1/−1
- tests/l-explicit-document.plain.output +2/−1
- tests/l-implicit-document.invalid.output +1/−1
- tests/l-implicit-document.literal.output +1/−1
- tests/l-implicit-document.plain.output +1/−1
- tests/l-nb-folded-lines.n=4.invalid.output +1/−1
- tests/l-nb-folded-lines.n=4.output +3/−1
- tests/l-nb-spaced-lines.n=4.output +3/−1
- tests/l-nb-start-with-folded.n=4.output +3/−1
- tests/l-nb-start-with-spaced.n=4.output +3/−1
- tests/ns-esc-16-bit.output +1/−1
- tests/ns-esc-32-bit.output +1/−1
- tests/ns-esc-8-bit.output +1/−1
- tests/ns-esc-char.16-bit.output +1/−1
- tests/ns-esc-char.32-bit.output +1/−1
- tests/ns-esc-char.8-bit.output +1/−1
- tests/ns-esc-char.backslash.output +1/−1
- tests/ns-esc-char.bell.output +1/−1
- tests/ns-esc-char.bs.output +1/−1
- tests/ns-esc-char.cr.output +1/−1
- tests/ns-esc-char.double-quote.output +1/−1
- tests/ns-esc-char.esc.output +1/−1
- tests/ns-esc-char.ff.output +1/−1
- tests/ns-esc-char.lf.output +1/−1
- tests/ns-esc-char.ls.output +1/−1
- tests/ns-esc-char.nbsp.output +1/−1
- tests/ns-esc-char.nl.output +1/−1
- tests/ns-esc-char.null.output +1/−1
- tests/ns-esc-char.ps.output +1/−1
- tests/ns-esc-char.sp.output +1/−1
- tests/ns-esc-char.tab.output +1/−1
- tests/ns-esc-char.vt.output +1/−1
- tests/ns-flow-content.n=4.c=flow-in.json.output +1/−1
- tests/ns-flow-content.n=4.c=flow-in.yaml.output +1/−1
- tests/ns-flow-map-entry.n=4.c=flow-in.explicit.output +1/−1
- tests/ns-flow-map-implicit-empty.n=4.c=flow-in.invalid.output +1/−1
- tests/ns-flow-map-implicit-empty.n=4.c=flow-in.output +2/−2
- tests/ns-flow-map-implicit-entry.n=4.c=flow-in.empty.output +2/−2
- tests/ns-flow-map-implicit-entry.n=4.c=flow-in.json.output +2/−2
- tests/ns-flow-map-implicit-entry.n=4.c=flow-in.yaml.output +2/−2
- tests/ns-flow-map-implicit-yaml.n=4.c=flow-in.compact.output +2/−2
- tests/ns-flow-map-implicit-yaml.n=4.c=flow-in.spaced.output +2/−2
- tests/ns-flow-map-single-entry.n=4.c=flow-in.empty.output +2/−2
- tests/ns-flow-map-single-entry.n=4.c=flow-in.json.output +2/−2
- tests/ns-flow-map-single-entry.n=4.c=flow-in.yaml.output +2/−2
- tests/ns-flow-map-single-pair.n=4.c=flow-in.explicit.output +3/−2
- tests/ns-flow-map-single-pair.n=4.c=flow-in.implicit.output +2/−2
- tests/ns-flow-map-single-yaml.n=4.c=flow-in.output +2/−2
- tests/ns-flow-node.n=4.c=flow-in.alias.output +1/−1
- tests/ns-flow-node.n=4.c=flow-in.tagged.output +1/−1
- tests/ns-flow-node.n=4.c=flow-in.untagged.output +1/−1
- tests/ns-flow-seq-entry.n=4.c=flow-in.pair.output +1/−1
- tests/ns-flow-yaml-content.n=4.c=flow-in.output +1/−1
- tests/ns-flow-yaml-node.n=4.c=flow-in.alias.output +1/−1
- tests/ns-flow-yaml-node.n=4.c=flow-in.tagged.output +1/−1
- tests/ns-flow-yaml-node.n=4.c=flow-in.untagged.output +1/−1
- tests/ns-l-block-map-entry.n=2.explicit.output +3/−1
- tests/ns-l-block-map-entry.n=2.implicit.output +2/−1
- tests/ns-l-block-map-implicit-entry.n=2.empty.output +1/−1
- tests/ns-l-block-map-implicit-entry.n=2.non-empty.output +2/−1
- tests/ns-l-in-line-mapping.n=2.output +4/−1
- tests/ns-l-in-line-sequence.n=3.invalid.output +2/−1
- tests/ns-l-in-line-sequence.n=3.output +4/−1
- tests/ns-plain-multi.n=4.c=flow-in.invalid.output +1/−1
- tests/ns-plain-multi.n=4.c=flow-in.output +1/−1
- tests/ns-plain-single.c=flow-key.invalid.output +1/−1
- tests/ns-plain-single.c=flow-out.output +1/−1
- tests/ns-plain.n=4.c=flow-in.output +1/−1
- tests/ns-plain.n=4.c=flow-key.invalid.output +1/−1
- tests/ns-plain.n=4.c=flow-key.output +1/−1
- tests/ns-s-flow-map-entries.n=4.c=flow-in.multi.output +1/−1
- tests/ns-s-flow-map-entries.n=4.c=flow-in.single.output +1/−1
- tests/ns-s-flow-seq-entries.n=4.c=flow-in.multi.output +1/−1
- tests/ns-tag-directive.invalid.output +1/−1
- tests/ns-tag-directive.output +1/−1
- tests/ns-yaml-directive.invalid.output +1/−1
- tests/ns-yaml-directive.output +1/−1
- tests/s-b-double-escaped.output +1/−1
- tests/s-l+block-content.n=2.c=block-in.sequence.output +2/−1
- tests/s-l+block-content.n=2.c=block-out.folded.output +1/−1
- tests/s-l+block-content.n=2.c=block-out.literal.output +1/−1
- tests/s-l+block-content.n=2.c=block-out.mapping.output +2/−1
- tests/s-l+block-in-block.n=2.c=block-out.tagged.output +1/−1
- tests/s-l+block-in-block.n=2.c=block-out.untagged.output +1/−1
- tests/s-l+block-indented.n=2.c=block-in.sequence.output +2/−1
- tests/s-l+block-indented.n=2.c=block-out.literal.output +1/−1
- tests/s-l+block-indented.n=2.c=block-out.sequence.output +2/−1
- tests/s-l+block-node.n=2.c=block-out.block.output +1/−1
- tests/s-l+block-node.n=2.c=block-out.flow.output +1/−1
- tests/s-l+flow-in-block.n=2.output +1/−1
- tests/s-nb-folded-text.n=4.output +1/−1
- tests/s-nb-spaced-text.n=4.output +1/−1
- tests/s-ns-flow-map-explicit-empty.n=4.c=flow-in.output +2/−2
- tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.json.output +2/−2
- tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.value.output +2/−2
- tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.yaml.output +2/−2
- tests/s-ns-flow-map-explicit-json.n=4.c=flow-in.output +3/−3
- tests/s-ns-flow-map-explicit-yaml.n=4.c=flow-in.output +3/−3
- yaml2yeast/Main.hs +2/−0
Text/Yaml/Reference.hs view
@@ -14,9 +14,8 @@ -- the actual productions from @Reference.bnf@. -- -- The parsing framework is fully streaming (generates output tokens--- \"immediately\"), but has a memory leak (actually retention) which causes it--- to blow up on \"large\" files. To debug this with minimal syntax productions--- use the @debug_leak@ production (@yes "#" | yaml2yeast -p debug-leak@).+-- \"immediately\"). The memory leak that existed in previous version has been+-- plugged. ------------------------------------------------------------------------------- module Text.Yaml.Reference@@ -53,11 +52,6 @@ import qualified Prelude import Prelude hiding ((/), (*), (+), (-), (^)) --- * DeepSeq------ Without this, memory consumption goes to infinity. This is a subset of Dean--- Herington's code.- -- * Generic operators -- -- ** Numeric operators@@ -420,8 +414,8 @@ -- building a parse tree, and completing all of it before any of it is -- accessible to the caller. We return a stream of tokens, and would like -- its head to be accessible as soon as possible to allow for streaming. To--- do this we use a difference list (not a 'DList' - we use a \"real\"--- difference list building on Haskell's lazy evaluation nature).+-- do this with bounded memory usage we use a combination of continuation+-- passing style and difference lists for the collected tokens. -- -- * Haskell makes it so easy to roll your own parsing framework. We need some -- specialized machinery (limited lookahead, forbidden patterns). It is@@ -435,23 +429,34 @@ -- | A 'Parser' is basically a function computing a 'Reply'. data Parser result = Parser (State -> Reply result) --- | A 'Reply' from a 'Parser'.+-- | The 'Result' of each invocation is either an error, the actual result, or+-- a continuation for computing the actual result.+data Result result = Failed String -- ^ Parsing aborted with a failure.+ | Result result -- ^ Parsing completed with a result.+ | More (Parser result) -- ^ Parsing is ongoing with a continuation.++-- Showing a 'Result' is only used in debugging.+instance (Show result) => Show (Result result) where+ show result = case result of+ Failed message -> "Failed " ++ message+ Result result -> "Result " ++ (show result)+ More _ -> "More"++-- | Each invication of a 'Parser' yields a 'Reply'. The 'Result' is only one+-- part of the 'Reply'. data Reply result = Reply {- rResult :: Either String result, -- ^ Error or parsing result.- rState :: State, -- ^ The updated parser state.- rTokens :: D.DList Token, -- ^ Tokens generated by the parser.- rCommits :: D.DList String, -- ^ Commitments to decision points.- rDidConsume :: Bool -- ^ Whether any characters were consumed.+ rResult :: !(Result result), -- ^ Parsing result.+ rTokens :: !(D.DList Token), -- ^ Tokens generated by the parser.+ rCommit :: !(Maybe String), -- ^ Commitment to a decision point.+ rState :: !State -- ^ The updated parser state. } --- Showing a 'State' is only used in debugging. Note that forcing dump of--- @rTokens@, @rCommits@ or even @rDidConsume@ will prevent streaming them.-instance Show (Reply result) where- show reply = -- "Result: " ++ (show $ reply|>rResult)- "State: { " ++ (show $ reply|>rState) ++ "}"- ++ ", Tokens: " ++ (show $ D.toList $ reply|>rTokens)- ++ ", Commits: " ++ (show $ D.toList $ reply|>rCommits)- ++ ", DidConsume: " ++ (show $ reply|>rDidConsume)+-- Showing a 'State' is only used in debugging.+instance (Show result) => Show (Reply result) where+ show reply = "Result: " ++ (show $ reply|>rResult)+ ++ ", Tokens: " ++ (show $ D.toList $ reply|>rTokens)+ ++ ", Commit: " ++ (show $ reply|>rCommit)+ ++ ", State: { " ++ (show $ reply|>rState) ++ "}" -- A 'Pattern' is a parser that doesn't have an (interesting) result. type Pattern = Parser ()@@ -469,52 +474,52 @@ sForbidden :: !(Maybe Pattern), -- ^ Pattern we must not enter into. sIsPeek :: !Bool, -- ^ Disables token generation. sChars :: ![Char], -- ^ (Reversed) characters collected for a token.+ sOffset :: !Int, -- ^ Offset in characters in the input. sLine :: !Int, -- ^ Builds on YAML's line break definition. sColumn :: !Int, -- ^ Actually character number - we hate tabs. sCode :: !Code, -- ^ Of token we are collecting chars for. sLast :: !Char, -- ^ Last matched character.- sInput :: [Char] -- ^ The input decoded characters.+ sInput :: ![Char] -- ^ The decoded input characters. } -- Showing a 'State' is only used in debugging. Note that forcing dump of--- @sInput@ will disable streamin it.+-- @sInput@ will disable streaming it. instance Show State where- show state = "Name: " ++ (show $ state|>sName)+ show state = "Name: " ++ (show $ state|>sName) ++ ", Encoding: " ++ (show $ state|>sEncoding) ++ ", Decision: " ++ (show $ state|>sDecision)- ++ ", Limit: " ++ (show $ state|>sLimit)- ++ ", IsPeek: " ++ (show $ state|>sIsPeek)+ ++ ", Limit: " ++ (show $ state|>sLimit)+ ++ ", IsPeek: " ++ (show $ state|>sIsPeek) ++ ", Chars: >>>" ++ (reverse $ state|>sChars) ++ "<<<"- ++ ", Line: " ++ (show $ state|>sLine)- ++ ", Column: " ++ (show $ state|>sColumn)- ++ ", Code: " ++ (show $ state|>sCode)- ++ ", Last: >>>" ++ (show $ state|>sLast) ++ "<<<"+ ++ ", Offset: " ++ (show $ state|>sOffset)+ ++ ", Line: " ++ (show $ state|>sLine)+ ++ ", Column: " ++ (show $ state|>sColumn)+ ++ ", Code: " ++ (show $ state|>sCode)+ ++ ", Last: " ++ (show $ state|>sLast) -- ++ ", Input: >>>" ++ (show $ state|>sInput) ++ "<<<" -- | @initialState name input@ returns an initial 'State' for parsing the -- /input/ (with /name/ for error messages). initialState :: String -> C.ByteString -> State initialState name input = let (encoding, decoded) = decode input- in State { sName = name,- sEncoding = encoding,- sDecision = "n/a",- sLimit = -1,- sForbidden = Nothing,- sIsPeek = False,- sChars = [],- sLine = 1,- sColumn = 0,- sCode = Test,- sLast = ' ',- sInput = decoded }+ in State { sName = name,+ sEncoding = encoding,+ sDecision = "",+ sLimit = -1,+ sForbidden = Nothing,+ sIsPeek = False,+ sChars = [],+ sOffset = 0,+ sLine = 1,+ sColumn = 0,+ sCode = Test,+ sLast = ' ',+ sInput = decoded } -- *** Setters ----- We need setter functions instead of using @{ sXxx = value }@ because the--- nice syntax causes the old state to be fully evaluated, killing the--- streaming (lazy) functionality we need. Generating the setters by hand was--- tedious, there's surely a way to do this using Template Haskell or DrIFT or--- some such. Life is too short.+-- We need four setter functions to pass them around as arguments. For some+-- reason, Haskell only generates getter functions. -- | @setDecision name state@ sets the @sDecision@ field to /decision/. setDecision :: String -> State -> State@@ -543,12 +548,6 @@ class Match parameter result | parameter -> result where match :: parameter -> Parser result --- | @parse parser state@ applies the actual /parser/ match function to a--- /state/.-parse :: (Match match result) => match -> State -> Reply result-parse parser state = let Parser parser' = match parser- in parser' state- -- | We don't need to convert a 'Parser', it already is one. instance Match (Parser result) result where match = id@@ -567,104 +566,94 @@ instance Match String () where match = foldr (&) empty +-- ** Reply constructors++-- | @returnReply state result@ prepares a 'Reply' with the specified /state/+-- and /result/.+returnReply :: State -> result -> Reply result+returnReply state result = Reply { rResult = Result result,+ rTokens = D.empty,+ rCommit = Nothing,+ rState = state }++-- | @tokenReply state token@ returns a 'Reply' containing the /state/ and+-- /token/. Any collected characters are cleared (either there are none, or we+-- put them in this token, or we don't want them).+tokenReply state token = Reply { rResult = Result (),+ rTokens = D.singleton token,+ rCommit = Nothing,+ rState = state { sChars = [] } }++-- | @failReply state message@ prepares a 'Reply' with the specified /state/+-- and error /message/.+failReply :: State -> String -> Reply result+failReply state message = Reply { rResult = Failed $ state|>sName+ ++ ": line " ++ (show $ state|>sLine)+ ++ ": column " ++ (show $ state|>sColumn)+ ++ ": " ++ message,+ rTokens = D.empty,+ rCommit = Nothing,+ rState = state }++-- | @unexpectedReply state@ returns a @failReply@ for an unexpected character.+unexpectedReply :: State -> Reply result+unexpectedReply state = case state|>sInput of+ (char:_) -> failReply state $ "Unexpected '" ++ [char] ++ "'"+ [] -> failReply state "Unexpected end of input"+ -- ** Parsing Monad -- | Allow using the @do@ notation for our parsers, which makes for short and -- sweet @do@ syntax when we want to examine the results (we typically don't).------ We don't use the 'Monad' @fail@ method because we need access to the 'State'--- on failure. instance Monad Parser where - -- | @return result@ does just that - return a /result/.+ -- @return result@ does just that - return a /result/. return result = Parser $ \ state -> returnReply state result - -- | @left >>= right@ applies the /left/ parser, and if it didn't fail- -- applies the /right/ one (well, the one /right/ returns). For streaming it- -- is vital that we return a value "regardless" of the result of the left- -- parser. The fields in the reply are populated at different rates (in- -- particular, tokens are made available before the final result is known).- left >>= right =- Parser $ \ originalState -> let leftReply = parse left originalState- rightReply = case leftReply|>rResult of- Right value -> parse (right value) $ leftReply|>rState- Left message -> failReply (leftReply|>rState) message- in bindReply leftReply rightReply+ -- @left >>= right@ applies the /left/ parser, and if it didn't fail+ -- applies the /right/ one (well, the one /right/ returns).+ left >>= right = bindParser left right+ where bindParser (Parser left) right = Parser $ \ state ->+ let reply = left state+ in case reply|>rResult of+ Failed message -> reply { rResult = Failed message }+ Result value -> reply { rResult = More $ right value }+ More parser -> reply { rResult = More $ bindParser parser right } - -- | @fail message@ does just that - failes with a /message/.+ -- @fail message@ does just that - fails with a /message/. fail message = Parser $ \ state -> failReply state message --- | @returnReply state result@ prepares a 'Reply' with the specified /state/--- and /result/.-returnReply :: State -> result -> Reply result-returnReply state result = Reply { rResult = Right result,- rState = state,- rTokens = D.empty,- rCommits = D.empty,- rDidConsume = False }---- NOTE: The profiler is blaming @bindReply@ at retaining old state and--- reply objects. How come?---- | @bindReply left right@ combines the replies of the /left/ and /right/--- parsers to a single reply, allowing for generated 'Token' to be consumed--- before parsing is completed.-bindReply :: Reply result1 -> Reply result2 -> Reply result2-bindReply left right = Reply { rResult = right|>rResult,- rState = right|>rState,- rTokens = D.append (left|>rTokens) (right|>rTokens),- rCommits = D.append (left|>rCommits) (right|>rCommits),- rDidConsume = (left|>rDidConsume) || (right|>rDidConsume) }---- | @failReply state message@ prepares a 'Reply' with the specified /state/--- and error /message/.-failReply :: State -> String -> Reply result-failReply state message = Reply { rResult = Left $ state|>sName- ++ ": line " ++ (show $ state|>sLine)- ++ ": column " ++ (show $ state|>sColumn)- ++ ": " ++ message,- rState = state,- rTokens = D.empty,- rCommits = D.empty,- rDidConsume = False }- -- ** Parsing operators ----- Here we reap the benefits of renaming the numerical operators. Note that in--- our specific case, we use the 'MonadPlus' to combine the results of--- different parsers. Typically, parsing frameworks simply use the last result,--- or leave the task of combining them to the rules themselves (using @do@--- notation).------ Operator precedence, in decreasing strength:+-- Here we reap the benefits of renaming the numerical operators. The Operator+-- precedence, in decreasing strength: -- -- @repeated % n@, @repeated <% n@, @match - rejected@, @match ! decision@,--- @match ?! decision@ are the strongest binding, and don't mix.+-- @match ?! decision@, @choice ^ (first \/ second)@. -- -- @match - first - second@ is @(match - first) - second@. -- -- @first & second & third@ is @first & (second & third)@. Note that @first ---- rejected & second@ is @(first - rejected) & second@, etc. d@ is @a & (b - c)--- & d@.+-- rejected & second@ is @(first - rejected) & second@, etc. -- -- @match \/ alternative \/ otherwise@ is @match \/ (alternative \/ -- otherwise)@. Note that @first & second \/ third@ is @(first & second) \/ -- third@. -- -- @( match *)@, @(match +)@, @(match ?)@ are the weakest and require the--- @()@.+-- surrounding @()@. +infix 3 ^ infix 3 % infix 3 <%-infix 3 ^ infix 3 ! infix 3 ?! infixl 3 - infixr 2 & infixr 1 /-infix 0 ?-infix 0 *-infix 0 ++infix 0 ?+infix 0 *+infix 0 + -- | @parser % n@ repeats /parser/ exactly /n/ times. (%) :: (Match match result) => match -> Int -> Pattern@@ -672,10 +661,17 @@ | n <= 0 = empty | n > 0 = parser & parser % n .- 1 +-- | @parser <% n@ matches fewer than /n/ occurrences of /parser/.+(<%) :: (Match match result) => match -> Int -> Pattern+parser <% n+ | n < 1 = fail "Fewer than 0 repetitions"+ | n == 1 = reject parser Nothing+ | n > 1 = "<%" ^ ( parser ! "<%" & parser <% n .- 1 / empty )+ -- | @decision ^ (option \/ option \/ ...)@ provides a /decision/ name to the -- choice about to be made, to allow to @commit@ to it. (^) :: (Match match result) => String -> match -> Parser result-decision ^ parser = decide decision parser+decision ^ parser = choice decision (match parser) -- | @parser ! decision@ commits to /decision/ after successfully matching the -- /parser/.@@ -687,103 +683,121 @@ (?!) :: (Match match result) => match -> String -> Pattern parser ?! decision = peek parser & commit decision --- | @parser <% n@ matches fewer than /n/ occurrences of /parser/.-(<%) :: (Match match result) => match -> Int -> Pattern-parser <% n- | n < 1 = fail "Fewer than 0 repetitions"- | n == 1 = reject parser Nothing- | n > 1 = "<%" ^ ( parser ! "<%" & parser <% n .- 1 / empty )- -- | @parser - rejected@ matches /parser/, except if /rejected/ matches at this -- point. (-) :: (Match match1 result1, Match match2 result2) => match1 -> match2 -> Parser result1 parser - rejected = reject rejected Nothing & parser -- | @before & after@ parses /before/ and, if it succeeds, parses /after/. This--- basically invokes the monad's @>>=@ method.+-- basically invokes the monad's @>>=@ (bind) method. (&) :: (Match match1 result1, Match match2 result2) => match1 -> match2 -> Parser result2 before & after = (match before) >> (match after) -- | @first \/ second@ tries to parse /first/, and failing that parses -- /second/, unless /first/ has committed in which case is fails immediately.--- To achieve streaming, we need to construct the final state manually, passing--- the commitments through \"regardless\" of the results of either parsers.--- This allows our caller to start consuming tokens from a committed option--- before it is done parsing. (/) :: (Match match1 result, Match match2 result) => match1 -> match2 -> Parser result-first / second =- Parser $ \ originalState -> let decision = originalState|>sDecision- nestState = originalState { sDecision = "n/a" }- firstReply = parse first nestState- (firstIsCommitted, firstCommits) = commitStatus "n/a" decision $ D.toList $ firstReply|>rCommits- in if firstIsCommitted- then firstReply { rCommits = firstCommits }- else case firstReply|>rResult of- Right _ -> firstReply { rCommits = firstCommits }- Left _ -> let secondReply = parse second nestState- (_, secondCommits) = commitStatus "n/a" decision $ D.toList $ secondReply|>rCommits- in secondReply { rCommits = secondCommits }- where commitStatus :: String -> String -> [String] -> (Bool, D.DList String)- commitStatus prev decision [] = (False, D.empty)- commitStatus prev decision (name:rest) | name == decision = (True, snd $ commitStatus prev decision rest)- | name == prev = (True, snd $ commitStatus prev decision rest)- | otherwise = (True, D.cons name $ snd $ commitStatus name decision rest)+first / second = Parser $ \ state ->+ let Parser parser = decide (match first) (match second)+ in parser state --- | @(parser ?)@ (optional) tries to match /parser/, otherwise does nothing.+-- | @(optional ?)@ tries to match /parser/, otherwise does nothing. (?) :: (Match match result) => match -> Pattern-(?) parser = Parser $ \ state -> let reply = parse parser state- in case reply|>rResult of- Right _ -> reply { rResult = Right () }- Left _ -> returnReply state ()+(?) optional = "?" ^ (optional & empty / empty) --- | @(parser *)@ matches zero or more occurrences of /parser/. Tricky--- optimization: we only return the commitments of the first match. In the YAML--- syntax, the additional occurences will only repeat them.+-- | @(parser *)@ matches zero or more occurrences of /repeat/, as long as each+-- one actually consumes input characters. (*) :: (Match match result) => match -> Pattern-(*) parser = Parser zero_or_more- where zero_or_more state = let reply = parse parser state- in case (reply|>rResult, reply|>rDidConsume) of- (Left _, _) -> returnReply state ()- (Right _, False) -> returnReply state ()- (Right _, True) -> let reply' = zero_or_more $ reply|>rState- in bindReply reply reply' { rCommits = D.empty }+(*) parser = "*" ^ zomParser+ where zomParser = (nonEmpty parser ! "*" & zomParser) / empty --- | @(parser +)@ matches one or more occurrences of /parser/.+-- | @(parser +)@ matches one or more occurrences of /parser/, as long as each+-- one actually consumed input characters. (+) :: (Match match result) => match -> Pattern-(+) parser = parser & (parser *)+(+) parser = nonEmpty parser & (parser *) -- ** Basic parsers --- | @traced name parser@ traces all invocations to the parser. Is only used when--- debugging.-traced :: (Match match result, Show result) => String -> match -> Parser result-traced name parser = Parser $ \ state -> trace_reply name $ parse parser $ trace_call name state+-- | @decide first second@ tries to parse /first/, and failing that parses+-- /second/, unless /first/ has committed in which case is fails immediately.+decide :: Parser result -> Parser result -> Parser result+decide left right = Parser $ \ state ->+ let Parser parser = decideParser state D.empty left right+ in parser state+ where decideParser point tokens (Parser left) right = Parser $ \state ->+ let reply = left state+ tokens' reply = D.append tokens $ reply|>rTokens+ in case (reply|>rResult, reply|>rCommit) of+ (Failed _, _) -> Reply { rState = point,+ rTokens = D.empty,+ rResult = More right,+ rCommit = Nothing }+ (Result _, _) -> reply { rTokens = tokens' reply }+ (More left', Just _) -> reply { rTokens = tokens' reply,+ rResult = More left' }+ (More left', Nothing) -> let Parser parser = decideParser point (tokens' reply) left' right+ in parser $ reply|>rState --- | @trace_call name state@ traces the /state/ at the start of the call to /name/.-trace_call :: String -> State -> State-trace_call name state = trace ("Call " ++ name ++ " with " ++ (show state)) state+-- | @choice decision parser@ provides a /decision/ name to the choice about to+-- be made in /parser/, to allow to @commit@ to it.+choice :: String -> Parser result -> Parser result+choice decision parser = Parser $ \ state ->+ let Parser parser' = choiceParser (state|>sDecision) decision parser+ in parser' state { sDecision = decision }+ where choiceParser parentDecision makingDecision (Parser parser) = Parser $ \ state ->+ let reply = parser state+ commit' = case reply|>rCommit of+ Nothing -> Nothing+ Just decision | decision == makingDecision -> Nothing+ | otherwise -> reply|>rCommit+ reply' = case reply|>rResult of+ More parser' -> reply { rCommit = commit',+ rResult = More $ choiceParser parentDecision makingDecision parser' }+ _ -> reply { rCommit = commit',+ rState = (reply|>rState) { sDecision = parentDecision } }+ in reply' --- | @trace_call name reply@ traces the /reply/ from calling /name/.-trace_reply :: Show result => String -> Reply result -> Reply result-trace_reply name reply = trace ("Done " ++ name ++ " with " ++ (show reply)) reply+-- | @peek parser@ succeeds if /parser/ matches at this point, but does not+-- consume any input.+peek :: (Match match result) => match -> Parser result+peek parser = Parser $ \ state ->+ peekParser state (match parser) state { sIsPeek = True }+ where peekParser point (Parser parser) state =+ let reply = parser state+ in case reply|>rResult of+ Failed message -> failReply point message+ Result value -> returnReply point value+ More parser' -> peekParser point parser' $ reply|>rState --- | @reject rejected name@ fails if /rejected/ matches at this point, and does+-- | @reject parser name@ fails if /parser/ matches at this point, and does -- nothing otherwise. If /name/ is provided, it is used in the error message, -- otherwise the messages uses the current character. reject :: (Match match result) => match -> Maybe String -> Pattern-reject rejected name = Parser $ \ state -> let reply = parse rejected state { sIsPeek = True }- in case (reply|>rResult, name) of- (Left _, _) -> returnReply state ()- (Right _, Nothing) -> unexpectedReply state- (Right _, Just text) -> failReply state $ "Unexpected " ++ text+reject parser name = Parser $ \ state ->+ rejectParser state name (match parser) state { sIsPeek = True }+ where rejectParser point name (Parser parser) state =+ let reply = parser state+ in case reply|>rResult of+ Failed message -> returnReply point ()+ Result value -> case name of+ Nothing -> unexpectedReply point+ Just text -> failReply point $ "Unexpected " ++ text+ More parser' -> rejectParser point name parser' $ reply|>rState --- | @peek parser@ succeeds if /parser/ matches at this point, but does not--- consume any input.-peek :: (Match match result) => match -> Parser result-peek parser = Parser $ \ state -> let reply = parse parser state { sIsPeek = True }- in case reply|>rResult of- Right value -> returnReply state value- Left _ -> failReply state "Peek failed"+-- | @nonEmpty parser@ succeeds if /parser/ matches some non-empty input+-- characters at this point.+nonEmpty :: (Match match result) => match -> Parser result+nonEmpty parser = Parser $ \ state ->+ let Parser parser' = nonEmptyParser (state|>sOffset) (match parser)+ in parser' state+ where nonEmptyParser offset (Parser parser) = Parser $ \ state ->+ let reply = parser state+ state' = reply|>rState+ in case reply|>rResult of+ Failed message -> reply+ Result value -> if state'|>sOffset > offset+ then reply+ else failReply state' "Matched empty pattern"+ More parser' -> reply { rResult = More $ nonEmptyParser offset parser' } -- | @empty@ always matches without consuming any input. empty :: Pattern@@ -791,48 +805,51 @@ -- | @eof@ matches the end of the input. eof :: Pattern-eof = Parser $ \ state -> if state|>sInput == []- then returnReply state ()- else failReply state "Expected end of input"+eof = Parser $ \ state ->+ if state|>sInput == []+ then returnReply state ()+ else failReply state "Expected end of input" -- | @sol@ matches the start of a line. sol :: Pattern-sol = Parser $ \ state -> if state|>sColumn == 0- then returnReply state ()- else failReply state "Expected start of line"+sol = Parser $ \ state ->+ if state|>sColumn == 0+ then returnReply state ()+ else failReply state "Expected start of line" -- ** State manipulation pseudo-parsers --- | @incrLine@ increments @sLine@ counter resets @sColumn@.+-- | @commit decision@ commits the parser to all the decisions up to the most+-- recent parent /decision/. This makes all tokens generated in this parsing+-- path immediately available to the caller.+commit :: String -> Pattern+commit decision = Parser $ \ state ->+ Reply { rState = state,+ rTokens = D.empty,+ rResult = Result (),+ rCommit = Just decision }++-- | @nextLine@ increments @sLine@ counter and resets @sColumn@. nextLine :: Pattern-nextLine = Parser $ \ state -> returnReply state { sLine = state|>sLine .+ 1,- sColumn = 0 }- ()+nextLine = Parser $ \ state ->+ returnReply state { sLine = state|>sLine .+ 1,+ sColumn = 0 }+ () -- | @with setField getField value parser@ invokes the specified /parser/ with -- the value of the specified field set to /value/ for the duration of the -- invocation, using the /setField/ and /getField/ functions to manipulate it. with :: (value -> State -> State) -> (State -> value) -> value -> Parser result -> Parser result-with setField getField value parser = Parser $ \ originalState -> let originalValue = getField originalState- withState = setField value originalState- reply = parse parser withState- finalState = setField originalValue $ reply|>rState- in reply { rState = finalState }---- | @decide name (a / b / ...)@ names the contained decision point so it can be--- addressed by later @commit@ calls.-decide :: (Match match result) => String -> match -> Parser result-decide decision parser = with setDecision sDecision decision $ match parser---- | @commit name@ commits the parser to all the decisions up to the most recent--- containing decision with the specified /name/. This makes all tokens--- generated in this parsing path immediately available to the caller.-commit :: String -> Pattern-commit name = Parser $ \ state -> Reply { rResult = Right (),- rState = state,- rTokens = D.empty,- rCommits = D.singleton name,- rDidConsume = False }+with setField getField value parser = Parser $ \ state ->+ let value' = getField state+ Parser parser' = value' `seq` withParser value' parser+ in parser' $ setField value state+ where withParser parentValue (Parser parser) = Parser $ \ state ->+ let reply = parser state+ in case reply|>rResult of+ Failed _ -> reply { rState = setField parentValue $ reply|>rState }+ Result _ -> reply { rState = setField parentValue $ reply|>rState }+ More parser' -> reply { rResult = More $ withParser parentValue parser' } -- | @parser ``forbidding`` pattern@ parses the specified /parser/ ensuring -- that it does not contain anything matching the /forbidden/ parser.@@ -850,59 +867,45 @@ -- pattern or if the 'State' lookahead limit is reached. Otherwise it consumes -- (and buffers) the next input char if it satisfies /test/. nextIf :: (Char -> Bool) -> Pattern-nextIf test = Parser $ \ state -> case state|>sForbidden of- Nothing -> limitedNextIf state- Just parser -> let reply = parse parser state { sIsPeek = True,- sForbidden = Nothing }- in case reply|>rResult of- Left _ -> limitedNextIf state- Right _ -> failReply state "Forbidden pattern detected"- where limitedNextIf state = case state|>sLimit of- -1 -> consumeNextIf state- 0 -> failReply state "Lookahead limit reached"- limit -> consumeNextIf state { sLimit = state|>sLimit .- 1 }- consumeNextIf state = case state|>sInput of- (char:rest) | test char -> let chars = if state|>sIsPeek- then []- else char:(state|>sChars)- state' = state { sInput = rest,- sLast = char,- sChars = chars,- sColumn = state|>sColumn .+ 1 }- in Reply { rResult = Right (),- rState = state',- rTokens = D.empty,- rCommits = D.empty,- rDidConsume = True }- | otherwise -> unexpectedReply state- [] -> unexpectedReply state---- | @unexpectedReply state@ returns a @failReply@ for an unexpected character.-unexpectedReply :: State -> Reply ()-unexpectedReply state = case state|>sInput of- (char:_) -> failReply state $ "Unexpected '" ++ [char] ++ "'"- [] -> failReply state "Unexpected end of input"+nextIf test = Parser $ \ state ->+ case state|>sForbidden of+ Nothing -> limitedNextIf state+ Just parser -> let Parser parser' = reject parser $ Just "forbidden pattern"+ reply = parser' state { sForbidden = Nothing }+ in case reply|>rResult of+ Failed _ -> reply+ Result _ -> limitedNextIf state+ where limitedNextIf state =+ case state|>sLimit of+ -1 -> consumeNextIf state+ 0 -> failReply state "Lookahead limit reached"+ limit -> consumeNextIf state { sLimit = state|>sLimit .- 1 }+ consumeNextIf state =+ case state|>sInput of+ (char:rest) | test char -> let chars = if state|>sIsPeek+ then []+ else char:(state|>sChars)+ state' = state { sInput = rest,+ sLast = char,+ sChars = chars,+ sOffset = state|>sOffset .+ 1,+ sColumn = state|>sColumn .+ 1 }+ in returnReply state' ()+ | otherwise -> unexpectedReply state+ [] -> unexpectedReply state -- ** Producing tokens -- | @finishToken@ places all collected text into a new token and begins a new -- one, or does nothing if there are no collected characters. finishToken :: Pattern-finishToken = Parser $ \ state -> if state|>sIsPeek- then returnReply state ()- else case state|>sChars of- [] -> returnReply state ()- chars@(_:_) -> tokenReply state Token { tCode = state|>sCode,- tText = reverse chars }---- | @tokenReply state token@ returns a 'Reply' containing the /state/ and--- /token/. Any collected characters are cleared (either there are none, or we--- put them in this token, or we don't want them).-tokenReply state token = Reply { rResult = Right (),- rState = state { sChars = [] },- rTokens = D.singleton token,- rCommits = D.empty,- rDidConsume = False }+finishToken = Parser $ \ state ->+ if state|>sIsPeek+ then returnReply state ()+ else case state|>sChars of+ [] -> returnReply state ()+ chars@(_:_) -> tokenReply state Token { tCode = state|>sCode,+ tText = reverse chars } -- | @wrap parser@ invokes the /parser/, ensures any unclaimed input characters -- are wrapped into a token (only happens when testing productions), ensures no@@ -918,9 +921,9 @@ consume :: (Match match result) => match -> Parser result consume parser = do result <- match parser finishToken- clear_input+ clearInput return result- where clear_input = Parser $ \ state -> returnReply state { sInput = [] } ()+ where clearInput = Parser $ \ state -> returnReply state { sInput = [] } () -- | @token code parser@ places all text matched by /parser/ into a 'Token' with -- the specified /code/ (unless it is empty). Note it collects the text even if@@ -931,10 +934,11 @@ -- | @fake code text@ creates a token with the specified /code/ and \"fake\" -- /text/ characters, instead of whatever characters are collected so far. fake :: Code -> String -> Pattern-fake code text = Parser $ \ state -> if state|>sIsPeek- then returnReply state ()- else tokenReply state Token { tCode = code,- tText = text }+fake code text = Parser $ \ state ->+ if state|>sIsPeek+ then returnReply state ()+ else tokenReply state Token { tCode = code,+ tText = text } -- | @meta parser@ collects the text matched by the specified /parser/ into a -- | @Meta@ token.@@ -954,12 +958,12 @@ -- | @nest code@ returns an empty token with the specified begin\/end /code/ to -- signal nesting. nest :: Code -> Pattern-nest code = Parser $ \ state -> if state|>sIsPeek- then returnReply state ()- else let left = parse finishToken state- right = tokenReply state Token { tCode = code,- tText = "" }- in bindReply left right+nest code = finishToken & nestParser code+ where nestParser code = Parser $ \ state ->+ if state|>sIsPeek+ then returnReply state ()+ else tokenReply state Token { tCode = code,+ tText = "" } -- * Production parameters @@ -1046,66 +1050,54 @@ -- implementation details from our callers. -- | 'Tokenizer' converts a (named) input text into a list of 'Token'. Errors--- are reported as tokens.+-- are reported as tokens with the @Error@ 'Code'. type Tokenizer = String -> C.ByteString -> [Token] -- | @patternTokenizer pattern@ converts the /pattern/ to a simple 'Tokenizer'.--- Note how using difference lists we can tuck the error token at the end of--- the result without preventing the streaming. patternTokenizer :: Pattern -> Tokenizer patternTokenizer pattern name input =- let reply = parse (wrap pattern) (initialState name input)- last = case reply|>rResult of- Right _ -> D.empty- Left message -> D.singleton Token { tCode = Error,- tText = message }- bugs = commitBugs "n/a" $ D.toList $ reply|>rCommits- errors = D.append bugs last- in D.toList $ D.append (reply|>rTokens) errors--{- NOTE: the 'debug-leak' production will run in constant memory "forever" when- - using the following instead - that is, discarding the result and- - commitments.--patternTokenizer pattern name input =- let reply = parse pattern (initialState name input)- in D.toList $ reply|>rTokens---}+ D.toList $ patternParser (wrap pattern) (initialState name input)+ where patternParser (Parser parser) state =+ let reply = parser state+ tokens = commitBugs reply+ in case reply|>rResult of+ Failed message -> D.append tokens $ D.singleton Token { tCode = Error,+ tText = message }+ Result _ -> tokens+ More parser' -> D.append tokens $ patternParser parser' $ reply|>rState -- | @parserTokenizer what parser@ converts the /parser/ returning /what/ to a--- simple 'Tokenizer' (only used for tests). Note how using difference lists we--- can tuck the result or error token at the end of the result without--- preventing the streaming.+-- simple 'Tokenizer' (only used for tests). The result is reported as a token+-- with the @Detected@ 'Code' The result is reported as a token with the+-- @Detected@ 'Code'. parserTokenizer :: (Show result, Match match result) => String -> match -> Tokenizer parserTokenizer what parser name input =- let reply = parse (wrap parser) (initialState name input)- last = case reply|>rResult of- Right value -> Token { tCode = Detected,- tText = what ++ "=" ++ (show value) }- Left message -> Token { tCode = Error,- tText = message }- bugs = commitBugs "n/a" $ D.toList $ reply|>rCommits- errors = D.snoc bugs last- in D.toList $ D.append (reply|>rTokens) errors+ D.toList $ parserParser (wrap parser) (initialState name input)+ where parserParser (Parser parser) state =+ let reply = parser state+ tokens = commitBugs reply+ in case reply|>rResult of+ Failed message -> D.append tokens $ D.singleton Token { tCode = Error,+ tText = message }+ Result value -> D.append tokens $ D.singleton Token { tCode = Detected,+ tText = what ++ "=" ++ (show value) }+ More parser' -> D.append tokens $ parserParser parser' $ reply|>rState --- | @commitBugs commits@ converts any @commit@ calls made outside the decision--- they refer to into an error token. No such calls should exists outside--- tests.-commitBugs :: String -> [String] -> D.DList Token-commitBugs prev [] = D.empty-commitBugs prev (decision:rest)- | decision == prev = commitBugs prev rest- | otherwise = D.cons Token { tCode = Error,- tText = "Commit to '" ++ decision ++ "' was made outside it" }- $ commitBugs decision rest+-- | @commitBugs reply@ inserts an error token if a commit was made outside a+-- named choice. This should never happen outside tests.+commitBugs :: Reply result -> D.DList Token+commitBugs reply =+ let tokens = reply|>rTokens+ in case reply|>rCommit of+ Nothing -> tokens+ Just commit -> D.append tokens $ D.singleton Token { tCode = Error,+ tText = "Commit to '" ++ commit ++ "' was made outside it" } -- | @yaml name input@ converts the Unicode /input/ (called /name/ in error -- messages) to a list of 'Token' according to the YAML spec. This is it! yaml :: Tokenizer yaml = patternTokenizer l_yaml_stream --- CPP LINES CAUSE HADDOCK TO BARF -- #ifdef REAL_CPP -- This is how non-ancient C pre-processor do it. #define STR(X) #X@@ -1117,7 +1109,6 @@ #define PAT(PATTERN) pat STR(PATTERN) PATTERN #define PAR(PARSER) par STR(PARSER) PARSER #define PAC(PARSER) pac STR(PARSER) PARSER--- CPP LINES CAUSE HADDOCK TO BARF -- -- | @pName name@ converts a parser name to the \"proper\" spec name. pName :: String -> String@@ -1134,7 +1125,6 @@ tokenizers :: Map.Map String Tokenizer tokenizers = PAR(c_chomping_indicator) "t" $ PAC(detect_inline_indentation) "m"- $ PAT(debug_leak) $ PAT(b_as_line_feed) $ PAT(b_carriage_return) $ PAT(b_char)@@ -1496,7 +1486,8 @@ UTF8 -> "TF8" UTF16LE -> "TF16LE" UTF16BE -> "TF16BE"- in parse (fake Bom text) state { sColumn = state|>sColumn .- 1 }+ Parser parser = fake Bom text+ in parser state { sColumn = state|>sColumn .- 1 } -- | @na@ is the \"non-applicable\" indentation value. We use Haskell's laziness -- to verify it really is never used.@@ -1514,8 +1505,4 @@ result :: result -> Parser result result = return --- CPP LINES CAUSE HADDOCK TO BARF -- #include "Reference.bnf"--- CPP LINES CAUSE HADDOCK TO BARF ----debug_leak = ( c_comment & b_line_feed *)
YamlReference.cabal view
@@ -1,5 +1,5 @@ Name: YamlReference-Version: 0.2+Version: 0.3 License: LGPL License-File: lgpl.txt Copyright: Oren Ben-Kiki 2007@@ -7,7 +7,7 @@ Maintainer: yaml-oren@ben-kiki.org Stability: alpha Homepage: www.ben-kiki.org/oren/YamlReference-Package-Url: www.ben-kiki.org/oren/YamlReference/YamlReference-0.2.tar.gz+Package-Url: www.ben-kiki.org/oren/YamlReference/YamlReference-0.3.tar.gz Category: Text Synopsis: YAML reference implementation Description: This package contains \"the\" reference YAML syntax parser@@ -20,15 +20,12 @@ interesting tools on top of it, such as the @yeast2html@ YAML syntax visualizer (contained in this package), pretty printers, etc. This is a streaming parser that will- \"immediately\" begin to generate output, but it has a memory- leak (actually, retention) problem that prevents it from being- applied to \"large\" files. To debug this with minimal syntax- productions use @yes "#" | yaml2yeast -p debug-leak@.+ \"immediately\" begin to generate output. The memory leak that+ existed in previous version has been plugged. Build-Depends: base >= 2.0, HUnit >= 1.1, regex-compat >= 0.71, dlist >= 0.2 Exposed-Modules: Text.Yaml.Reference Extensions: CPP, MultiParamTypeClasses Data-Files: Text/Yaml/Reference.bnf yeast2html yaml2yeast.css- tests/debug-leak.input tests/debug-leak.output tests/b-as-line-feed.input tests/b-as-line-feed.output tests/b-carriage-return.input tests/b-carriage-return.output tests/b-char.cr.input tests/b-char.cr.output
tests/c-b+block-header.n=2.s=folded.i.output view
@@ -1,4 +1,4 @@ I>-b\x0a !Commit to 'node' was made outside it+b\x0a $(m,t)=(1,clip)
tests/c-b+block-header.n=2.s=folded.im.output view
@@ -1,5 +1,5 @@ I>+!Commit to 'node' was made outside it I7 b\x0a-!Commit to 'node' was made outside it $(m,t)=(7,clip)
tests/c-b+block-header.n=2.s=folded.imt.output view
@@ -1,6 +1,6 @@ I>+!Commit to 'node' was made outside it I7 I- b\x0a-!Commit to 'node' was made outside it $(m,t)=(7,strip)
tests/c-b+block-header.n=2.s=folded.it.output view
@@ -1,5 +1,5 @@ I>+!Commit to 'node' was made outside it I- b\x0a-!Commit to 'node' was made outside it $(m,t)=(1,strip)
tests/c-b+block-header.n=2.s=folded.itm.output view
@@ -1,6 +1,6 @@ I>+!Commit to 'node' was made outside it I- I7 b\x0a-!Commit to 'node' was made outside it $(m,t)=(7,strip)
tests/c-double-quoted.n=4.c=flow-out.invalid.output view
@@ -1,5 +1,5 @@ S I"-Ta !Commit to 'node' was made outside it+Ta !$InputFile$: line 1: column 2: Unexpected '\x0a'
tests/c-double-quoted.n=4.c=flow-out.output view
@@ -1,5 +1,6 @@ S I"+!Commit to 'node' was made outside it T a w l\x0a@@ -8,4 +9,3 @@ Ta b\x09c I" s-!Commit to 'node' was made outside it
tests/c-flow-json-content.n=4.c=flow-in.double.output view
@@ -1,6 +1,6 @@ S I"+!Commit to 'node' was made outside it Ta I" s-!Commit to 'node' was made outside it
tests/c-flow-json-content.n=4.c=flow-in.mapping.output view
@@ -1,5 +1,6 @@ M I{+!Commit to 'node' was made outside it X N S@@ -10,10 +11,10 @@ w N S+!Commit to 'node' was made outside it Tb s n x I} m-!Commit to 'node' was made outside it
tests/c-flow-json-content.n=4.c=flow-in.sequence.output view
@@ -1,5 +1,6 @@ Q I[+!Commit to 'node' was made outside it N S Ta@@ -7,4 +8,3 @@ n I] q-!Commit to 'node' was made outside it
tests/c-flow-json-node.n=4.c=flow-in.tagged.output view
@@ -10,8 +10,8 @@ w S I"+!Commit to 'node' was made outside it Ta I" s n-!Commit to 'node' was made outside it
tests/c-flow-json-node.n=4.c=flow-in.untagged.output view
@@ -1,8 +1,8 @@ N S I"+!Commit to 'node' was made outside it Ta I" s n-!Commit to 'node' was made outside it
tests/c-flow-mapping.n=4.c=flow-in.compact.output view
@@ -1,5 +1,6 @@ M I{+!Commit to 'node' was made outside it X N S@@ -11,6 +12,7 @@ I: N S+!Commit to 'node' was made outside it Tb s n@@ -39,6 +41,7 @@ w N S+!Commit to 'node' was made outside it Td s n@@ -57,4 +60,3 @@ x I} m-!Commit to 'node' was made outside it
tests/c-flow-mapping.n=4.c=flow-in.invalid.output view
@@ -1,5 +1,6 @@ M I{+!Commit to 'node' was made outside it X N S@@ -11,5 +12,4 @@ s n x-!Commit to 'node' was made outside it !$InputFile$: line 1: column 2: Unexpected end of input
tests/c-flow-mapping.n=4.c=flow-in.spaced.output view
@@ -1,5 +1,6 @@ M I{+!Commit to 'node' was made outside it w X N@@ -14,6 +15,7 @@ w N S+!Commit to 'node' was made outside it Tb s n@@ -44,6 +46,7 @@ w N S+!Commit to 'node' was made outside it Td s n@@ -67,4 +70,3 @@ w I} m-!Commit to 'node' was made outside it
tests/c-flow-sequence.n=4.c=flow-in.compact.output view
@@ -1,5 +1,6 @@ Q I[+!Commit to 'node' was made outside it N S Ta@@ -17,6 +18,7 @@ w N S+!Commit to 'node' was made outside it Td s n@@ -24,4 +26,3 @@ m I] q-!Commit to 'node' was made outside it
tests/c-flow-sequence.n=4.c=flow-in.invalid.output view
@@ -1,10 +1,10 @@ Q I[+!Commit to 'node' was made outside it N S Ta s n I,-!Commit to 'node' was made outside it !$InputFile$: line 1: column 3: Unexpected end of input
tests/c-flow-sequence.n=4.c=flow-in.spaced.output view
@@ -1,5 +1,6 @@ Q I[+!Commit to 'node' was made outside it w N S@@ -20,6 +21,7 @@ w N S+!Commit to 'node' was made outside it Td s n@@ -30,4 +32,3 @@ w I] q-!Commit to 'node' was made outside it
tests/c-l+folded.n=2.indent.output view
@@ -1,5 +1,6 @@ S I>+!Commit to 'node' was made outside it I2 w C@@ -23,4 +24,3 @@ I# c b\x0a-!Commit to 'node' was made outside it
tests/c-l+folded.n=2.invalid.output view
@@ -1,5 +1,5 @@ S I>-b\x0a !Commit to 'node' was made outside it+b\x0a !$InputFile$: line 2: column 0: Expected end of input
tests/c-l+folded.n=2.simple.output view
@@ -1,8 +1,8 @@ S I>+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s-!Commit to 'node' was made outside it
tests/c-l+literal.n=2.invalid.output view
@@ -1,7 +1,7 @@ S I|+!Commit to 'node' was made outside it I2 I- b\x0a-!Commit to 'node' was made outside it !$InputFile$: line 2: column 0: Expected end of input
tests/c-l+literal.n=2.simple.output view
@@ -1,8 +1,8 @@ S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s-!Commit to 'node' was made outside it
tests/c-l+literal.n=2.strip-indent.output view
@@ -1,5 +1,6 @@ S I|+!Commit to 'node' was made outside it I- I2 b\x0a@@ -21,4 +22,3 @@ I# c b\x0a-!Commit to 'node' was made outside it
tests/c-l+literal.n=2.strip.output view
@@ -1,5 +1,6 @@ S I|+!Commit to 'node' was made outside it I- b\x0a i @@ -20,4 +21,3 @@ I# c b\x0a-!Commit to 'node' was made outside it
tests/c-l-block-map-explicit-entry.n=2.output view
@@ -1,7 +1,9 @@ I?+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n@@ -11,8 +13,8 @@ w N S+!Commit to 'node' was made outside it Tb s n b\x0a-!Commit to 'node' was made outside it
tests/c-l-block-map-explicit-key.n=2.output view
@@ -1,9 +1,10 @@ I?+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/c-l-block-map-implicit-value.n=2.empty.output view
@@ -1,7 +1,7 @@ I:+!Commit to 'node' was made outside it N S s n b\x0a-!Commit to 'node' was made outside it
tests/c-l-block-map-implicit-value.n=2.invalid.output view
@@ -1,7 +1,7 @@ I:+!Commit to 'node' was made outside it N S s n-!Commit to 'node' was made outside it !$InputFile$: line 1: column 1: Expected start of line
tests/c-l-block-map-implicit-value.n=2.plain.output view
@@ -1,9 +1,10 @@ I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/c-l-block-seq-entry.n=2.output view
@@ -1,9 +1,10 @@ I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/c-ns-alias.output view
@@ -1,5 +1,5 @@ R I*+!Commit to 'node' was made outside it t*&!name r-!Commit to 'node' was made outside it
tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.compact.output view
@@ -1,8 +1,8 @@ I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.empty.output view
@@ -1,6 +1,6 @@ I:+!Commit to 'pair' was made outside it N S s n-!Commit to 'pair' was made outside it
tests/c-ns-flow-map-adjacent-value.n=4.c=flow-in.spaced.output view
@@ -1,9 +1,9 @@ I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-ns-flow-map-implicit-json.n=4.c=flow-in.compact.output view
@@ -6,10 +6,10 @@ s n I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-ns-flow-map-implicit-json.n=4.c=flow-in.spaced.output view
@@ -7,11 +7,11 @@ n w I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-ns-flow-map-separate-value.n=4.c=flow-in.empty.output view
@@ -1,6 +1,6 @@ I:+!Commit to 'pair' was made outside it N S s n-!Commit to 'pair' was made outside it
tests/c-ns-flow-map-separate-value.n=4.c=flow-in.invalid.output view
@@ -1,7 +1,7 @@ I:+!Commit to 'pair' was made outside it N S s n-!Commit to 'pair' was made outside it !$InputFile$: line 1: column 1: Expected end of input
tests/c-ns-flow-map-separate-value.n=4.c=flow-in.value.output view
@@ -1,9 +1,9 @@ I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-ns-flow-map-single-json.n=4.c=flow-in.output view
@@ -6,10 +6,10 @@ s n I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/c-quoted-quote.output view
@@ -1,5 +1,5 @@ E I'+!Commit to 'escape' was made outside it t' e-!Commit to 'escape' was made outside it
− tests/debug-leak.input
@@ -1,1 +0,0 @@-#
− tests/debug-leak.output
@@ -1,2 +0,0 @@-I#-?\x0a
tests/l+block-mapping.n=1.output view
@@ -7,9 +7,11 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n@@ -18,9 +20,11 @@ i X I?+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tc s n@@ -30,10 +34,10 @@ w N S+!Commit to 'node' was made outside it Td s n b\x0a x m-!Commit to 'node' was made outside it
tests/l+block-sequence.n=1.output view
@@ -1,23 +1,28 @@ Q i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a i I-+!Commit to 'node' was made outside it N b\x0a Q i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n@@ -26,6 +31,7 @@ n i I-+!Commit to 'node' was made outside it i N Q@@ -49,4 +55,3 @@ q n q-!Commit to 'node' was made outside it
tests/l-block-map-explicit-value.n=2.output view
@@ -3,8 +3,8 @@ w N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/l-explicit-document.invalid.output view
@@ -1,10 +1,10 @@ O K---+!Commit to 'doc' was made outside it N S s n b\x0a o-!Commit to 'doc' was made outside it !$InputFile$: line 2: column 0: Expected end of input
tests/l-explicit-document.literal.output view
@@ -1,5 +1,6 @@ O K---+!Commit to 'doc' was made outside it O N w @@ -12,4 +13,3 @@ n o o-!Commit to 'doc' was made outside it
tests/l-explicit-document.plain.output view
@@ -6,7 +6,9 @@ t1.1 d b\x0a+!Commit to 'doc' was made outside it K---+!Commit to 'doc' was made outside it O w N@@ -17,4 +19,3 @@ b\x0a o o-!Commit to 'doc' was made outside it
tests/l-implicit-document.invalid.output view
@@ -1,4 +1,4 @@ O N S-!$InputFile$: line 1: column 0: Forbidden pattern detected+!$InputFile$: line 1: column 0: Unexpected forbidden pattern
tests/l-implicit-document.literal.output view
@@ -2,10 +2,10 @@ N S I|+!Commit to 'node' was made outside it b\x0a Ta L\x0a s n o-!Commit to 'node' was made outside it
tests/l-implicit-document.plain.output view
@@ -1,9 +1,9 @@ O N S+!Commit to 'node' was made outside it Ta s n b\x0a o-!Commit to 'node' was made outside it
tests/l-nb-folded-lines.n=4.invalid.output view
@@ -1,4 +1,4 @@ i -?a !Commit to 'fold' was made outside it+?a !$InputFile$: line 1: column 5: Expected end of input
tests/l-nb-folded-lines.n=4.output view
@@ -1,10 +1,12 @@ i +!Commit to 'fold' was made outside it ?a l\x0a i +!Commit to 'fold' was made outside it ?b b\x0a L\x0a i -?c !Commit to 'fold' was made outside it+?c
tests/l-nb-spaced-lines.n=4.output view
@@ -1,10 +1,12 @@ i +!Commit to 'fold' was made outside it ? a L\x0a i +!Commit to 'fold' was made outside it ? b L\x0a L\x0a i -? c !Commit to 'fold' was made outside it+? c
tests/l-nb-start-with-folded.n=4.output view
@@ -1,12 +1,14 @@ i L\x0a i +!Commit to 'fold' was made outside it ?a L\x0a i +!Commit to 'fold' was made outside it ? b L\x0a L\x0a i -?c !Commit to 'fold' was made outside it+?c
tests/l-nb-start-with-spaced.n=4.output view
@@ -1,10 +1,12 @@ i +!Commit to 'fold' was made outside it ? a L\x0a i +!Commit to 'fold' was made outside it ?b L\x0a L\x0a i -? c !Commit to 'fold' was made outside it+? c
tests/ns-esc-16-bit.output view
@@ -1,3 +1,3 @@ Iu-tFEDC !Commit to 'escaped' was made outside it+tFEDC
tests/ns-esc-32-bit.output view
@@ -1,3 +1,3 @@ IU-t0010FEDC !Commit to 'escaped' was made outside it+t0010FEDC
tests/ns-esc-8-bit.output view
@@ -1,3 +1,3 @@ Ix-tFF !Commit to 'escaped' was made outside it+tFF
tests/ns-esc-char.16-bit.output view
@@ -1,6 +1,6 @@ E I\x5c+!Commit to 'escape' was made outside it Iu tFEDC e-!Commit to 'escape' was made outside it
tests/ns-esc-char.32-bit.output view
@@ -1,6 +1,6 @@ E I\x5c+!Commit to 'escape' was made outside it IU t0010FEDC e-!Commit to 'escape' was made outside it
tests/ns-esc-char.8-bit.output view
@@ -1,6 +1,6 @@ E I\x5c+!Commit to 'escape' was made outside it Ix tFF e-!Commit to 'escape' was made outside it
tests/ns-esc-char.backslash.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it t\x5c e-!Commit to 'escape' was made outside it
tests/ns-esc-char.bell.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it ta e-!Commit to 'escape' was made outside it
tests/ns-esc-char.bs.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tb e-!Commit to 'escape' was made outside it
tests/ns-esc-char.cr.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tr e-!Commit to 'escape' was made outside it
tests/ns-esc-char.double-quote.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it t" e-!Commit to 'escape' was made outside it
tests/ns-esc-char.esc.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it te e-!Commit to 'escape' was made outside it
tests/ns-esc-char.ff.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tf e-!Commit to 'escape' was made outside it
tests/ns-esc-char.lf.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tn e-!Commit to 'escape' was made outside it
tests/ns-esc-char.ls.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tL e-!Commit to 'escape' was made outside it
tests/ns-esc-char.nbsp.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it t_ e-!Commit to 'escape' was made outside it
tests/ns-esc-char.nl.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tN e-!Commit to 'escape' was made outside it
tests/ns-esc-char.null.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it t0 e-!Commit to 'escape' was made outside it
tests/ns-esc-char.ps.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tP e-!Commit to 'escape' was made outside it
tests/ns-esc-char.sp.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it t e-!Commit to 'escape' was made outside it
tests/ns-esc-char.tab.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tt e-!Commit to 'escape' was made outside it
tests/ns-esc-char.vt.output view
@@ -1,5 +1,5 @@ E I\x5c+!Commit to 'escape' was made outside it tv e-!Commit to 'escape' was made outside it
tests/ns-flow-content.n=4.c=flow-in.json.output view
@@ -1,6 +1,6 @@ S I"+!Commit to 'node' was made outside it Ta I" s-!Commit to 'node' was made outside it
tests/ns-flow-content.n=4.c=flow-in.yaml.output view
@@ -1,4 +1,4 @@ S+!Commit to 'node' was made outside it Ta s-!Commit to 'node' was made outside it
tests/ns-flow-map-entry.n=4.c=flow-in.explicit.output view
@@ -10,8 +10,8 @@ w N S+!Commit to 'node' was made outside it Tb s n x-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-empty.n=4.c=flow-in.invalid.output view
@@ -3,9 +3,9 @@ s n I:+!Commit to 'pair' was made outside it N S s n-!Commit to 'pair' was made outside it !$InputFile$: line 1: column 1: Expected end of input
tests/ns-flow-map-implicit-empty.n=4.c=flow-in.output view
@@ -3,11 +3,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-entry.n=4.c=flow-in.empty.output view
@@ -3,11 +3,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-entry.n=4.c=flow-in.json.output view
@@ -6,10 +6,10 @@ s n I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-entry.n=4.c=flow-in.yaml.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-yaml.n=4.c=flow-in.compact.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-implicit-yaml.n=4.c=flow-in.spaced.output view
@@ -5,11 +5,11 @@ n w I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-entry.n=4.c=flow-in.empty.output view
@@ -3,11 +3,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-entry.n=4.c=flow-in.json.output view
@@ -6,10 +6,10 @@ s n I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-entry.n=4.c=flow-in.yaml.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-pair.n=4.c=flow-in.explicit.output view
@@ -1,6 +1,7 @@ M X I?+!Commit to 'pair' was made outside it w N S@@ -8,13 +9,13 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n x m-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-pair.n=4.c=flow-in.implicit.output view
@@ -6,13 +6,13 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n x m-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-map-single-yaml.n=4.c=flow-in.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/ns-flow-node.n=4.c=flow-in.alias.output view
@@ -1,7 +1,7 @@ N R I*+!Commit to 'node' was made outside it ta r n-!Commit to 'node' was made outside it
tests/ns-flow-node.n=4.c=flow-in.tagged.output view
@@ -10,8 +10,8 @@ w S I"+!Commit to 'node' was made outside it Ta I" s n-!Commit to 'node' was made outside it
tests/ns-flow-node.n=4.c=flow-in.untagged.output view
@@ -1,6 +1,6 @@ N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'node' was made outside it
tests/ns-flow-seq-entry.n=4.c=flow-in.pair.output view
@@ -9,9 +9,9 @@ w N S+!Commit to 'node' was made outside it Tb s n x m-!Commit to 'node' was made outside it
tests/ns-flow-yaml-content.n=4.c=flow-in.output view
@@ -1,4 +1,4 @@ S+!Commit to 'node' was made outside it Ta s-!Commit to 'node' was made outside it
tests/ns-flow-yaml-node.n=4.c=flow-in.alias.output view
@@ -1,7 +1,7 @@ N R I*+!Commit to 'node' was made outside it ta r n-!Commit to 'node' was made outside it
tests/ns-flow-yaml-node.n=4.c=flow-in.tagged.output view
@@ -9,7 +9,7 @@ p w S+!Commit to 'node' was made outside it Ta s n-!Commit to 'node' was made outside it
tests/ns-flow-yaml-node.n=4.c=flow-in.untagged.output view
@@ -1,6 +1,6 @@ N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'node' was made outside it
tests/ns-l-block-map-entry.n=2.explicit.output view
@@ -1,8 +1,10 @@ X I?+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n@@ -12,10 +14,10 @@ w N S+!Commit to 'node' was made outside it Tb s n b\x0a b\x0a x-!Commit to 'node' was made outside it
tests/ns-l-block-map-entry.n=2.implicit.output view
@@ -5,12 +5,13 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n b\x0a x-!Commit to 'node' was made outside it
tests/ns-l-block-map-implicit-entry.n=2.empty.output view
@@ -3,9 +3,9 @@ s n I:+!Commit to 'node' was made outside it N S s n b\x0a-!Commit to 'node' was made outside it
tests/ns-l-block-map-implicit-entry.n=2.non-empty.output view
@@ -4,11 +4,12 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n b\x0a-!Commit to 'node' was made outside it
tests/ns-l-in-line-mapping.n=2.output view
@@ -7,9 +7,11 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n@@ -23,9 +25,11 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Td s n@@ -33,4 +37,3 @@ x m n-!Commit to 'node' was made outside it
tests/ns-l-in-line-sequence.n=3.invalid.output view
@@ -1,14 +1,15 @@ N Q I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a q n-!Commit to 'node' was made outside it !$InputFile$: line 2: column 0: Expected end of input
tests/ns-l-in-line-sequence.n=3.output view
@@ -1,22 +1,25 @@ N Q I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n b\x0a q n-!Commit to 'node' was made outside it
tests/ns-plain-multi.n=4.c=flow-in.invalid.output view
@@ -1,6 +1,6 @@+!Commit to 'node' was made outside it ?a l\x0a i ?12-!Commit to 'node' was made outside it !$InputFile$: line 2: column 6: Expected end of input
tests/ns-plain-multi.n=4.c=flow-in.output view
@@ -1,3 +1,4 @@+!Commit to 'node' was made outside it ?a w\x09 b\x0a@@ -10,4 +11,3 @@ i w ?c-!Commit to 'node' was made outside it
tests/ns-plain-single.c=flow-key.invalid.output view
@@ -1,3 +1,3 @@-?12 !Commit to 'node' was made outside it+?12 !$InputFile$: line 1: column 2: Expected end of input
tests/ns-plain-single.c=flow-out.output view
@@ -1,2 +1,2 @@-?a \x09" :# {} b !Commit to 'node' was made outside it+?a \x09" :# {} b
tests/ns-plain.n=4.c=flow-in.output view
@@ -1,4 +1,5 @@ S+!Commit to 'node' was made outside it Ta w\x09 b\x0a@@ -12,4 +13,3 @@ w Tc s-!Commit to 'node' was made outside it
tests/ns-plain.n=4.c=flow-key.invalid.output view
@@ -1,5 +1,5 @@ S+!Commit to 'node' was made outside it T12 s-!Commit to 'node' was made outside it !$InputFile$: line 1: column 2: Expected end of input
tests/ns-plain.n=4.c=flow-key.output view
@@ -1,4 +1,4 @@ S+!Commit to 'node' was made outside it Ta \x09" :# () b s-!Commit to 'node' was made outside it
tests/ns-s-flow-map-entries.n=4.c=flow-in.multi.output view
@@ -8,6 +8,7 @@ w N S+!Commit to 'node' was made outside it Tb s n@@ -42,4 +43,3 @@ x I, w -!Commit to 'node' was made outside it
tests/ns-s-flow-map-entries.n=4.c=flow-in.single.output view
@@ -8,8 +8,8 @@ w N S+!Commit to 'node' was made outside it Tb s n x-!Commit to 'node' was made outside it
tests/ns-s-flow-seq-entries.n=4.c=flow-in.multi.output view
@@ -17,10 +17,10 @@ w N S+!Commit to 'node' was made outside it Td s n x m w -!Commit to 'node' was made outside it
tests/ns-tag-directive.invalid.output view
@@ -1,5 +1,5 @@ tTAG+!Commit to 'directive' was made outside it w H-!Commit to 'directive' was made outside it !$InputFile$: line 1: column 4: Unexpected 'a'
tests/ns-tag-directive.output view
@@ -1,4 +1,5 @@ tTAG+!Commit to 'directive' was made outside it w H I!@@ -10,4 +11,3 @@ I! tprefix g-!Commit to 'directive' was made outside it
tests/ns-yaml-directive.invalid.output view
@@ -1,4 +1,4 @@ tYAML-w !Commit to 'directive' was made outside it+w !$InputFile$: line 1: column 5: Unexpected 'a'
tests/ns-yaml-directive.output view
@@ -1,4 +1,4 @@ tYAML+!Commit to 'directive' was made outside it w t0.1-!Commit to 'directive' was made outside it
tests/s-b-double-escaped.output view
@@ -1,6 +1,6 @@ ? E I\x5c+!Commit to 'escape' was made outside it b\x0a e-!Commit to 'escape' was made outside it
tests/s-l+block-content.n=2.c=block-in.sequence.output view
@@ -2,12 +2,13 @@ Q i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a q-!Commit to 'node' was made outside it
tests/s-l+block-content.n=2.c=block-out.folded.output view
@@ -1,8 +1,8 @@ S I>+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s-!Commit to 'node' was made outside it
tests/s-l+block-content.n=2.c=block-out.literal.output view
@@ -1,9 +1,9 @@ w S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s-!Commit to 'node' was made outside it
tests/s-l+block-content.n=2.c=block-out.mapping.output view
@@ -8,13 +8,14 @@ s n I:+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Tb s n b\x0a x m-!Commit to 'node' was made outside it
tests/s-l+block-in-block.n=2.c=block-out.tagged.output view
@@ -11,10 +11,10 @@ w S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s n-!Commit to 'node' was made outside it
tests/s-l+block-in-block.n=2.c=block-out.untagged.output view
@@ -1,10 +1,10 @@ N S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s n-!Commit to 'node' was made outside it
tests/s-l+block-indented.n=2.c=block-in.sequence.output view
@@ -3,13 +3,14 @@ Q i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a q n-!Commit to 'node' was made outside it
tests/s-l+block-indented.n=2.c=block-out.literal.output view
@@ -2,10 +2,10 @@ w S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s n-!Commit to 'node' was made outside it
tests/s-l+block-indented.n=2.c=block-out.sequence.output view
@@ -3,13 +3,14 @@ Q i I-+!Commit to 'node' was made outside it w N S+!Commit to 'node' was made outside it Ta s n b\x0a q n-!Commit to 'node' was made outside it
tests/s-l+block-node.n=2.c=block-out.block.output view
@@ -1,10 +1,10 @@ N S I|+!Commit to 'node' was made outside it b\x0a i Ta L\x0a s n-!Commit to 'node' was made outside it
tests/s-l+block-node.n=2.c=block-out.flow.output view
@@ -1,7 +1,7 @@ N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/s-l+flow-in-block.n=2.output view
@@ -1,7 +1,7 @@ N S+!Commit to 'node' was made outside it Ta s n b\x0a-!Commit to 'node' was made outside it
tests/s-nb-folded-text.n=4.output view
@@ -1,3 +1,3 @@ i -?a !Commit to 'fold' was made outside it+?a
tests/s-nb-spaced-text.n=4.output view
@@ -1,3 +1,3 @@ i -? a !Commit to 'fold' was made outside it+? a
tests/s-ns-flow-map-explicit-empty.n=4.c=flow-in.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.json.output view
@@ -7,10 +7,10 @@ s n I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.value.output view
@@ -4,11 +4,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Ta s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/s-ns-flow-map-explicit-entry.n=4.c=flow-in.yaml.output view
@@ -5,11 +5,11 @@ s n I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/s-ns-flow-map-explicit-json.n=4.c=flow-in.output view
@@ -6,12 +6,12 @@ I" s n+!Commit to 'entry' was made outside it I:+!Commit to 'pair' was made outside it N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'entry' was made outside it-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
tests/s-ns-flow-map-explicit-yaml.n=4.c=flow-in.output view
@@ -4,13 +4,13 @@ Ta s n+!Commit to 'entry' was made outside it I:+!Commit to 'pair' was made outside it w N S+!Commit to 'node' was made outside it Tb s n-!Commit to 'entry' was made outside it-!Commit to 'pair' was made outside it-!Commit to 'node' was made outside it
yaml2yeast/Main.hs view
@@ -132,6 +132,8 @@ -- -- [@y@] Ends YAML stream --+-- [@!@] Parsing error at this point.+-- -- In addition, the following codes are used for testing partial productions -- and do not appear when parsing a complete YAML stream: --