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

Merge branch 'master' of github.com:consultomd/yaml_spirit

This commit is contained in:
Joel de Guzman
2011-11-14 07:52:02 +08:00
7 changed files with 176 additions and 1 deletions

View File

@@ -0,0 +1,65 @@
/**
* Copyright (C) 2010, 2011 Object Modeling Designs
*/
#include "../yaml/generator/scalar_def.hpp"
#include <boost/detail/lightweight_test.hpp>
namespace
{
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct output_iterator
{
typedef std::basic_string<Char> string_type;
typedef std::back_insert_iterator<string_type> type;
};
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename T>
void print_if_failed(char const* func, bool result
, std::basic_string<Char> const& generated, T const& expected)
{
if (!result)
std::cerr << "in " << func << ": result is false" << std::endl;
else if (generated != expected)
std::cerr << "in " << func << ": generated \""
<< std::string(generated.begin(), generated.end())
<< "\"" << std::endl;
}
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename Generator, typename Attr>
inline bool test(Char const *expected, Generator const& g, Attr const& attr)
{
namespace karma = boost::spirit::karma;
typedef std::basic_string<Char> string_type;
string_type generated;
std::back_insert_iterator<string_type> outit(generated);
bool result = karma::generate(outit, g, attr);
print_if_failed("test", result, generated, expected);
return result && generated == expected;
}
}
int main()
{
using omd::generator::scalar;
using omd::ast::value_t;
using omd::ast::null_t;
scalar<output_iterator<char>::type> g;
BOOST_TEST(test("12345", g, value_t(12345)));
BOOST_TEST(test("true", g, value_t(true)));
BOOST_TEST(test("false", g, value_t(false)));
BOOST_TEST(test("123.45", g, value_t(123.45)));
BOOST_TEST(test("123.456789012", g, value_t(123.456789012)));
BOOST_TEST(test("null", g, value_t(null_t())));
BOOST_TEST(test("\"Hello, World\"", g, value_t(std::string("Hello, World"))));
return boost::report_errors();
}

34
yaml/generator/scalar.hpp Normal file
View File

@@ -0,0 +1,34 @@
/**
* Copyright (C) 2010, 2011 Object Modeling Designs
*/
#if !defined(OMD_GENERATOR_SCALAR_HPP)
#define OMD_GENERATOR_SCALAR_HPP
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#include <string>
#include <boost/spirit/include/karma.hpp>
#include "../ast.hpp" // our AST
namespace omd { namespace generator
{
namespace karma = boost::spirit::karma;
namespace ascii = boost::spirit::ascii;
typedef boost::uint32_t uchar; // a unicode code point
template <typename OutputIterator>
struct scalar : karma::grammar<OutputIterator, ast::value_t()>
{
scalar();
karma::rule<OutputIterator, ast::value_t()> value;
karma::rule<OutputIterator, ast::null_t()> null_value;
karma::rule<OutputIterator, ast::string_t()> string_value;
};
}}
#endif

View File

@@ -0,0 +1,76 @@
/**
* Copyright (C) 2010, 2011 Object Modeling Designs
*/
#if !defined(OMD_GENERATOR_SCALAR_DEF_HPP)
#define OMD_GENERATOR_SCALAR_DEF_HPP
#include "scalar.hpp"
#include <boost/cstdint.hpp>
#include <boost/spirit/include/karma.hpp>
namespace boost { namespace spirit { namespace traits
{
// this specialization tells Spirit that omd::ast::value_t is a variant-
// like type
template <>
struct not_is_variant<omd::ast::value_t, karma::domain>
: mpl::false_
{};
// this specialization tells Spirit how to extract the type of the value
// stored in the given omd::ast::value_t node
template <>
struct variant_which<omd::ast::value_t>
{
static int call(omd::ast::value_t const& v)
{
return v.get().which();
}
};
}}}
namespace omd { namespace generator
{
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct max_precision_policy : boost::spirit::karma::real_policies<T>
{
static unsigned int precision(T)
{
return 6; // same as std C++ library default
}
};
typedef karma::real_generator<double, max_precision_policy<double> >
max_precision_double_type;
max_precision_double_type const max_precision_double =
max_precision_double_type();
///////////////////////////////////////////////////////////////////////////
template <typename OutputIterator>
scalar<OutputIterator>::scalar()
: scalar::base_type(value)
{
karma::int_type int_;
karma::bool_type bool_;
karma::char_type char_;
karma::lit_type lit;
using boost::spirit::attr_cast;
value =
max_precision_double
| int_
| bool_
| string_value
| null_value
;
null_value = attr_cast(lit("null"));
string_value = '"' << *(&char_('"') << "\\\"" | char_) << '"';
}
}}
#endif

View File

@@ -30,7 +30,7 @@ namespace omd { namespace parser
qi::rule<Iterator, ast::value_t(), white_space_t> 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, element_t(), white_space_t> member_pair;
qi::rule<Iterator, ast::array_t(), white_space_t> array;
scalar<Iterator> scalar_value;