diff --git a/test/generate_scalar_tests.cpp b/test/generate_scalar_tests.cpp new file mode 100644 index 00000000..bf90690f --- /dev/null +++ b/test/generate_scalar_tests.cpp @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2010, 2011 Object Modeling Designs + */ + +#include "../yaml/generator/scalar_def.hpp" +#include + +namespace +{ + /////////////////////////////////////////////////////////////////////////// + template + struct output_iterator + { + typedef std::basic_string string_type; + typedef std::back_insert_iterator type; + }; + + /////////////////////////////////////////////////////////////////////////// + template + void print_if_failed(char const* func, bool result + , std::basic_string 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 + inline bool test(Char const *expected, Generator const& g, Attr const& attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + string_type generated; + std::back_insert_iterator 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::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(); +} + diff --git a/test/json_test.cpp b/test/parse_json_test.cpp similarity index 100% rename from test/json_test.cpp rename to test/parse_json_test.cpp diff --git a/test/scalar_tests.cpp b/test/parse_scalar_tests.cpp similarity index 100% rename from test/scalar_tests.cpp rename to test/parse_scalar_tests.cpp diff --git a/test/yaml_test.cpp b/test/parse_yaml_test.cpp similarity index 100% rename from test/yaml_test.cpp rename to test/parse_yaml_test.cpp diff --git a/yaml/generator/scalar.hpp b/yaml/generator/scalar.hpp new file mode 100644 index 00000000..a915c0e8 --- /dev/null +++ b/yaml/generator/scalar.hpp @@ -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 + +#include + +#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 + struct scalar : karma::grammar + { + scalar(); + + karma::rule value; + karma::rule null_value; + karma::rule string_value; + }; +}} + +#endif diff --git a/yaml/generator/scalar_def.hpp b/yaml/generator/scalar_def.hpp new file mode 100644 index 00000000..f3c69e08 --- /dev/null +++ b/yaml/generator/scalar_def.hpp @@ -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 +#include + +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 + : 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 + { + static int call(omd::ast::value_t const& v) + { + return v.get().which(); + } + }; +}}} + +namespace omd { namespace generator +{ + /////////////////////////////////////////////////////////////////////////// + template + struct max_precision_policy : boost::spirit::karma::real_policies + { + static unsigned int precision(T) + { + return 6; // same as std C++ library default + } + }; + + typedef karma::real_generator > + max_precision_double_type; + max_precision_double_type const max_precision_double = + max_precision_double_type(); + + /////////////////////////////////////////////////////////////////////////// + template + scalar::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 diff --git a/yaml/parser/flow.hpp b/yaml/parser/flow.hpp index 82c32c6c..92cdefa1 100644 --- a/yaml/parser/flow.hpp +++ b/yaml/parser/flow.hpp @@ -30,7 +30,7 @@ namespace omd { namespace parser qi::rule start; qi::rule flow_value; qi::rule object; - qi::rule< Iterator, element_t(), white_space_t> member_pair; + qi::rule member_pair; qi::rule array; scalar scalar_value;