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

incremental updates

This commit is contained in:
Joel de Guzman
2011-11-14 16:45:00 +08:00
parent d75b00437a
commit dd4d3aec58
8 changed files with 120 additions and 45 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

@@ -5,4 +5,4 @@
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves
- Atlanta Braves

View File

@@ -1,14 +1,6 @@
# Now we have comments
[
123.45,
true,
false,
"this is a unicode \u20AC string",
"Τη γλώσσα μου έδωσαν ελληνική",
[
92,
["another string", apple, Sîne], # We also have plain unquoted strings
'this is a ''unicode'' string' # and we have single quoted strings
]
apple ,
Sîne
]

View File

@@ -21,8 +21,7 @@ namespace omd { namespace ast
template <typename A, typename B>
bool operator()(A const& a, B const& b) const
{
BOOST_ASSERT(false); // this should not happen. We cannot compare different types
return false;
return false; // comparing different types returns false
}
template <typename T>

View File

@@ -7,6 +7,7 @@
#define OMD_PARSER_SCALAR_HPP
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
#include <string>
@@ -29,6 +30,9 @@ namespace omd { namespace parser
// These are not allowed as first plain-style character
char const* unsafe_first = ",[]{}#&*!|>\\\"%@`";
// These are not allowed as non-first plain-style character
char const* unsafe_plain = " \n\r\t-?:,[]{}#&*!|>\\\"%@`";
template <typename Iterator>
struct unicode_string : qi::grammar<Iterator, std::string()>
{

View File

@@ -65,6 +65,7 @@ namespace omd { namespace parser
qi::_r1_type _r1;
qi::_1_type _1;
qi::lit_type lit;
qi::raw_type raw;
using boost::spirit::qi::uint_parser;
using boost::phoenix::function;
@@ -76,31 +77,36 @@ namespace omd { namespace parser
char_esc =
'\\'
> ( ('u' > hex4) [push_utf8(_r1, _1)]
| ('U' > hex8) [push_utf8(_r1, _1)]
| char_("btnfr/\\\"'") [push_esc(_r1, _1)]
> ( ('u' > hex4) [push_utf8(_r1, _1)]
| ('U' > hex8) [push_utf8(_r1, _1)]
| char_("btnfr/\\\"'") [push_esc(_r1, _1)]
)
;
double_quoted =
'"'
> *(char_esc(_val) | (~char_('"')) [_val += _1])
> *(char_esc(_val) | (~char_('"')) [_val += _1])
> '"'
;
single_quoted =
'\''
> *(
lit("''") [_val += '\'']
| (~char_('\'')) [_val += _1]
lit("''") [_val += '\'']
| (~char_('\'')) [_val += _1]
)
> '\''
;
auto space = char_(" \r\n\t");
auto safe_first = ~char_(unsafe_first);
auto safe_plain = ~char_(unsafe_plain);
unquoted =
~char_(unsafe_first)
>> *(~char_(indicators))
;
raw[
safe_first
>> *((+space >> safe_plain) | safe_plain)
];
start =
double_quoted

View File

@@ -7,8 +7,9 @@
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#include <string>
#include "flow.hpp"
#include <string>
#include <boost/fusion/adapted/std_pair.hpp>
namespace omd { namespace parser
{
@@ -19,18 +20,23 @@ 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;
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, 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, 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::array_t()> blocks;
qi::rule<Iterator, ast::value_t()> blocks;
typedef omd::parser::error_handler<Iterator> error_handler_t;
boost::phoenix::function<error_handler_t> const error_handler;

View File

@@ -24,17 +24,73 @@ namespace omd { namespace parser
}
};
//~ struct parse_block
//~ {
//~ template <typename This>
//~ struct result { typedef void type; };
struct parse_block
{
template <typename, typename, typename, typename>
struct result { typedef void type; };
//~ template <typename This>
//~ void operator()(This* g) const
//~ {
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>
@@ -60,24 +116,36 @@ namespace omd { namespace parser
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;
phx::function<detail::count_chars> count_chars;
auto append = _val += _1;
auto pb = phx::push_back(_val, _1);
//~ auto pb = phx::push_back(_val, _1);
phx::function<detail::parse_block> parse_block;
start =
skip(space)[flow_value]
| blocks
;
blocks = +block[pb];
flow = skip(space)[flow_value];
scalar = skip(space)[flow_value.scalar_value];
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
//~ 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
;
@@ -85,12 +153,12 @@ namespace omd { namespace parser
line = // a line is:
repeat(_r1 + 1, inf)[blank] // at least current indent + 1 blanks
>> (+(char_ - endl)[append]) // one or more non-endl characters
>> (+(char_ - endl)) // 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
(+(char_ - endl)) // one or more non-endl characters
>> endl // terminated by endl
;