packages feed

YamlReference-0.9: 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')

-- 5.2 Character Encodings

c_byte_order_mark {- 2 -} = '\xFEFF' & detect_utf_encoding

-- 5.3 Indicator Characters

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

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

c_comment        {- 11 -} = indicator '#'

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

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

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

c_directive      {- 19 -} = indicator '%'

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

c_indicator {- 21 -} = 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

-- 5.4 Line Break Characters

b_line_feed           {- 22 -} = '\xA'
b_carriage_return     {- 23 -} = '\xD'
b_next_line           {- 24 -} = '\x85'
b_line_separator      {- 25 -} = '\x2028'
b_paragraph_separator {- 26 -} = '\x2029'

b_char {- 27 -} = b_line_feed / b_carriage_return / b_next_line
                / b_line_separator / b_paragraph_separator

nb_char {- 28 -} = c_printable - b_char

b_specific {- 29 -} = ( b_line_separator / b_paragraph_separator )
                    & nextLine

b_generic {- 30 -} = ( b_carriage_return & b_line_feed
                     / b_carriage_return
                     / b_line_feed
                     / b_next_line )
                   & nextLine

b_as_line_feed {- 31 -} = token LineFeed b_generic
b_normalized   {- 32 -} = b_as_line_feed / token Break b_specific

b_non_content_generic {- 33 -} = token Continue b_generic

b_non_content_any {- 34 -} = b_non_content_generic / token Continue b_specific

-- 5.5 White Space Characters

s_space {- 35 -} = '\x20'
s_tab   {- 36 -} = '\x9'
s_white {- 37 -} = s_space / s_tab

ns_char {- 38 -} = nb_char - s_white

-- 5.6 Miscellaneous Characters

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

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

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

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

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

ns_tag_char {- 44 -} = ns_uri_char - c_tag

-- 5.7 Escaped Characters

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

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

c_ns_esc_char {- 65 -} = nest BeginEscape
              & 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_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 )
              & nest EndEscape

-- 6.1 Indentation Spaces

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

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

-- 6.2 Separation Spaces

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

-- 6.3 Line Prefixes

s_line_prefix n c {- 70 -} = 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 {- 71 -} = s_indent n
s_flow_line_prefix  n {- 72 -} = s_indent n & ( s_separate_in_line ?)

-- 6.4 Empty Lines

l_empty n c {- 73 -} = ( s_line_prefix n c / s_indent_lt n )
                     & b_normalized

-- 6.5 Comments

c_nb_comment_text {- 74 -} = nest BeginComment
                           & c_comment & meta ( nb_char *)
                           & nest EndComment

s_b_comment {- 75 -} = ( s_separate_in_line & ( c_nb_comment_text ?) ?)
                     & b_non_content_any

l_comment {- 76 -} = s_separate_in_line & ( c_nb_comment_text ?) & b_non_content_any

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

-- 6.6 Separation Lines

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

-- 6.7 Line Folding

b_l_folded_specific n c {- 80 -} = token Break b_specific & ( l_empty n c *)

b_l_folded_trimmed  n c {- 81 -} = b_non_content_generic & ( l_empty n c +)

b_l_folded_as_space {-  82 -} = token LineFold b_generic

b_l_folded_any n c  {-  83 -} = b_l_folded_specific n c
                              / b_l_folded_trimmed n c
                              / b_l_folded_as_space

s_l_flow_folded n {-  84 -} = ( s_separate_in_line ?) & b_l_folded_any n FlowIn

-- 6.8 Directives

l_directive {-  85 -} = nest BeginDirective
                      & c_directive
                      & "directive"
                      ^ ( ns_yaml_directive
                        / ns_tag_directive
                        / ns_reserved_directive )
                      & nest EndDirective
                      & s_l_comments

ns_reserved_directive  {-  86 -} = ns_directive_name
                                 & ( s_separate_in_line & ns_directive_parameter *)
ns_directive_name      {-  87 -} = meta ( ns_char +)
ns_directive_parameter {-  88 -} = meta ( ns_char +)

-- 6.8.1 Yaml Directives

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

-- 6.8.2 Tag Directives

ns_tag_directive {-  91 -} = 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 {-  92 -} = c_named_tag_handle
                       / c_secondary_tag_handle
                       / c_primary_tag_handle

c_primary_tag_handle   {-  93 -} = nest BeginHandle
                                 & c_tag
                                 & nest EndHandle

c_secondary_tag_handle {-  94 -} = nest BeginHandle
                                 & c_tag & c_tag
                                 & nest EndHandle

c_named_tag_handle     {-  95 -} = nest BeginHandle
                                 & c_tag & meta ( ns_word_char +) & c_tag
                                 & nest EndHandle

-- 6.8.2.2 Tag Prefixes

ns_tag_prefix {-  96 -} = nest BeginTag
                        & ( c_ns_local_tag_prefix / ns_global_tag_prefix )
                        & nest EndTag

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

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

-- 6.9 Node Properties

c_ns_properties n c {-  99 -} = nest BeginProperties
                              & ( ( c_ns_tag_property
                                  & ( s_separate n c & c_ns_anchor_property ?) )
                                / ( c_ns_anchor_property
                                  & ( s_separate n c & c_ns_tag_property ?) ) )
                              & nest EndProperties

-- 6.9.1 Node Tags

c_ns_tag_property {- 100 -} = nest BeginTag
                            & ( c_verbatim_tag
                              / c_ns_shorthand_tag
                              / c_non_specific_tag )
                            & nest EndTag

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

c_ns_shorthand_tag {- 102 -} = c_named_tag_handle & meta ( ns_uri_char +)
                             / c_secondary_tag_handle & meta ( ns_uri_char +)
                             / c_primary_tag_handle & meta ( ns_tag_char +)

c_non_specific_tag {- 103 -} = c_tag

-- 6.9.2 Node Anchors

c_ns_anchor_property {- 104 -} = nest BeginAnchor
                               & c_anchor & ns_anchor_name
                               & nest EndAnchor

ns_anchor_char {- 105 -} = ns_char - ( c_collect_entry / c_sequence_start / c_sequence_end / c_mapping_start  / c_mapping_end )
ns_anchor_name {- 106 -} = meta ( ns_anchor_char +)

-- 7.1 Alias Nodes

c_ns_alias_node {- 107 -} = nest BeginAlias
                          & c_alias ! "node" & ns_anchor_name
                          & nest EndAlias

-- 7.2 Empty Nodes

e_scalar {- 108 -} = nest BeginScalar & nest EndScalar

e_node {- 109 -} = nest BeginNode & e_scalar & nest EndNode

-- 7.3.1 Double Quoted Style

nb_double_char {- 110 -} = "escape" ^ ( nb_char - c_escape - c_double_quote / c_ns_esc_char )
ns_double_char {- 111 -} = nb_double_char - s_white

c_double_quoted n c {- 112 -} = nest BeginScalar
                              & c_double_quote ! "node" & text ( nb_double_text n c ) & c_double_quote
                              & nest EndScalar
nb_double_text n c  {- 113 -} = case c of
                                     FlowOut -> nb_double_multi_line n
                                     FlowIn  -> nb_double_multi_line n
                                     FlowKey -> nb_double_one_line
nb_double_one_line  {- 114 -} = ( nb_double_char *)

s_l_double_escaped n {- 115 -} = ( s_white *)
                               & nest BeginEscape
                               & c_escape ! "escape" & b_non_content_any
                               & nest EndEscape
                               & ( l_empty n FlowIn *)
s_l_double_any n     {- 116 -} = "escape" ^ ( s_l_double_escaped n / s_l_flow_folded n )

nb_ns_double_in_line    {- 117 -} = ( ( s_white *) & ns_double_char *)
s_ns_double_next_line n {- 118 -} = s_l_double_any n
                                  & s_flow_line_prefix n
                                  & ns_double_char & nb_ns_double_in_line
nb_double_multi_line n  {- 119 -} = nb_ns_double_in_line
                                  & ( s_ns_double_next_line n *)
                                  & ( s_white *)

-- 7.3.2 Single Quoted Style

c_quoted_quote {- 120 -} = nest BeginEscape
                         & c_single_quote ! "escape" & meta '\''
                         & nest EndEscape
nb_single_char {- 121 -} = "escape" ^ ( nb_char - c_single_quote / c_quoted_quote )
ns_single_char {- 122 -} = nb_single_char - s_white

c_single_quoted  n c {- 123 -}= nest BeginScalar
                              & c_single_quote & text ( nb_single_text n c ) & c_single_quote
                              & nest EndScalar
nb_single_text n c {- 124 -} = case c of
                                    FlowOut -> nb_single_multi_line n
                                    FlowIn  -> nb_single_multi_line n
                                    FlowKey -> nb_single_one_line
nb_single_one_line {- 125 -} = ( nb_single_char *)

nb_ns_single_in_line    {- 126 -} = ( ( s_white *) & ns_single_char *)
s_ns_single_next_line n {- 127 -} = s_l_flow_folded n
                                  & s_flow_line_prefix n
                                  & ns_single_char & nb_ns_single_in_line
nb_single_multi_line n  {- 128 -} = ( nb_ns_single_in_line *)
                                  & ( s_ns_single_next_line n *)
                                  & ( s_white *)

-- 7.3.3 Plain Style

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

ns_plain_safe c   {- 130 -} = case c of
                                   FlowOut -> ns_plain_safe_out
                                   FlowIn  -> ns_plain_safe_in
                                   FlowKey -> ns_plain_safe_in
ns_plain_safe_out {- 131 -} = ns_char - c_mapping_value - c_comment
ns_plain_safe_in   {- 132 -}= ns_plain_safe_out - ( c_collect_entry / c_sequence_start / c_sequence_end / c_mapping_start  / c_mapping_end )
ns_plain_char c   {- 133 -} = ns_plain_safe c
                            / ( ns_char <?) & '#'
                            / ':' & ( ns_char >?)
nb_plain_char c   {- 134 -} = s_white / ns_plain_char c

ns_plain n c          {- 135 -} = nest BeginScalar
                                & text (case c of
                                              FlowOut -> ns_plain_multi_line n c
                                              FlowIn  -> ns_plain_multi_line n c
                                              FlowKey -> ns_plain_one_line c)
                                & nest EndScalar
nb_ns_plain_in_line c {- 136 -} = ( ( s_white *) & ns_plain_char c *)
ns_plain_one_line c   {- 137 -} = ns_plain_first c ! "node" & nb_ns_plain_in_line c

s_ns_plain_next_line n c {- 138 -} = s_l_flow_folded n
                                   & s_flow_line_prefix n
                                   & ns_plain_char c & nb_ns_plain_in_line c
ns_plain_multi_line n c  {- 139 -} = ns_plain_one_line c & ( s_ns_plain_next_line n c *)

-- 7.4 Flow Collection Styles

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

-- 7.4.1 Flow Sequences

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

ns_s_flow_seq_entries n c {- 142 -} = 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 {- 143 -} = "pair" ^ ( ns_flow_pair n c / "node" ^ ns_flow_node n c )

-- 7.4.2 Flow Mappings

c_flow_mapping n c        {- 144 -} = nest BeginMapping
                                    & c_mapping_start ! "node" & ( s_separate n c ?)
                                    & ( ns_s_flow_map_entries n (in_flow c) ?) & c_mapping_end
                                    & nest EndMapping
ns_s_flow_map_entries n c {- 145 -} = 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 {- 146 -}          = nest BeginPair
                                         & "key" ^ ( c_mapping_key ! "key" & s_separate n c
                                                   & ns_flow_map_explicit_entry n c
                                         / ns_flow_map_implicit_entry n c )
                                         & nest EndPair
ns_flow_map_explicit_entry n c {- 147 -} = ns_flow_map_implicit_entry n c
                                         / e_node
                                         & e_node

ns_flow_map_implicit_entry n c {- 148 -}    = "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 {- 149 -}    = ( "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 {- 150 -} = e_node
                                            & c_ns_flow_map_separate_value n c
c_ns_flow_map_separate_value n c {- 151 -}  = c_mapping_value ! "pair"
                                            & ( s_separate n c & ns_flow_node n c
                                              / e_node )

c_ns_flow_map_json_key_entry n c {- 152 -} = ( "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 {- 153 -} = c_mapping_value ! "pair" & (   ( s_separate n c ?)
                                                                          & ns_flow_node n c
                                                                        / e_node )

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

ns_flow_pair_entry n c            {- 155 -} = "entry"
                                            ^ ( 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   {- 156 -} = ns_s_implicit_yaml_key
                                            & c_ns_flow_map_separate_value n c
c_ns_flow_pair_json_key_entry n c {- 157 -} = c_s_implicit_json_key
                                            & c_ns_flow_map_adjacent_value n c
ns_s_implicit_yaml_key            {- 158 -} = ( "node" ^ ( ns_flow_yaml_node na FlowKey )
                                              & ( s_separate_in_line ?) )
                                            `limitedTo` 1024
c_s_implicit_json_key             {- 159 -} = ( "node" ^ ( c_flow_json_node  na FlowKey )
                                              & ( s_separate_in_line ?) )
                                            `limitedTo` 1024

-- 7.5 Flow Nodes

ns_flow_yaml_content n c {- 160 -} = ns_plain n c
c_flow_json_content n c  {- 161 -} = 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      {- 162 -} = ns_flow_yaml_content n c / c_flow_json_content n c

ns_flow_yaml_node n c {- 163 -} = nest BeginNode
                                & ( 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 ) ) )
                                & nest EndNode
c_flow_json_node n c  {- 164 -} = nest BeginNode
                                & ( c_ns_properties n c & s_separate n c ?)
                                & c_flow_json_content n c
                                & nest EndNode
ns_flow_node n c      {- 165 -} = nest BeginNode
                                & ( 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 ) ) )
                                & nest EndNode

-- 8.1.1 Block Scalar Headers

c_b_block_header n {- 166 -} = "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 {- 167 -} = indicator ( ns_dec_digit - '0' ) & asInteger
                                    / detect_scalar_indentation n

detect_scalar_indentation n = peek $ ( nb_char *)
                                   & ( b_non_content_any & ( 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 {- 168 -} = indicator '-' & result Strip
                               / indicator '+' ! "header" & result Keep
                               / result Clip

b_chomped_last t {- 169 -} = case t of
                                  Strip -> nest EndScalar & b_non_content_any
                                  Clip  -> b_normalized & nest EndScalar
                                  Keep  -> b_normalized

l_chomped_empty n t {- 170 -} = case t of
                                     Strip -> l_strip_empty n
                                     Clip  -> l_strip_empty n
                                     Keep  -> l_keep_empty n
l_strip_empty n     {- 171 -} = ( s_indent_le n & b_non_content_any *)
                              & ( l_trail_comments n ?)
l_keep_empty n      {- 172 -} = ( l_empty n BlockIn *)
                              & nest EndScalar
                              & ( l_trail_comments n ?)

l_trail_comments n {- 173 -} = s_indent_lt n & c_nb_comment_text & b_non_content_any
                             & ( l_comment *)

-- 8.1.2 Literal Style

c_l__literal n {- 174 -} = do nest BeginScalar
                              indicator '|'
                              (m, t) <- c_b_block_header n
                              text ( l_literal_content (n .+ m) t )

l_nb_literal_text n   {- 175 -} = ( l_empty n BlockIn *)
                                & s_indent n & ( nb_char +)
b_nb_literal_next n   {- 176 -} = b_normalized
                                & l_nb_literal_text n
l_literal_content n t {- 177 -} = ( l_nb_literal_text n & ( b_nb_literal_next n *)
                                  & b_chomped_last t ?)
                                & l_chomped_empty n t

-- 8.1.3 Folded Style

c_l__folded n {- 178 -} = do nest BeginScalar
                             indicator '>'
                             (m, t) <- c_b_block_header n
                             text ( l_folded_content (n .+ m) t )

s_nb_folded_text n  {- 179 -} = s_indent n & ns_char ! "fold" & ( nb_char *)
l_nb_folded_lines n {- 180 -} = s_nb_folded_text n
                              & ( b_l_folded_any n BlockIn & s_nb_folded_text n *)

s_nb_spaced_text n  {- 181 -} = s_indent n & s_white ! "fold" & ( nb_char *)
b_l_spaced        n {- 182 -} = b_normalized
                              & ( l_empty n BlockIn *)
l_nb_spaced_lines n {- 183 -} = s_nb_spaced_text n
                              & ( b_l_spaced n & s_nb_spaced_text n *)

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

l_nb_diff_lines n {- 185 -} = l_nb_same_lines n
                            & ( b_normalized & l_nb_same_lines n *)

l_folded_content n t {- 186 -} = ( l_nb_diff_lines n & b_chomped_last t ?)
                               & l_chomped_empty n t

-- 8.2.1 Block Sequences

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

l__block_sequence n   {- 187 -} = do m  <- detect_collection_indentation n
                                     (   nest BeginSequence
                                       & ( s_indent (n .+ m) & c_l_block_seq_entry (n .+ m) +)
                                       & nest EndSequence )
c_l_block_seq_entry n {- 188 -} = c_sequence_entry ! "node" & s_l__block_indented n BlockIn

s_l__block_indented n c {- 189 -} = do m <- detect_inline_indentation
                                       (   s_indent m
                                         & "node"
                                         ^ ( 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
ns_l_in_line_sequence n {- 190 -} = nest BeginNode
                                  & nest BeginSequence
                                  & c_l_block_seq_entry n
                                  & ( s_indent n & c_l_block_seq_entry n *)
                                  & nest EndSequence
                                  & nest EndNode

-- 8.2.2 Block Mappings

l__block_mapping n = {- 191 -} do m <- detect_collection_indentation n
                                  (   nest BeginMapping
                                    & ( s_indent (n .+ m) & ns_l_block_map_entry (n .+ m) +)
                                    & nest EndMapping )

ns_l_block_map_entry n {- 192 -} = nest BeginPair
                                 & ( c_l_block_map_explicit_entry n
                                   / ns_l_block_map_implicit_entry n )
                                 & nest EndPair
c_l_block_map_explicit_entry n {- 193 -} = c_l_block_map_explicit_key n
                                         & ( l_block_map_explicit_value n
                                         / e_node )
c_l_block_map_explicit_key n   {- 194 -} = c_mapping_key ! "node" & s_l__block_indented n BlockOut
l_block_map_explicit_value n   {- 195 -} = s_indent n & c_mapping_value & s_l__block_indented n BlockOut

ns_l_block_map_implicit_entry n {- 196 -} = ( ns_s_block_map_implicit_key
                                            / e_node )
                                          & c_l_block_map_implicit_value n
ns_s_block_map_implicit_key     {- 197 -} = c_s_implicit_json_key / ns_s_implicit_yaml_key
c_l_block_map_implicit_value n  {- 198 -} = c_mapping_value ! "node" & ( s_l__block_node n BlockOut
                                                                     / e_node & s_l_comments )

ns_l_in_line_mapping n {-199 -} = nest BeginNode
                                 & nest BeginMapping
                                 & ns_l_block_map_entry n
                                 & ( s_indent n & ns_l_block_map_entry n *)
                                 & nest EndMapping
                                 & nest EndNode

-- 8.2.3 Block Nodes

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

s_l__block_in_block n c {- 202 -} = nest BeginNode
                                  & ( s_l__block_scalar n c / s_l__block_collection n c )
                                  & nest EndNode
s_l__block_scalar n c   {- 203 -} = 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 {- 204 -} = ( 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            {- 205 -} = case c of
                                           BlockOut -> n .- 1
                                           BlockIn  -> n

-- Document:

c_document_start {- 206 -} = token DocumentStart [ '-', '-', '-' ]
c_document_end   {- 207 -} = token DocumentEnd [ '.', '.', '.' ]
l_forbidden      {- 208 -} = sol
                           & ( c_document_start / c_document_end )
                            & ( b_char / s_white / eof )

l_document_prefix {- 209 -} = ( c_byte_order_mark ?) & ( l_comment *)
l_document_suffix {- 210 -} = c_document_end & s_l_comments

l_implicit_document {- 211 -} = nest BeginDocument
                              & s_l__block_node (-1) BlockIn
                                `forbidding` l_forbidden
                              & nest EndDocument
l_explicit_document {- 212 -} =  nest BeginDocument
                              & ( l_directive ! "doc" *)
                              & c_document_start ! "doc"
                              & "node" ^ ( l_implicit_document
                                         / e_node & s_l_comments )
                              & nest EndDocument

l_leading_document   {- 213 -} = l_document_prefix
                               & "doc" ^ ( l_explicit_document
                                         / "node" ^ ( l_implicit_document
                                                    / empty ) )
l_following_document {- 214 -} = l_document_prefix
                               & "doc" ^ ( l_explicit_document
                                         / empty )

-- Stream:

l_documents   {- 215 -} = l_leading_document
                        & ( l_following_document *)
l_yaml_stream {- 216 -} = nest BeginStream
                        & l_documents
                        & ( l_document_suffix & l_documents *)
                        & nest EndStream