packages feed

YamlReference-0.9.3: Text/Yaml/Reference.bnf

-- ** Spec productions
--
-- These are copied directly from the spec, with the sprinkling of
-- additional token and decision point directives.

-- 5.1 Character Set

c_printable {- 1 -} = '\x9' / '\xA' / '\xD' / ('\x20', '\x7E')
                    / '\x85' / ('\xA0', '\xD7FF') / ('\xE000', '\xFFFD')
                    / ('\x10000', '\x10FFFF')

nb_json {- 2 -} = '\x9' / ('\x20', '\x10FFFF')

-- 5.2 Character Encodings

c_byte_order_mark {- 3 -} = bom '\xFEFF'

-- 5.3 Indicator Characters

c_sequence_entry {-  4 -} = indicator '-'
c_mapping_key    {-  5 -} = indicator '?'
c_mapping_value  {-  6 -} = indicator ':'

c_collect_entry  {-  7 -} = indicator ','
c_sequence_start {-  8 -} = indicator '['
c_sequence_end   {-  9 -} = indicator ']'
c_mapping_start  {- 10 -} = indicator '{'
c_mapping_end    {- 11 -} = indicator '}'

c_comment        {- 12 -} = indicator '#'

c_anchor         {- 13 -} = indicator '&'
c_alias          {- 14 -} = indicator '*'
c_tag            {- 15 -} = indicator '!'

c_literal        {- 16 -} = indicator '|'
c_folded         {- 17 -} = indicator '>'

c_single_quote   {- 18 -} = indicator '\''
c_double_quote   {- 19 -} = indicator '"'

c_directive      {- 20 -} = indicator '%'

c_reserved       {- 21 -} = indicator ( '@' /  '`' )

c_indicator {- 22 -} = c_sequence_entry / c_mapping_key / c_mapping_value / c_collect_entry
                     / c_sequence_start / c_sequence_end / c_mapping_start / c_mapping_end
                     / c_comment / c_anchor / c_alias / c_tag
                     / c_literal / c_folded / c_single_quote / c_double_quote
                     / c_directive / c_reserved

c_flow_indicator {- 23 -} = c_collect_entry / c_sequence_start / c_sequence_end / c_mapping_start / c_mapping_end

-- 5.4 Line Break Characters

b_line_feed       {- 24 -} = '\xA'
b_carriage_return {- 25 -} = '\xD'
b_char            {- 26 -} = b_line_feed / b_carriage_return

nb_char {- 27 -} = c_printable - b_char - c_byte_order_mark

b_break {- 28 -} = ( b_carriage_return & b_line_feed
                   / b_carriage_return
                   / b_line_feed )
                 & nextLine

b_as_line_feed {- 29 -} = token LineFeed b_break

b_non_content {- 30 -} = token Break b_break

-- 5.5 White Space Characters

s_space {- 31 -} = '\x20'
s_tab   {- 32 -} = '\x9'
s_white {- 33 -} = s_space / s_tab

ns_char {- 34 -} = nb_char - s_white

-- 5.6 Miscellaneous Characters

ns_dec_digit {- 35 -} = ('\x30', '\x39')

ns_hex_digit {- 36 -} = ns_dec_digit
                      / ('\x41', '\x46') / ('\x61', '\x66')

ns_ascii_letter {- 37 -} = ('\x41', '\x5A') / ('\x61', '\x7A')

ns_word_char {- 38 -} = ns_dec_digit / ns_ascii_letter / '-'

ns_uri_char {- 39 -} = "escape"
                     ^ ( '%' ! "escape" & ns_hex_digit & ns_hex_digit / ns_word_char / '#'
                       / ';' / '/' / '?' / ':' / '@' / '&'  / '=' / '+' / '$' / ','
                       / '_' / '.' / '!' / '~' / '*' / '\'' / '(' / ')' / '[' / ']' )

ns_tag_char {- 40 -} = ns_uri_char - c_tag - c_flow_indicator

-- 5.7 Escaped Characters

c_escape {- 41 -} = indicator '\\'

ns_esc_null                {- 42 -} = meta '0'
ns_esc_bell                {- 43 -} = meta 'a'
ns_esc_backspace           {- 44 -} = meta 'b'
ns_esc_horizontal_tab      {- 45 -} = meta ( 't' / '\x9' )
ns_esc_line_feed           {- 46 -} = meta 'n'
ns_esc_vertical_tab        {- 47 -} = meta 'v'
ns_esc_form_feed           {- 48 -} = meta 'f'
ns_esc_carriage_return     {- 49 -} = meta 'r'
ns_esc_escape              {- 50 -} = meta 'e'
ns_esc_space               {- 51 -} = meta '\x20'
ns_esc_double_quote        {- 52 -} = meta '"'
ns_esc_slash               {- 53 -} = meta '/'
ns_esc_backslash           {- 54 -} = meta '\\'
ns_esc_next_line           {- 55 -} = meta 'N'
ns_esc_non_breaking_space  {- 56 -} = meta '_'
ns_esc_line_separator      {- 57 -} = meta 'L'
ns_esc_paragraph_separator {- 58 -} = meta 'P'
ns_esc_8_bit               {- 59 -} = indicator 'x' ! "escaped" & meta ( ns_hex_digit % 2 )
ns_esc_16_bit              {- 60 -} = indicator 'u' ! "escaped" & meta ( ns_hex_digit % 4 )
ns_esc_32_bit              {- 61 -} = indicator 'U' ! "escaped" & meta ( ns_hex_digit % 8 )

c_ns_esc_char {- 62 -} = wrapTokens BeginEscape EndEscape
                       $ c_escape ! "escape"
                       & "escaped"
                       ^ ( ns_esc_null / ns_esc_bell / ns_esc_backspace
                         / ns_esc_horizontal_tab / ns_esc_line_feed
                         / ns_esc_vertical_tab / ns_esc_form_feed
                         / ns_esc_carriage_return / ns_esc_escape / ns_esc_space
                         / ns_esc_double_quote / ns_esc_slash / ns_esc_backslash
                         / ns_esc_next_line / ns_esc_non_breaking_space
                         / ns_esc_line_separator / ns_esc_paragraph_separator
                         / ns_esc_8_bit / ns_esc_16_bit / ns_esc_32_bit )

-- 6.1 Indentation Spaces

s_indent    n {- 63 -} = token Indent ( s_space % n )

s_indent_lt n {- 64 -} = token Indent ( s_space <% n )
s_indent_le n {- 65 -} = token Indent ( s_space <% (n .+ 1) )

-- 6.2 Separation Spaces

s_separate_in_line {- 66 -} = token White ( s_white +) / sol

-- 6.3 Line Prefixes

s_line_prefix n c {- 67 -} = case c of
                                  BlockOut -> s_block_line_prefix n
                                  BlockIn  -> s_block_line_prefix n
                                  FlowOut  -> s_flow_line_prefix n
                                  FlowIn   -> s_flow_line_prefix n

s_block_line_prefix n {- 68 -} = s_indent n
s_flow_line_prefix  n {- 69 -} = s_indent n & ( s_separate_in_line ?)

-- 6.4 Empty Lines

l_empty n c {- 70 -} = ( s_line_prefix n c / s_indent_lt n )
                     & b_as_line_feed

-- 6.5 Line Folding

b_l_trimmed  n c {- 71 -} = b_non_content & ( l_empty n c +)

b_as_space {- 72 -} = token LineFold b_break

b_l_folded n c  {- 73 -} = b_l_trimmed n c / b_as_space

s_flow_folded n {- 74 -} = ( s_separate_in_line ?) & b_l_folded n FlowIn
                         & s_flow_line_prefix n

-- 6.6 Comments

c_nb_comment_text {- 75 -} = wrapTokens BeginComment EndComment
                           $ c_comment & meta ( nb_char *)

b_comment {- 76 -} = b_non_content / eof

s_b_comment {- 77 -} = ( s_separate_in_line & ( c_nb_comment_text ?) ?)
                     & b_comment

l_comment {- 78 -} = s_separate_in_line & ( c_nb_comment_text ?) & b_comment

s_l_comments {- 79 -} = ( s_b_comment / sol )
                      & ( nonEmpty l_comment *)

-- 6.7 Separation Lines

s_separate n c      {- 80 -} = case c of
                                    BlockOut -> s_separate_lines n
                                    BlockIn  -> s_separate_lines n
                                    FlowOut  -> s_separate_lines n
                                    FlowIn   -> s_separate_lines n
                                    BlockKey -> s_separate_in_line
                                    FlowKey  -> s_separate_in_line
s_separate_lines n {- 81 -} = s_l_comments & s_flow_line_prefix n
                            / s_separate_in_line

-- 6.8 Directives

l_directive {- 82 -} = ( wrapTokens BeginDirective EndDirective
                       $ c_directive ! "doc"
                       & "directive"
                       ^ ( ns_yaml_directive
                         / ns_tag_directive
                         / ns_reserved_directive ) )
                     & s_l_comments

ns_reserved_directive  {- 83 -} = ns_directive_name
                                & ( s_separate_in_line & ns_directive_parameter *)
ns_directive_name      {- 84 -} = meta ( ns_char +)
ns_directive_parameter {- 85 -} = meta ( ns_char +)

-- 6.8.1 Yaml Directives

ns_yaml_directive {- 86 -} = meta [ 'Y', 'A', 'M', 'L' ] ! "directive"
                           & s_separate_in_line & ns_yaml_version
ns_yaml_version   {- 87 -} = meta ( ( ns_dec_digit +) & '.' & ( ns_dec_digit +) )

-- 6.8.2 Tag Directives

ns_tag_directive {- 88 -} = meta [ 'T', 'A', 'G' ] ! "directive"
                          & s_separate_in_line & c_tag_handle
                          & s_separate_in_line & ns_tag_prefix

-- 6.8.2.1 Tag Handles

c_tag_handle {- 89 -} = c_named_tag_handle
                      / c_secondary_tag_handle
                      / c_primary_tag_handle

c_primary_tag_handle   {- 90 -} = wrapTokens BeginHandle EndHandle
                                $ c_tag

c_secondary_tag_handle {- 91 -} = wrapTokens BeginHandle EndHandle
                                $ c_tag & c_tag

c_named_tag_handle     {- 92 -} = wrapTokens BeginHandle EndHandle
                                $ c_tag & meta ( ns_word_char +) & c_tag

-- 6.8.2.2 Tag Prefixes

ns_tag_prefix {- 93 -} = wrapTokens BeginTag EndTag
                       $ ( c_ns_local_tag_prefix / ns_global_tag_prefix )

c_ns_local_tag_prefix {- 94 -} = c_tag & meta ( ns_uri_char *)

ns_global_tag_prefix  {- 95 -} = meta ( ns_tag_char & ( ns_uri_char *) )

-- 6.9 Node Properties

c_ns_properties n c {- 96 -} = wrapTokens BeginProperties EndProperties
                             $ ( c_ns_tag_property
                               & ( s_separate n c & c_ns_anchor_property ?) )
                             / ( c_ns_anchor_property
                               & ( s_separate n c & c_ns_tag_property ?) )

-- 6.9.1 Node Tags

c_ns_tag_property {- 97 -} = wrapTokens BeginTag EndTag
                           $ c_verbatim_tag
                           / c_ns_shorthand_tag
                           / c_non_specific_tag

c_verbatim_tag     {- 98 -} = c_tag & indicator '<' & meta ( ns_uri_char +) & indicator '>'

c_ns_shorthand_tag {- 99 -} = c_tag_handle & meta ( ns_tag_char +)

c_non_specific_tag {- 100 -} = c_tag

-- 6.9.2 Node Anchors

c_ns_anchor_property {- 101 -} = wrapTokens BeginAnchor EndAnchor
                               $ c_anchor & ns_anchor_name

ns_anchor_char {- 102 -} = ns_char - c_flow_indicator
ns_anchor_name {- 103 -} = meta ( ns_anchor_char +)

-- 7.1 Alias Nodes

c_ns_alias_node {- 104 -} = wrapTokens BeginAlias EndAlias
                          $ c_alias ! "node" & ns_anchor_name

-- 7.2 Empty Nodes

e_scalar {- 105 -} = wrapTokens BeginScalar EndScalar empty

e_node {- 106 -} = wrapTokens BeginNode EndNode e_scalar

-- 7.3.1 Double Quoted Style

nb_double_char {- 107 -} = "escape" ^ ( c_ns_esc_char / ( nb_json - c_escape - c_double_quote ) )
ns_double_char {- 108 -} = nb_double_char - s_white

c_double_quoted n c {- 109 -} = wrapTokens BeginScalar EndScalar
                              $ c_double_quote ! "node" & text ( nb_double_text n c ) & c_double_quote
nb_double_text n c  {- 110 -} = case c of
                                     FlowOut  -> nb_double_multi_line n
                                     FlowIn   -> nb_double_multi_line n
                                     BlockKey -> nb_double_one_line
                                     FlowKey  -> nb_double_one_line
nb_double_one_line  {- 111 -} = ( nb_double_char *)

s_double_escaped n {- 112 -} = ( s_white *)
                             & wrapTokens BeginEscape EndEscape ( c_escape ! "escape" & b_non_content )
                             & ( l_empty n FlowIn *)
                             & s_flow_line_prefix n
s_double_break n   {- 113 -} = "escape" ^ ( s_double_escaped n / s_flow_folded n )

nb_ns_double_in_line    {- 114 -} = ( ( s_white *) & ns_double_char *)
s_double_next_line n {- 115 -} = s_double_break n
                               & ( ns_double_char & nb_ns_double_in_line
                                 & ( s_double_next_line n / ( s_white *) ) ?)
nb_double_multi_line n  {- 116 -} = nb_ns_double_in_line
                                  & ( s_double_next_line n / ( s_white *) )

-- 7.3.2 Single Quoted Style

c_quoted_quote {- 117 -} = wrapTokens BeginEscape EndEscape
                         $ c_single_quote ! "escape" & meta '\''
nb_single_char {- 118 -} = "escape" ^ ( c_quoted_quote / ( nb_json - c_single_quote ) )
ns_single_char {- 119 -} = nb_single_char - s_white

c_single_quoted  n c {- 120 -} = wrapTokens BeginScalar EndScalar
                               $ c_single_quote ! "node" & text ( nb_single_text n c ) & c_single_quote
nb_single_text n c {- 121 -} = case c of
                                    FlowOut  -> nb_single_multi_line n
                                    FlowIn   -> nb_single_multi_line n
                                    BlockKey -> nb_single_one_line
                                    FlowKey  -> nb_single_one_line
nb_single_one_line {- 122 -} = ( nb_single_char *)

nb_ns_single_in_line    {- 123 -} = ( ( s_white *) & ns_single_char *)
s_single_next_line n {- 124 -} = s_flow_folded n
                                 & ( ns_single_char & nb_ns_single_in_line
                                    & ( s_single_next_line n / ( s_white *) ) ?)
nb_single_multi_line n  {- 125 -} = nb_ns_single_in_line
                                  & ( s_single_next_line n / ( s_white *) )

-- 7.3.3 Plain Style

ns_plain_first c  {- 126 -} = ns_char - c_indicator
                            / ( ':' / '?' / '-' ) & ( ns_char >?)

ns_plain_safe c   {- 127 -} = case c of
                                   FlowOut  -> ns_plain_safe_out
                                   FlowIn   -> ns_plain_safe_in
                                   BlockKey -> ns_plain_safe_out
                                   FlowKey  -> ns_plain_safe_in
ns_plain_safe_out {- 128 -} = ns_char - c_mapping_value - c_comment
ns_plain_safe_in  {- 129 -} = ns_plain_safe_out - c_flow_indicator
ns_plain_char c   {- 130 -} = ns_plain_safe c
                            / ( ns_char <?) & '#'
                            / ':' & ( ns_char >?)

ns_plain n c          {- 131 -} = wrapTokens BeginScalar EndScalar
                                $ text (case c of
                                             FlowOut  -> ns_plain_multi_line n c
                                             FlowIn   -> ns_plain_multi_line n c
                                             BlockKey -> ns_plain_one_line c
                                             FlowKey  -> ns_plain_one_line c)
nb_ns_plain_in_line c {- 132 -} = ( ( s_white *) & ns_plain_char c *)
ns_plain_one_line c   {- 133 -} = ns_plain_first c ! "node" & nb_ns_plain_in_line c

s_ns_plain_next_line n c {- 134 -} = s_flow_folded n
                                   & ns_plain_char c & nb_ns_plain_in_line c
ns_plain_multi_line n c  {- 135 -} = ns_plain_one_line c
                                   & ( s_ns_plain_next_line n c *)

-- 7.4 Flow Collection Styles

in_flow c {- 136 -} = case c of
                           FlowOut  -> FlowIn
                           FlowIn   -> FlowIn
                           BlockKey -> FlowKey
                           FlowKey  -> FlowKey

-- 7.4.1 Flow Sequences

c_flow_sequence n c {- 137 -} = wrapTokens BeginSequence EndSequence
                              $ c_sequence_start ! "node" & ( s_separate n c ?)
                              & ( ns_s_flow_seq_entries n (in_flow c) ?) & c_sequence_end

ns_s_flow_seq_entries n c {- 138 -} = ns_flow_seq_entry n c & ( s_separate n c ?)
                                    & ( c_collect_entry & ( s_separate n c ?)
                                      & ( ns_s_flow_seq_entries n c ?) ?)

ns_flow_seq_entry n c {- 139 -} = "pair" ^ ( ns_flow_pair n c / "node" ^ ns_flow_node n c )

-- 7.4.2 Flow Mappings

c_flow_mapping n c        {- 140 -} = wrapTokens BeginMapping EndMapping
                                    $ c_mapping_start ! "node" & ( s_separate n c ?)
                                    & ( ns_s_flow_map_entries n (in_flow c) ?) & c_mapping_end
ns_s_flow_map_entries n c {- 141 -} = ns_flow_map_entry n c & ( s_separate n c ?)
                                    & ( c_collect_entry & ( s_separate n c ?)
                                      & ( ns_s_flow_map_entries n c ?) ?)

ns_flow_map_entry n c {- 142 -}          = wrapTokens BeginPair EndPair
                                         $ "key" ^ ( ( c_mapping_key ! "key" & s_separate n c
                                                     & ns_flow_map_explicit_entry n c )
                                                   / ns_flow_map_implicit_entry n c )
ns_flow_map_explicit_entry n c {- 143 -} = ns_flow_map_implicit_entry n c
                                         / ( e_node
                                           & e_node )

ns_flow_map_implicit_entry n c {- 144 -}    = "pair"
                                            ^ ( ns_flow_map_yaml_key_entry n c
                                              / c_ns_flow_map_empty_key_entry n c
                                              / c_ns_flow_map_json_key_entry n c )
ns_flow_map_yaml_key_entry n c {- 145 -}    = ( "node" ^ ns_flow_yaml_node n c ) ! "pair"
                                            & ( ( ( s_separate n c ?)
                                                & c_ns_flow_map_separate_value n c )
                                              / e_node )
c_ns_flow_map_empty_key_entry n c {- 146 -} = e_node
                                            & c_ns_flow_map_separate_value n c

c_ns_flow_map_separate_value n c {- 147 -}  = c_mapping_value & ( ns_char >!) ! "pair"
                                            & ( ( s_separate n c & ns_flow_node n c )
                                              / e_node )

c_ns_flow_map_json_key_entry n c {- 148 -} = ( "node" ^ c_flow_json_node n c ) ! "pair"
                                           & ( ( ( s_separate n c ?)
                                               & c_ns_flow_map_adjacent_value n c )
                                             / e_node )
c_ns_flow_map_adjacent_value n c {- 149 -} = c_mapping_value ! "pair"
                                           & ( ( ( s_separate n c ?)
                                               & ns_flow_node n c )
                                               / e_node )

ns_flow_pair n c {- 150 -} = wrapTokens BeginMapping EndMapping
                           $ wrapTokens BeginPair EndPair
                           $ ( ( c_mapping_key ! "pair" & s_separate n c
                               & ns_flow_map_explicit_entry n c )
                             / ns_flow_pair_entry n c )

ns_flow_pair_entry n c            {- 151 -} = ( ns_flow_pair_yaml_key_entry n c
                                              / c_ns_flow_map_empty_key_entry n c
                                              / c_ns_flow_pair_json_key_entry n c )
ns_flow_pair_yaml_key_entry n c   {- 152 -} = ns_s_implicit_yaml_key FlowKey
                                            & c_ns_flow_map_separate_value n c
c_ns_flow_pair_json_key_entry n c {- 153 -} = c_s_implicit_json_key FlowKey
                                            & c_ns_flow_map_adjacent_value n c
ns_s_implicit_yaml_key c          {- 154 -} = ( "node" ^ ( ns_flow_yaml_node na c ) & ( s_separate_in_line ?) )
                                            `limitedTo` 1024
c_s_implicit_json_key c           {- 155 -} = ( "node" ^ ( c_flow_json_node  na c ) & ( s_separate_in_line ?) )
                                            `limitedTo` 1024

-- 7.5 Flow Nodes

ns_flow_yaml_content n c {- 156 -} = ns_plain n c
c_flow_json_content n c  {- 157 -} = c_flow_sequence n c / c_flow_mapping n c
                                   / c_single_quoted n c / c_double_quoted n c
ns_flow_content n c      {- 158 -} = ns_flow_yaml_content n c / c_flow_json_content n c

ns_flow_yaml_node n c {- 159 -} = wrapTokens BeginNode EndNode
                                $ c_ns_alias_node
                                / ns_flow_yaml_content n c
                                / ( c_ns_properties n c
                                  & ( ( s_separate n c & ns_flow_yaml_content n c )
                                    / e_scalar ) )
c_flow_json_node n c  {- 160 -} = wrapTokens BeginNode EndNode
                                $ ( c_ns_properties n c & s_separate n c ?)
                                & c_flow_json_content n c
ns_flow_node n c      {- 161 -} = wrapTokens BeginNode EndNode
                                $ c_ns_alias_node
                                / ns_flow_content n c
                                / ( c_ns_properties n c
                                  & ( ( s_separate n c & ns_flow_content n c )
                                    / e_scalar ) )

-- 8.1.1 Block Scalar Headers

c_b_block_header n {- 162 -} = "header"
                             ^ ( do m <- c_indentation_indicator n
                                    t <- c_chomping_indicator
                                    ( s_white / b_char ) ?! "header"
                                    s_b_comment
                                    result (m, t)
                               / do t <- c_chomping_indicator
                                    m <- c_indentation_indicator n
                                    s_b_comment
                                    result (m, t) )

-- 8.1.1.1 Block Indentation Indicator

c_indentation_indicator n {- 163 -} = indicator ( ns_dec_digit - '0' ) & asInteger
                                    / detect_scalar_indentation n

detect_scalar_indentation n = peek $ ( nb_char *)
                                   & ( b_non_content & ( l_empty n BlockIn *) ?)
                                   & count_spaces (-n)

count_spaces n  = (s_space & count_spaces (n .+ 1))
                / result (max 1 n)

-- 8.1.1.2 Chomping Indicator

c_chomping_indicator {- 164 -} = indicator '-' & result Strip
                               / indicator '+' & result Keep
                               / result Clip

end_block_scalar t = case t of
                          Strip -> emptyToken EndScalar
                          Clip  -> emptyToken EndScalar
                          Keep  -> empty

b_chomped_last t {- 165 -} = case t of
                                  Strip -> emptyToken EndScalar & b_non_content
                                  Clip  -> b_as_line_feed & emptyToken EndScalar
                                  Keep  -> b_as_line_feed

l_chomped_empty n t {- 166 -} = case t of
                                     Strip -> l_strip_empty n
                                     Clip  -> l_strip_empty n
                                     Keep  -> l_keep_empty n
l_strip_empty n     {- 167 -} = ( s_indent_le n & b_non_content *)
                              & ( l_trail_comments n ?)
l_keep_empty n      {- 168 -} = ( l_empty n BlockIn *)
                              & emptyToken EndScalar
                              & ( l_trail_comments n ?)

l_trail_comments n {- 169 -} = s_indent_lt n & c_nb_comment_text & b_comment
                             & ( nonEmpty l_comment *)

-- 8.1.2 Literal Style

c_l__literal n {- 170 -} = do emptyToken BeginScalar
                              c_literal ! "node"
                              (m, t) <- c_b_block_header n `prefixErrorWith` emptyToken EndScalar
                              text ( l_literal_content (n .+ m) t )

l_nb_literal_text n   {- 171 -} = ( l_empty n BlockIn *)
                                & s_indent n & ( nb_char +)
b_nb_literal_next n   {- 172 -} = b_as_line_feed
                                & l_nb_literal_text n
l_literal_content n t {- 173 -} = ( ( l_nb_literal_text n & ( b_nb_literal_next n *) & b_chomped_last t )
                                  / end_block_scalar t )
                                & l_chomped_empty n t

-- 8.1.3 Folded Style

c_l__folded n {- 174 -} = do emptyToken BeginScalar
                             c_folded ! "node"
                             (m, t) <- c_b_block_header n `prefixErrorWith` emptyToken EndScalar
                             text ( l_folded_content (n .+ m) t )

s_nb_folded_text n  {- 175 -} = s_indent n & ns_char ! "fold" & ( nb_char *)
l_nb_folded_lines n {- 176 -} = s_nb_folded_text n
                              & ( b_l_folded n BlockIn & s_nb_folded_text n *)

s_nb_spaced_text n  {- 177 -} = s_indent n & s_white ! "fold" & ( nb_char *)
b_l_spaced        n {- 178 -} = b_as_line_feed
                              & ( l_empty n BlockIn *)
l_nb_spaced_lines n {- 179 -} = s_nb_spaced_text n
                              & ( b_l_spaced n & s_nb_spaced_text n *)

l_nb_same_lines n {- 180 -} = ( l_empty n BlockIn *)
                            & "fold" ^ ( l_nb_folded_lines n / l_nb_spaced_lines n )

l_nb_diff_lines n {- 181 -} = l_nb_same_lines n
                            & ( b_as_line_feed & l_nb_same_lines n *)

l_folded_content n t {- 182 -} = ( ( l_nb_diff_lines n & b_chomped_last t )
                                 / end_block_scalar t )
                               & l_chomped_empty n t

-- 8.2.1 Block Sequences

detect_collection_indentation n = peek $ ( nonEmpty l_comment* ) & count_spaces (-n)
detect_inline_indentation       = peek $ count_spaces 0

l__block_sequence n   {- 183 -} = do m  <- detect_collection_indentation n
                                     wrapTokens BeginSequence EndSequence $ ( s_indent (n .+ m) & c_l_block_seq_entry (n .+ m) +)
c_l_block_seq_entry n {- 184 -} = c_sequence_entry & ( ns_char >!) ! "node"
                                & s_l__block_indented n BlockIn

s_l__block_indented n c {- 185 -} = do m <- detect_inline_indentation
                                       "node" ^ ( ( s_indent m
                                                  & ( ns_l_in_line_sequence (n .+ 1 .+ m)
                                                    / ns_l_in_line_mapping (n .+ 1 .+ m) ) )
                                                / s_l__block_node n c
                                                / ( e_node & ( s_l_comments ?) & unparsed (n .+ 1) ) ) `recovery` unparsed (n .+ 1)
ns_l_in_line_sequence n {- 186 -} = wrapTokens BeginNode EndNode
                                  $ wrapTokens BeginSequence EndSequence
                                  $ c_l_block_seq_entry n
                                  & ( s_indent n & c_l_block_seq_entry n *)

-- 8.2.2 Block Mappings

l__block_mapping n = {- 187 -} do m <- detect_collection_indentation n
                                  wrapTokens BeginMapping EndMapping $ ( s_indent (n .+ m) & ns_l_block_map_entry (n .+ m) +)

ns_l_block_map_entry n {- 188 -} = wrapTokens BeginPair EndPair
                                 $ c_l_block_map_explicit_entry n
                                 / ns_l_block_map_implicit_entry n
c_l_block_map_explicit_entry n {- 189 -} = c_l_block_map_explicit_key n
                                         & ( l_block_map_explicit_value n
                                         / e_node )
c_l_block_map_explicit_key n   {- 190 -} = c_mapping_key ! "node" & s_l__block_indented n BlockOut
l_block_map_explicit_value n   {- 191 -} = s_indent n & c_mapping_value & s_l__block_indented n BlockOut

ns_l_block_map_implicit_entry n {- 192 -} = ( ns_s_block_map_implicit_key
                                            / e_node )
                                          & c_l_block_map_implicit_value n
ns_s_block_map_implicit_key     {- 193 -} = c_s_implicit_json_key BlockKey
                                          / ns_s_implicit_yaml_key BlockKey

c_l_block_map_implicit_value n  {- 194 -} = c_mapping_value ! "node"
                                          & ( ( s_l__block_node n BlockOut
                                              / ( e_node & ( s_l_comments ?) & unparsed (n .+ 1) ) ) `recovery` unparsed (n .+ 1) )

ns_l_in_line_mapping n {- 195 -} = wrapTokens BeginNode EndNode
                                 $ wrapTokens BeginMapping EndMapping
                                 $ ns_l_block_map_entry n
                                 & ( s_indent n & ns_l_block_map_entry n *)

-- 8.2.3 Block Nodes

unparsed n = ( sol / unparsed_text & unparsed_break )
           & ( nonEmpty ( unparsed_indent n & unparsed_text & unparsed_break ) *)
unparsed_indent n = token Unparsed ( s_space % n )
unparsed_text = token Unparsed ( upto ( eof / c_forbidden / b_break ) )
unparsed_break = eof / peek c_forbidden / token Unparsed b_break / empty

s_l__block_node n c  {- 196 -} = s_l__block_in_block n c / s_l__flow_in_block n
s_l__flow_in_block n {- 197 -} = s_separate (n .+ 1) FlowOut
                               & ns_flow_node (n .+ 1) FlowOut & s_l_comments

s_l__block_in_block n c {- 198 -} = wrapTokens BeginNode EndNode
                                  $ ( s_l__block_scalar n c / s_l__block_collection n c )
s_l__block_scalar n c   {- 199 -} = s_separate (n .+ 1) c
                                  & ( c_ns_properties (n .+ 1) c & s_separate (n .+ 1) c ?)
                                  & ( c_l__literal n / c_l__folded n )

s_l__block_collection n c {- 200 -} = ( s_separate (n .+ 1) c & c_ns_properties (n .+ 1) c & ( s_l_comments >?) ?)
                                    & s_l_comments
                                    & ( l__block_sequence (seq_spaces n c)
                                      / l__block_mapping n )
seq_spaces n c            {- 201 -} = case c of
                                           BlockOut -> n .- 1
                                           BlockIn  -> n

-- 9.1.1 Document Prefix

l_document_prefix {- 202 -} = ( c_byte_order_mark ?) & ( nonEmpty l_comment *)

-- 9.1.2 Document Markers

c_directives_end  {- 203 -} = token DirectivesEnd [ '-', '-', '-' ]
c_document_end    {- 204 -} = token DocumentEnd [ '.', '.', '.' ]
l_document_suffix {- 205 -} = c_document_end & s_l_comments
c_forbidden       {- 206 -} = sol
                            & ( c_directives_end / c_document_end )
                            & ( b_char / s_white / eof )

-- 9.1.3 Explicit Documents

l_bare_document {- 207 -} = "node" ^ s_l__block_node (-1) BlockIn
                            `forbidding` c_forbidden

-- 9.1.4 Explicit Documents

l_explicit_document {- 208 -} = c_directives_end ! "doc"
                              & ( ( l_bare_document
                                  / e_node & ( s_l_comments ?) & unparsed 0 ) `recovery` unparsed 0 )

-- 9.1.5 Directives Documents

l_directives_document {- 209 -} = ( l_directive +)
                                & l_explicit_document

-- 9.2 Streams:

l_any_document   {- 210 -} = wrapTokens BeginDocument EndDocument
                           $ "doc" ^ ( l_directives_document
                                     / l_explicit_document
                                     / l_bare_document ) `recovery` unparsed 0

l_yaml_stream {- 211 -} = ( nonEmpty l_document_prefix *)
                        & ( eof / ( c_document_end & ( b_char / s_white / eof ) >?) / l_any_document )
                        & ( nonEmpty ( "more" ^ ( ( l_document_suffix ! "more" +) & ( nonEmpty l_document_prefix *) & ( eof / l_any_document )
                                                / ( nonEmpty l_document_prefix *) & "doc" ^ ( wrapTokens BeginDocument EndDocument l_explicit_document ?) ) ) *)