1 /*============================================================================== 2 Copyright (c) 2001-2011 Hartmut Kaiser 3 Copyright (c) 2010-2011 Bryce Lelbach 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 9 #if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP) 10 #define BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP 11 12 #include <boost/spirit/include/support_utree.hpp> 13 #include <boost/spirit/include/karma.hpp> 14 15 namespace boost { 16 namespace spirit { 17 namespace traits { 18 19 template<> 20 struct transform_attribute<utree::nil_type, unused_type, karma::domain> { 21 typedef unused_type type; 22 preboost::spirit::traits::transform_attribute23 static unused_type pre (utree::nil_type&) { return unused_type(); } 24 }; 25 26 } // traits 27 } // spirit 28 } // boost 29 30 namespace sexpr 31 { 32 33 namespace karma = boost::spirit::karma; 34 namespace standard = boost::spirit::standard; 35 36 using boost::spirit::utree; 37 using boost::spirit::utf8_symbol_range_type; 38 using boost::spirit::utf8_string_range_type; 39 using boost::spirit::binary_range_type; 40 41 struct bool_output_policies : karma::bool_policies<> 42 { 43 template <typename CharEncoding, typename Tag, typename Iterator> generate_truesexpr::bool_output_policies44 static bool generate_true(Iterator& sink, bool) 45 { 46 return string_inserter<CharEncoding, Tag>::call(sink, "#t"); 47 } 48 49 template <typename CharEncoding, typename Tag, typename Iterator> generate_falsesexpr::bool_output_policies50 static bool generate_false(Iterator& sink, bool) 51 { 52 return string_inserter<CharEncoding, Tag>::call(sink, "#f"); 53 } 54 }; 55 56 template <typename Iterator> 57 struct generator : karma::grammar<Iterator, utree()> 58 { 59 typedef boost::iterator_range<utree::const_iterator> utree_list; 60 61 karma::rule<Iterator, utree()> 62 start, ref_; 63 64 karma::rule<Iterator, utree_list()> 65 list; 66 67 karma::rule<Iterator, utf8_symbol_range_type()> 68 symbol; 69 70 karma::rule<Iterator, utree::nil_type()> 71 nil_; 72 73 karma::rule<Iterator, utf8_string_range_type()> 74 utf8; 75 76 karma::rule<Iterator, binary_range_type()> 77 binary; 78 generatorsexpr::generator79 generator() : generator::base_type(start) 80 { 81 using standard::char_; 82 using standard::string; 83 using karma::bool_generator; 84 using karma::uint_generator; 85 using karma::double_; 86 using karma::int_; 87 using karma::lit; 88 using karma::right_align; 89 90 uint_generator<unsigned char, 16> hex2; 91 bool_generator<bool, bool_output_policies> boolean; 92 93 start = nil_ 94 | double_ 95 | int_ 96 | boolean 97 | utf8 98 | symbol 99 | binary 100 | list 101 | ref_; 102 103 ref_ = start; 104 105 list = '(' << -(start % ' ') << ')'; 106 107 utf8 = '"' << *(&char_('"') << "\\\"" | char_) << '"'; 108 109 symbol = string; 110 111 binary = '#' << *right_align(2, '0')[hex2] << '#'; 112 113 nil_ = karma::attr_cast(lit("nil")); 114 115 start.name("sexpr"); 116 ref_.name("ref"); 117 list.name("list"); 118 utf8.name("string"); 119 symbol.name("symbol"); 120 binary.name("binary"); 121 nil_.name("nil"); 122 } 123 }; 124 125 } // sexpr 126 127 #endif // BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP 128 129