sexpr_generator.hpp 3.2 KB

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