ValueParser.hpp
1 #pragma once
2 #ifndef Q_MOC_RUN
3 //#define BOOST_SPIRIT_DEBUG
4 // see https://svn.boost.org/trac/boost/ticket/11875
5 #if defined(_GLIBCXX_DEBUG)
6 #define BOOST_PHOENIX_USING_LIBCPP
7 #endif
8 
9 // see https://github.com/boostorg/iostreams/pull/106
10 #define BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED
11 #include <boost/config.hpp>
12 /*
13 #include <boost/iostreams/detail/config/fpos.hpp>
14 #if defined(BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS)
15 #undef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
16 #endif
17 */
18 #include <State/Value.hpp>
19 
20 #include <ossia/network/base/name_validation.hpp>
21 #include <ossia/network/dataspace/dataspace_parse.hpp>
22 
23 #include <boost/fusion/adapted.hpp>
24 #include <boost/fusion/include/at.hpp>
25 #include <boost/fusion/sequence/intrinsic/at.hpp>
26 #include <boost/spirit/include/qi.hpp>
27 #include <boost/spirit/include/qi_eoi.hpp>
28 #include <boost/spirit/include/qi_lit.hpp>
29 #include <boost/spirit/include/qi_real.hpp>
30 #include <boost/spirit/repository/include/qi_confix.hpp>
31 #include <boost/variant/recursive_wrapper.hpp>
32 
33 #include <QString>
34 #endif
35 
36 // Taken from boost doc, necessary to have support of QString
37 namespace boost
38 {
39 namespace spirit
40 {
41 namespace traits
42 {
43 // Make Qi recognize QString as a container
44 template <>
45 struct is_container<QString> : mpl::true_
46 {
47 };
48 
49 // Expose the container's (QString's) value_type
50 template <>
51 struct container_value<QString> : mpl::identity<QChar>
52 {
53 };
54 
55 // Define how to insert a new element at the end of the container (QString)
56 template <>
57 struct push_back_container<QString, QChar>
58 {
59  static bool call(QString& c, QChar const& val)
60  {
61  c.append(val);
62  return true;
63  }
64 };
65 
66 // Test if a QString is empty (required for debug)
67 template <>
68 struct is_empty_container<QString>
69 {
70  static bool call(QString const& c) { return c.isEmpty(); }
71 };
72 
73 // Define how to stream a QString (required for debug)
74 template <typename Out, typename Enable>
75 struct print_attribute_debug<Out, QString, Enable>
76 {
77  static void call(Out& out, QString const& val) { out << val.toStdString(); }
78 };
79 }
80 }
81 }
82 
83 namespace
84 {
86 namespace qi = boost::spirit::qi;
87 
88 using boost::spirit::qi::rule;
89 
91 struct BoolParse_map : qi::symbols<char, bool>
92 {
93  BoolParse_map() { add("true", true)("false", false); }
94 };
95 template <typename Iterator>
96 struct Value_parser : qi::grammar<Iterator, ossia::value()>
97 {
98  Value_parser()
99  : Value_parser::base_type(start)
100  {
101  using boost::spirit::int_;
102  using boost::spirit::qi::char_;
103  using boost::spirit::qi::real_parser;
104  using boost::spirit::qi::skip;
105  using qi::alnum;
106 
107  char_parser %= "'" >> (char_ - "'") >> "'";
108  str_parser %= '"' >> qi::lexeme[*(char_ - '"')] >> '"';
109 
110  // FIXME does not support empty list [ ]
111  list_parser %= skip(boost::spirit::standard::space)["[" >> start % "," >> "]"];
112  start %= real_parser<float, boost::spirit::qi::strict_real_policies<float>>() | int_
113  | bool_parser | char_parser | str_parser | list_parser;
114  }
115 
116  BoolParse_map bool_parser;
117 
118  qi::rule<Iterator, std::vector<ossia::value>()> list_parser;
119  qi::rule<Iterator, char()> char_parser;
120  qi::rule<Iterator, std::string()> str_parser;
121  qi::rule<Iterator, ossia::value()> start;
122 };
123 }
Definition: lv2_atom_helpers.hpp:99