mirror of
https://github.com/boostorg/parser.git
synced 2026-01-19 04:22:13 +00:00
scalar parsers
This commit is contained in:
59
yaml/ast.hpp
59
yaml/ast.hpp
@@ -9,37 +9,48 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/spirit/include/support_extended_variant.hpp>
|
||||
|
||||
|
||||
namespace omd{ namespace json
|
||||
namespace omd { namespace ast
|
||||
{
|
||||
|
||||
// ------------------- json types --------------------
|
||||
//
|
||||
typedef std::string string_t;
|
||||
typedef double number_t;
|
||||
typedef bool bool_t;
|
||||
struct null_t
|
||||
{
|
||||
// ------------------- AST types --------------------
|
||||
//
|
||||
typedef std::string string_t;
|
||||
typedef double double_t;
|
||||
typedef int int_t;
|
||||
typedef bool bool_t;
|
||||
struct null_t
|
||||
{
|
||||
// nulls always compare
|
||||
bool operator==(const null_t&) const{ return true; }
|
||||
bool operator!=(const null_t&) const{ return false; }
|
||||
};
|
||||
};
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
null_t,
|
||||
bool_t,
|
||||
string_t,
|
||||
number_t,
|
||||
std::map<string_t,
|
||||
boost::recursive_variant_>,
|
||||
std::vector<boost::recursive_variant_>
|
||||
>::type value_t;
|
||||
struct value_t;
|
||||
typedef std::map<std::string, value_t> object_t;
|
||||
typedef std::vector<value_t> array_t;
|
||||
|
||||
typedef std::map<std::string, value_t> object_t;
|
||||
typedef std::vector<value_t> array_t;
|
||||
struct value_t
|
||||
: boost::spirit::extended_variant<
|
||||
null_t,
|
||||
bool_t,
|
||||
string_t,
|
||||
double_t,
|
||||
int_t,
|
||||
object_t
|
||||
>
|
||||
{
|
||||
value_t(string_t const& val) : base_type(val) {}
|
||||
value_t(double_t val) : base_type(val) {}
|
||||
value_t(int_t val) : base_type(val) {}
|
||||
value_t(bool_t val) : base_type(val) {}
|
||||
value_t(null_t val = null_t()) : base_type(val) {}
|
||||
|
||||
// ---------------------------------------------------
|
||||
value_t(value_t const& rhs)
|
||||
: base_type(rhs.get()) {}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
45
yaml/parser/scalar.hpp
Normal file
45
yaml/parser/scalar.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (C) 2010, 2011 Object Modeling Designs
|
||||
*/
|
||||
|
||||
#if !defined(OMD_PARSER_STRING)
|
||||
#define OMD_PARSER_STRING
|
||||
|
||||
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include "../ast.hpp" // our AST
|
||||
|
||||
namespace omd { namespace parser
|
||||
{
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace ascii = boost::spirit::ascii;
|
||||
|
||||
typedef boost::uint32_t uchar; // a unicode code point
|
||||
|
||||
template <typename Iterator>
|
||||
struct unicode_string : qi::grammar<Iterator, std::string()>
|
||||
{
|
||||
unicode_string();
|
||||
|
||||
qi::rule<Iterator, void(std::string&)> char_esc;
|
||||
qi::rule<Iterator, std::string()> char_lit;
|
||||
qi::rule<Iterator, std::string()> start;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct scalar : qi::grammar<Iterator, ast::value_t(), ascii::space_type>
|
||||
{
|
||||
scalar();
|
||||
|
||||
qi::rule<Iterator, ast::value_t(), ascii::space_type> value;
|
||||
unicode_string<Iterator> string_value;
|
||||
qi::rule<Iterator, int()> integer_value;
|
||||
qi::symbols<bool, std::string> bool_value;
|
||||
qi::rule<Iterator, ast::null_t(), ascii::space_type > null_value;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
||||
153
yaml/parser/scalar_def.hpp
Normal file
153
yaml/parser/scalar_def.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Copyright (C) 2010, 2011 Object Modeling Designs
|
||||
*/
|
||||
|
||||
#if !defined(OMD_COMMON_STRING_DEF)
|
||||
#define OMD_COMMON_STRING_DEF
|
||||
|
||||
#include "scalar.hpp"
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/include/phoenix_container.hpp>
|
||||
#include <boost/spirit/include/phoenix_statement.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/regex/pending/unicode_iterator.hpp>
|
||||
|
||||
namespace omd { namespace parser
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct push_utf8
|
||||
{
|
||||
template <typename S, typename C>
|
||||
struct result { typedef void type; };
|
||||
|
||||
void operator()(std::string& utf8, uchar code_point) const
|
||||
{
|
||||
typedef std::back_insert_iterator<std::string> insert_iter;
|
||||
insert_iter out_iter(utf8);
|
||||
boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
|
||||
*utf8_iter++ = code_point;
|
||||
}
|
||||
};
|
||||
|
||||
struct push_esc
|
||||
{
|
||||
template <typename S, typename C>
|
||||
struct result { typedef void type; };
|
||||
|
||||
void operator()(std::string& utf8, uchar c) const
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b': utf8 += '\b'; break;
|
||||
case 't': utf8 += '\t'; break;
|
||||
case 'n': utf8 += '\n'; break;
|
||||
case 'f': utf8 += '\f'; break;
|
||||
case 'r': utf8 += '\r'; break;
|
||||
case '"': utf8 += '"'; break;
|
||||
case '/': utf8 += '/'; break;
|
||||
case '\\': utf8 += '\\'; break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
unicode_string<Iterator>::unicode_string()
|
||||
: unicode_string::base_type(start)
|
||||
{
|
||||
qi::char_type char_;
|
||||
qi::_val_type _val;
|
||||
qi::_r1_type _r1;
|
||||
qi::_1_type _1;
|
||||
|
||||
using boost::spirit::qi::uint_parser;
|
||||
using boost::phoenix::function;
|
||||
|
||||
uint_parser<uchar, 16, 4, 4> hex4;
|
||||
uint_parser<uchar, 16, 8, 8> hex8;
|
||||
function<detail::push_utf8> push_utf8;
|
||||
function<detail::push_esc> push_esc;
|
||||
|
||||
char_esc
|
||||
= '\\'
|
||||
> ( ('u' > hex4) [push_utf8(_r1, _1)]
|
||||
| ('U' > hex8) [push_utf8(_r1, _1)]
|
||||
| char_("btnfr/\\\"'") [push_esc(_r1, _1)]
|
||||
)
|
||||
;
|
||||
|
||||
char_lit
|
||||
= '\''
|
||||
> (char_esc(_val) | (~char_('\'')) [_val += _1])
|
||||
> '\''
|
||||
;
|
||||
|
||||
start
|
||||
= '"'
|
||||
> *(char_esc(_val) | (~char_('"')) [_val += _1])
|
||||
> '"'
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODES(
|
||||
(char_esc)
|
||||
(char_lit)
|
||||
(start)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
scalar<Iterator>::scalar()
|
||||
: scalar::base_type(value)
|
||||
{
|
||||
qi::_val_type _val;
|
||||
qi::lit_type lit;
|
||||
qi::lexeme_type lexeme;
|
||||
qi::char_type char_;
|
||||
qi::hex_type hex;
|
||||
qi::oct_type oct_;
|
||||
qi::no_case_type no_case;
|
||||
qi::lexeme_type lexeme;
|
||||
|
||||
real_parser<double, strict_real_policies<double> > double_value;
|
||||
|
||||
value =
|
||||
string_value
|
||||
| double_value
|
||||
| integer_value
|
||||
| no_case[bool_value]
|
||||
| no_case[null_value]
|
||||
;
|
||||
|
||||
integer_value =
|
||||
lexeme[no_case["0x"] > hex]
|
||||
| lexeme['0' >> oct]
|
||||
| int_
|
||||
;
|
||||
|
||||
bool_value.add
|
||||
("true", true)
|
||||
("false", false)
|
||||
("on", true)
|
||||
("off", false)
|
||||
("yes", true)
|
||||
("no", false)
|
||||
;
|
||||
|
||||
null_value =
|
||||
(lit("null") | '~')
|
||||
>> qi::attr(ast::null_t())
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODES(
|
||||
(value)
|
||||
(integer_value)
|
||||
(bool_value)
|
||||
(null_value)
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user