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

parsing blocks

This commit is contained in:
Joel de Guzman
2011-11-14 15:14:26 +08:00
parent c0dd20a977
commit d75b00437a
5 changed files with 103 additions and 4 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,8 @@
american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves

View File

@@ -121,7 +121,6 @@ namespace omd { namespace parser
scalar<Iterator>::scalar()
: scalar::base_type(value)
{
qi::_val_type _val;
qi::lit_type lit;
qi::char_type char_;
qi::hex_type hex;

View File

@@ -24,6 +24,14 @@ namespace omd { namespace parser
qi::rule<Iterator, ast::value_t()> start;
flow_t flow_value;
qi::rule<Iterator, std::size_t()> indent;
qi::rule<Iterator> blank_line;
qi::rule<Iterator, std::string(std::size_t)> line;
qi::rule<Iterator, std::string()> first_line;
qi::rule<Iterator, std::string(), qi::locals<std::size_t> > block;
qi::rule<Iterator, ast::array_t()> blocks;
typedef omd::parser::error_handler<Iterator> error_handler_t;
boost::phoenix::function<error_handler_t> const error_handler;
};

View File

@@ -6,23 +6,107 @@
#define OMD_PARSER_YAML_DEF_HPP
#include "yaml.hpp"
#include <algorithm>
namespace omd { namespace parser
{
namespace detail
{
struct count_chars
{
template <typename Range>
struct result { typedef std::size_t type; };
template <typename Range>
std::size_t operator()(Range const& rng) const
{
return std::distance(rng.begin(), rng.end());
}
};
//~ struct parse_block
//~ {
//~ template <typename This>
//~ struct result { typedef void type; };
//~ template <typename This>
//~ void operator()(This* g) const
//~ {
//~ }
//~ };
}
template <typename Iterator>
yaml<Iterator>::yaml(std::string const& source_file)
: yaml::base_type(start),
error_handler(error_handler_t(source_file))
{
namespace phx = boost::phoenix;
qi::skip_type skip;
auto space = ws.start.alias();
start = skip(space)[flow_value];
qi::_val_type _val;
qi::_1_type _1;
qi::_2_type _2;
qi::_3_type _3;
qi::_4_type _4;
qi::_r1_type _r1;
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::blank_type blank;
phx::function<detail::count_chars> count_chars;
auto append = _val += _1;
auto pb = phx::push_back(_val, _1);
start =
skip(space)[flow_value]
| blocks
;
blocks = +block[pb];
block =
indent[_a = _1] // indent and save the number of indents
>> first_line[append] // get the rest of the first line
>> *(blank_line | line(_a)[append]) // get the lines
>> repeat(_a)[blank] // must end with exact indent as started
;
auto endl = eol | eoi;
line = // a line is:
repeat(_r1 + 1, inf)[blank] // at least current indent + 1 blanks
>> (+(char_ - endl)[append]) // one or more non-endl characters
>> endl // terminated by endl
;
first_line = // the first_line is:
(+(char_ - endl)[append]) // one or more non-endl characters
>> endl // terminated by endl
;
blank_line = *blank >> eol;
indent = (*blank)[_val = count_chars(_1)];
BOOST_SPIRIT_DEBUG_NODES(
(start)
(blocks)
(block)
(line)
(first_line)
(blank_line)
(indent)
);
qi::on_error<qi::fail>(start, error_handler(_1, _2, _3, _4));
}
}}