2
0
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:
Joel de Guzman
2011-11-15 12:16:51 +08:00
parent dd4d3aec58
commit 8d83cfafa1
8 changed files with 55 additions and 136 deletions

View File

@@ -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"

View File

@@ -0,0 +1,3 @@
- Boston Red Sox
- Detroit Tigers
- New York Yankees

View File

@@ -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;

View File

@@ -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));
}
}}

View File

@@ -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;

View File

@@ -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)
);

View File

@@ -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;

View File

@@ -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));
}
}}