2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-19 04:22:13 +00:00

plain strings respecting indent level

This commit is contained in:
Joel de Guzman
2011-11-15 16:47:33 +08:00
parent dcc019396b
commit dd5df0fbe2
5 changed files with 60 additions and 14 deletions

View File

@@ -2,7 +2,7 @@
- Boston Red Sox
- Detroit Tigers
- New York
Yankees
Yankees
national:
- New York Mets
- Chicago Cubs

View File

@@ -36,6 +36,7 @@ namespace omd { namespace parser
template <typename Iterator>
struct unicode_string : qi::grammar<Iterator, std::string()>
{
std::size_t indent;
unicode_string();
qi::rule<Iterator, void(std::string&)> char_esc;

View File

@@ -54,21 +54,41 @@ namespace omd { namespace parser
}
}
};
//~ struct fold_plain_string
//~ {
//~ template <typename String, typename Range>
//~ struct result { typedef void type; };
//~ template <typename String, typename Range>
//~ void operator()(String& utf8, Range const& rng) const
//~ {
//~ BOOST_FOREACH(typename Range::value_type c, rng)
//~ {
//~ }
//~ }
//~ };
}
template <typename Iterator>
unicode_string<Iterator>::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<uchar, 16, 4, 4> hex4;
uint_parser<uchar, 16, 8, 8> 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

View File

@@ -28,7 +28,7 @@ namespace omd { namespace parser
flow_t flow_g;
qi::rule<Iterator, std::size_t()> indent;
qi::rule<Iterator, ast::value_t()> blocks;
qi::rule<Iterator, ast::value_t(), qi::locals<std::size_t> > blocks;
qi::rule<Iterator, ast::array_t(), qi::locals<std::size_t> > block_seq;
qi::rule<Iterator, ast::value_t(std::size_t)> block_seq_entry;
qi::rule<Iterator, ast::object_t(), qi::locals<std::size_t> > block_map;

View File

@@ -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)[':']
)
;