From d75b00437a0327293eca01f61fe25a846f7a5749 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 14 Nov 2011 15:14:26 +0800 Subject: [PATCH] parsing blocks --- test/parse_yaml_test.cpp | 2 +- test/test_files/basic_yaml_block.yaml | 8 +++ yaml/parser/scalar_def.hpp | 1 - yaml/parser/yaml.hpp | 8 +++ yaml/parser/yaml_def.hpp | 88 ++++++++++++++++++++++++++- 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 test/test_files/basic_yaml_block.yaml diff --git a/test/parse_yaml_test.cpp b/test/parse_yaml_test.cpp index 5fbf6370..2f1a455b 100644 --- a/test/parse_yaml_test.cpp +++ b/test/parse_yaml_test.cpp @@ -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" diff --git a/test/test_files/basic_yaml_block.yaml b/test/test_files/basic_yaml_block.yaml new file mode 100644 index 00000000..cbb12dcf --- /dev/null +++ b/test/test_files/basic_yaml_block.yaml @@ -0,0 +1,8 @@ +american: + - Boston Red Sox + - Detroit Tigers + - New York Yankees +national: + - New York Mets + - Chicago Cubs + - Atlanta Braves \ No newline at end of file diff --git a/yaml/parser/scalar_def.hpp b/yaml/parser/scalar_def.hpp index adfd3605..81e40616 100644 --- a/yaml/parser/scalar_def.hpp +++ b/yaml/parser/scalar_def.hpp @@ -121,7 +121,6 @@ namespace omd { namespace parser scalar::scalar() : scalar::base_type(value) { - qi::_val_type _val; qi::lit_type lit; qi::char_type char_; qi::hex_type hex; diff --git a/yaml/parser/yaml.hpp b/yaml/parser/yaml.hpp index 05bbce3c..b30cfbc3 100644 --- a/yaml/parser/yaml.hpp +++ b/yaml/parser/yaml.hpp @@ -24,6 +24,14 @@ namespace omd { namespace parser qi::rule start; flow_t flow_value; + qi::rule indent; + qi::rule blank_line; + qi::rule line; + qi::rule first_line; + qi::rule > block; + + qi::rule blocks; + typedef omd::parser::error_handler error_handler_t; boost::phoenix::function const error_handler; }; diff --git a/yaml/parser/yaml_def.hpp b/yaml/parser/yaml_def.hpp index 0123953c..99d9f3e8 100644 --- a/yaml/parser/yaml_def.hpp +++ b/yaml/parser/yaml_def.hpp @@ -6,23 +6,107 @@ #define OMD_PARSER_YAML_DEF_HPP #include "yaml.hpp" +#include namespace omd { namespace parser { + namespace detail + { + struct count_chars + { + template + struct result { typedef std::size_t type; }; + + template + std::size_t operator()(Range const& rng) const + { + return std::distance(rng.begin(), rng.end()); + } + }; + + //~ struct parse_block + //~ { + //~ template + //~ struct result { typedef void type; }; + + //~ template + //~ void operator()(This* g) const + //~ { + + //~ } + //~ }; + } + template yaml::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 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(start, error_handler(_1, _2, _3, _4)); } }}