diff --git a/test/test_files/basic_yaml_block.yaml b/test/test_files/basic_yaml_block.yaml index 632feafc..aa536c38 100644 --- a/test/test_files/basic_yaml_block.yaml +++ b/test/test_files/basic_yaml_block.yaml @@ -2,7 +2,7 @@ - Boston Red Sox - Detroit Tigers - New York - Yankees + Yankees national: - New York Mets - Chicago Cubs diff --git a/yaml/parser/scalar.hpp b/yaml/parser/scalar.hpp index 6796c318..b886a949 100644 --- a/yaml/parser/scalar.hpp +++ b/yaml/parser/scalar.hpp @@ -36,6 +36,7 @@ namespace omd { namespace parser template struct unicode_string : qi::grammar { + std::size_t indent; unicode_string(); qi::rule char_esc; diff --git a/yaml/parser/scalar_def.hpp b/yaml/parser/scalar_def.hpp index e5244fd9..bd29b735 100644 --- a/yaml/parser/scalar_def.hpp +++ b/yaml/parser/scalar_def.hpp @@ -54,21 +54,41 @@ namespace omd { namespace parser } } }; + + //~ struct fold_plain_string + //~ { + //~ template + //~ struct result { typedef void type; }; + + //~ template + //~ void operator()(String& utf8, Range const& rng) const + //~ { + //~ BOOST_FOREACH(typename Range::value_type c, rng) + //~ { + //~ } + //~ } + //~ }; } template unicode_string::unicode_string() - : unicode_string::base_type(unicode_start) + : unicode_string::base_type(unicode_start), + indent(0) { qi::char_type char_; qi::_val_type _val; qi::_r1_type _r1; qi::_1_type _1; + qi::_2_type _2; qi::lit_type lit; - qi::raw_type raw; + qi::blank_type blank; + qi::eol_type eol; + qi::repeat_type repeat; + qi::inf_type inf; using boost::spirit::qi::uint_parser; using boost::phoenix::function; + using boost::phoenix::ref; uint_parser hex4; uint_parser hex8; @@ -98,15 +118,17 @@ namespace omd { namespace parser > '\'' ; - auto space = char_(" \r\n\t"); + auto space = blank | (eol >> repeat(ref(indent)+1, inf)[blank]); auto safe_first = ~char_(unsafe_first); auto safe_plain = ~char_(unsafe_plain); unquoted = - raw[ - safe_first - >> *((+space >> safe_plain) | safe_plain) - ]; + safe_first[_val = _1] + >> *( + (+space >> safe_plain) [_val += ' ', _val += _2] + | safe_plain [_val += _1] + ) + ; unicode_start = double_quoted diff --git a/yaml/parser/yaml.hpp b/yaml/parser/yaml.hpp index 2991ff44..a42101d0 100644 --- a/yaml/parser/yaml.hpp +++ b/yaml/parser/yaml.hpp @@ -28,7 +28,7 @@ namespace omd { namespace parser flow_t flow_g; qi::rule indent; - qi::rule blocks; + qi::rule > blocks; qi::rule > block_seq; qi::rule block_seq_entry; qi::rule > block_map; diff --git a/yaml/parser/yaml_def.hpp b/yaml/parser/yaml_def.hpp index a124534d..c77885bc 100644 --- a/yaml/parser/yaml_def.hpp +++ b/yaml/parser/yaml_def.hpp @@ -48,6 +48,7 @@ namespace omd { namespace parser qi::char_type char_; qi::omit_type omit; qi::_pass_type _pass; + qi::eps_type eps; qi::blank_type blank; auto blank_line = *blank >> eol; @@ -68,15 +69,37 @@ namespace omd { namespace parser | flow_value ; - blocks = + std::size_t& indent_var = + flow_g.scalar_value.string_value.indent + ; + + auto save_indent = + eps[_a = phx::ref(indent_var)] + ; + + auto restore_indent = + eps[phx::ref(indent_var) = _a] + ; + + auto block_main = block_seq | block_map ; + blocks %= + save_indent + >> (block_main | restore_indent) + >> restore_indent + ; + indent = (*blank)[_val = count_chars(_1)]; + auto start_indent = + indent[ _a = _1, phx::ref(indent_var) = _1 ] + ; + auto block_seq_indicator = // Lookahead and see if we have a - &(indent[_a = _1] >> '-' >> blank) // sequence indicator. Save the indent + &(start_indent >> '-' >> blank) // sequence indicator. Save the indent ; // in local variable _a block_seq = @@ -92,9 +115,9 @@ namespace omd { namespace parser ; auto block_map_indicator = // Lookahead and see if we have a - &( indent[_a = _1] // map indicator. Save the indent - >> flow_scalar // in local variable _a - >> skip(space)[':'] + &( start_indent // map indicator. Save the indent + >> flow_scalar // in local variable _a + >> skip(space)[':'] ) ;