mirror of
https://github.com/boostorg/parser.git
synced 2026-01-19 04:22:13 +00:00
block arrays working
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2010, 2011 Object Modeling Designs
|
||||
*/
|
||||
|
||||
//~ #define BOOST_SPIRIT_DEBUG
|
||||
#define BOOST_SPIRIT_DEBUG
|
||||
|
||||
#include "../yaml/parser/yaml_def.hpp"
|
||||
#include "../yaml/parser/flow_def.hpp"
|
||||
|
||||
3
test/test_files/yaml_block_array1.yaml
Normal file
3
test/test_files/yaml_block_array1.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
- Boston Red Sox
|
||||
- Detroit Tigers
|
||||
- New York Yankees
|
||||
@@ -24,13 +24,13 @@ namespace omd { namespace parser
|
||||
{
|
||||
flow(std::string const& source_file = "");
|
||||
|
||||
typedef std::pair<ast::value_t, ast::value_t> element_t;
|
||||
typedef std::pair<ast::value_t, ast::value_t> map_element_t;
|
||||
typedef white_space<Iterator> white_space_t;
|
||||
|
||||
qi::rule<Iterator, ast::value_t(), white_space_t> start;
|
||||
qi::rule<Iterator, ast::value_t(), white_space_t> flow_start;
|
||||
qi::rule<Iterator, ast::value_t(), white_space_t> flow_value;
|
||||
qi::rule<Iterator, ast::object_t(), white_space_t> object;
|
||||
qi::rule<Iterator, element_t(), white_space_t> member_pair;
|
||||
qi::rule<Iterator, map_element_t(), white_space_t> member_pair;
|
||||
qi::rule<Iterator, ast::array_t(), white_space_t> array;
|
||||
scalar<Iterator> scalar_value;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace omd { namespace parser
|
||||
|
||||
template <typename Iterator>
|
||||
flow<Iterator>::flow(std::string const& source_file)
|
||||
: flow::base_type(start),
|
||||
: flow::base_type(flow_start),
|
||||
error_handler(error_handler_t(source_file))
|
||||
{
|
||||
qi::_1_type _1;
|
||||
@@ -42,7 +42,7 @@ namespace omd { namespace parser
|
||||
auto pb = phx::push_back(_val, _1);
|
||||
auto ins = phx::insert(_val, _1);
|
||||
|
||||
start = &(lit('[') | '{') // has to start with an array or object
|
||||
flow_start = &(lit('[') | '{') // has to start with an array or object
|
||||
>> flow_value
|
||||
;
|
||||
|
||||
@@ -71,14 +71,14 @@ namespace omd { namespace parser
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODES(
|
||||
(start)
|
||||
(flow_start)
|
||||
(flow_value)
|
||||
(object)
|
||||
(member_pair)
|
||||
(array)
|
||||
);
|
||||
|
||||
qi::on_error<qi::fail>(start, error_handler(_1, _2, _3, _4));
|
||||
qi::on_error<qi::fail>(flow_start, error_handler(_1, _2, _3, _4));
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace omd { namespace parser
|
||||
{
|
||||
scalar();
|
||||
|
||||
qi::rule<Iterator, ast::value_t()> value;
|
||||
qi::rule<Iterator, ast::value_t()> scalar_value;
|
||||
unicode_string<Iterator> string_value;
|
||||
qi::rule<Iterator, int()> integer_value;
|
||||
qi::symbols<char, bool> bool_value;
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace omd { namespace parser
|
||||
|
||||
template <typename Iterator>
|
||||
scalar<Iterator>::scalar()
|
||||
: scalar::base_type(value)
|
||||
: scalar::base_type(scalar_value)
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::char_type char_;
|
||||
@@ -137,7 +137,7 @@ namespace omd { namespace parser
|
||||
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > double_value;
|
||||
|
||||
value =
|
||||
scalar_value =
|
||||
double_value
|
||||
| integer_value
|
||||
| no_case[bool_value]
|
||||
@@ -166,7 +166,7 @@ namespace omd { namespace parser
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODES(
|
||||
(value)
|
||||
(scalar_value)
|
||||
(integer_value)
|
||||
(null_value)
|
||||
);
|
||||
|
||||
@@ -20,23 +20,18 @@ namespace omd { namespace parser
|
||||
|
||||
typedef white_space<Iterator> white_space_t;
|
||||
typedef flow<Iterator> flow_t;
|
||||
typedef boost::iterator_range<Iterator> range_t;
|
||||
typedef std::pair<range_t, range_t> raw_block_t;
|
||||
typedef std::pair<ast::value_t, ast::value_t> map_element_t;
|
||||
|
||||
white_space_t ws;
|
||||
qi::rule<Iterator, ast::value_t()> start;
|
||||
qi::rule<Iterator, ast::value_t()> flow;
|
||||
qi::rule<Iterator, ast::value_t()> scalar;
|
||||
//~ qi::rule<Iterator, ast::value_t&(ast::value_t&), white_space_t> block_content;
|
||||
flow_t flow_value;
|
||||
qi::rule<Iterator, ast::value_t()> yaml_start;
|
||||
flow_t flow_g;
|
||||
|
||||
qi::rule<Iterator, std::size_t()> indent;
|
||||
qi::rule<Iterator> blank_line;
|
||||
qi::rule<Iterator, void(std::size_t)> line;
|
||||
qi::rule<Iterator> first_line;
|
||||
qi::rule<Iterator, raw_block_t(), qi::locals<std::size_t> > block;
|
||||
|
||||
qi::rule<Iterator, ast::value_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;
|
||||
qi::rule<Iterator, map_element_t(std::size_t)> block_map_entry;
|
||||
|
||||
typedef omd::parser::error_handler<Iterator> error_handler_t;
|
||||
boost::phoenix::function<error_handler_t> const error_handler;
|
||||
|
||||
@@ -23,79 +23,11 @@ namespace omd { namespace parser
|
||||
return std::distance(rng.begin(), rng.end());
|
||||
}
|
||||
};
|
||||
|
||||
struct parse_block
|
||||
{
|
||||
template <typename, typename, typename, typename>
|
||||
struct result { typedef void type; };
|
||||
|
||||
template <typename YamlG, typename Attr, typename Ranges>
|
||||
void operator()(YamlG* g, Attr& attr, Ranges const& rngs, bool& pass) const
|
||||
{
|
||||
ast::array_t* arr_p = boost::get<ast::array_t>(&attr);
|
||||
|
||||
// hack:
|
||||
if (arr_p == 0)
|
||||
{
|
||||
attr = ast::array_t();
|
||||
arr_p = boost::get<ast::array_t>(&attr);
|
||||
}
|
||||
|
||||
using boost::spirit::qi::parse;
|
||||
typedef typename Ranges::second_type::const_iterator iter_t;
|
||||
|
||||
{
|
||||
//~ ast::value_t value;
|
||||
//~ iter_t first = rngs.first.begin();
|
||||
//~ iter_t last = rngs.first.end();
|
||||
|
||||
//~ bool is_array = phrase_parse(first, last, '-', g->ws, value);
|
||||
//~ if (boost::get<ast::null_t>(&attr))
|
||||
//~ {
|
||||
//~ attr = ast::array_t();
|
||||
//~ }
|
||||
|
||||
//~ arr_p = boost::get<ast::array_t>(&attr);
|
||||
|
||||
//~ if (!arr_p)
|
||||
//~ {
|
||||
//~ pass = false;
|
||||
//~ return;
|
||||
//~ }
|
||||
|
||||
//~ if (phrase_parse(first, last, g->scalar, g->ws, value))
|
||||
//~ {
|
||||
//~ arr_p->push_back(value);
|
||||
//~ }
|
||||
//~ else
|
||||
//~ {
|
||||
//~ pass = false;
|
||||
//~ return;
|
||||
//~ }
|
||||
|
||||
std::string utf8;
|
||||
detail::push_utf8 push_back;
|
||||
BOOST_FOREACH(uchar code_point, rngs.first)
|
||||
{
|
||||
push_back(utf8, code_point);
|
||||
}
|
||||
arr_p->push_back(utf8);
|
||||
}
|
||||
|
||||
{
|
||||
ast::value_t value;
|
||||
iter_t first = rngs.second.begin();
|
||||
iter_t last = rngs.second.end();
|
||||
if (parse(first, last, *g, value))
|
||||
arr_p->push_back(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
yaml<Iterator>::yaml(std::string const& source_file)
|
||||
: yaml::base_type(start),
|
||||
: yaml::base_type(yaml_start),
|
||||
error_handler(error_handler_t(source_file))
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
@@ -112,70 +44,59 @@ namespace omd { namespace parser
|
||||
qi::_a_type _a;
|
||||
|
||||
qi::repeat_type repeat;
|
||||
qi::inf_type inf;
|
||||
qi::eol_type eol;
|
||||
qi::eoi_type eoi;
|
||||
qi::char_type char_;
|
||||
qi::raw_type raw;
|
||||
qi::omit_type omit;
|
||||
qi::_pass_type _pass;
|
||||
|
||||
qi::blank_type blank;
|
||||
auto blank_line = *blank >> eol;
|
||||
|
||||
phx::function<detail::count_chars> count_chars;
|
||||
|
||||
auto append = _val += _1;
|
||||
//~ auto pb = phx::push_back(_val, _1);
|
||||
phx::function<detail::parse_block> parse_block;
|
||||
auto flow_compound = skip(space)[flow_g.flow_start];
|
||||
auto flow_value = skip(space)[flow_g.flow_value];
|
||||
auto flow_scalar = skip(space)[flow_g.scalar_value.scalar_value];
|
||||
|
||||
start =
|
||||
skip(space)[flow_value]
|
||||
yaml_start =
|
||||
flow_compound
|
||||
| blocks
|
||||
;
|
||||
|
||||
flow = skip(space)[flow_value];
|
||||
scalar = skip(space)[flow_value.scalar_value];
|
||||
|
||||
//~ block_content =
|
||||
//~ '-' >> scalar
|
||||
//~ | scalar >> ':'
|
||||
//~ ;
|
||||
|
||||
blocks = +(block[parse_block(this, _val, _1, _pass)]);
|
||||
|
||||
block %=
|
||||
omit[indent[_a = _1]] // indent and save the number of indents
|
||||
>> raw[first_line] // get the rest of the first line
|
||||
>> raw[*(blank_line | line(_a))] // get the lines
|
||||
>> repeat(_a)[blank] // must end with exact indent as started
|
||||
blocks =
|
||||
block_seq
|
||||
//~ | block_map
|
||||
;
|
||||
|
||||
auto endl = eol | eoi;
|
||||
|
||||
line = // a line is:
|
||||
repeat(_r1 + 1, inf)[blank] // at least current indent + 1 blanks
|
||||
>> (+(char_ - endl)) // one or more non-endl characters
|
||||
>> endl // terminated by endl
|
||||
;
|
||||
|
||||
first_line = // the first_line is:
|
||||
(+(char_ - endl)) // one or more non-endl characters
|
||||
>> endl // terminated by endl
|
||||
;
|
||||
|
||||
blank_line = *blank >> eol;
|
||||
indent = (*blank)[_val = count_chars(_1)];
|
||||
|
||||
auto block_seq_indicator = // Lookahead and see if we have a
|
||||
&(indent[_a = _1] >> '-' >> blank) // sequence indicator. Save the indent
|
||||
; // in local variable _a
|
||||
|
||||
block_seq =
|
||||
omit[block_seq_indicator]
|
||||
>> +block_seq_entry(_a) // Get the entries passing in the
|
||||
; // indent level
|
||||
|
||||
block_seq_entry =
|
||||
omit[*blank_line] // Ignore blank lines
|
||||
>> omit[repeat(_r1)[blank]] // Indent _r1 spaces
|
||||
>> omit['-' >> blank] // Get the sequence indicator '-'
|
||||
>> flow_value // Get the value
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODES(
|
||||
(start)
|
||||
(yaml_start)
|
||||
(blocks)
|
||||
(block)
|
||||
(line)
|
||||
(first_line)
|
||||
(blank_line)
|
||||
(block_seq)
|
||||
(block_seq_entry)
|
||||
(block_map)
|
||||
(block_map_entry)
|
||||
(indent)
|
||||
);
|
||||
|
||||
qi::on_error<qi::fail>(start, error_handler(_1, _2, _3, _4));
|
||||
qi::on_error<qi::fail>(yaml_start, error_handler(_1, _2, _3, _4));
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user