1 // Copyright (c) 2005 Carl Barron. Distributed under the Boost 2 // Software License, Version 1.0. (See accompanying file 3 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5 #ifndef XML_G_H 6 #define XML_G_H 7 #define BOOST_SPIRIT_DEBUG 8 #ifndef BOOST_SPIRIT_CLOSURE_LIMIT 9 #define BOOST_SPIRIT_CLOSURE_LIMIT 10 10 #endif 11 12 #ifndef PHOENIX_LIMIT 13 #define PHOENIX_LIMIT 10 14 #endif 15 16 #if BOOST_SPIRIT_CLOSURE_LIMIT < 6 17 #undef BOOST_SPIRIT_CLOSURE_LIMIT 18 #define BOOST_SPIRIT_CLOSURE_LIMIT 6 19 #endif 20 21 #if PHOENIX_LIMIT < BOOST_SPIRIT_CLOSURE_LIMIT 22 #undef PHOENIX_LIMIT 23 #define PHOENIX_LIMIT BOOST_SPIRIT_CLOSURE_LIMIT 24 #endif 25 26 #if 0 27 #ifdef BOOST_SPIRIT_DEBUG_FLAGS 28 #undef BOOST_SPIRIT_DEBUG_FLAGS 29 #endif 30 #define BOOST_SPIRIT_DEBUG_FLAGS (BOOST_SPIRIT_DEBUG_FLAGS_MAX - BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES) 31 #endif 32 33 #include <boost/spirit/include/classic_core.hpp> 34 #include <boost/spirit/include/classic_attribute.hpp> 35 #include <boost/spirit/include/phoenix1.hpp> 36 #include "tag.hpp" 37 #include "actions.hpp" 38 #include <boost/variant.hpp> 39 40 #include <string> 41 #include <utility> 42 43 namespace SP = BOOST_SPIRIT_CLASSIC_NS; 44 using phoenix::arg1; 45 using phoenix::arg2; 46 using phoenix::construct_; 47 using phoenix::var; 48 49 struct str_cls:SP::closure<str_cls,std::string> 50 { member1 value;}; 51 52 struct attrib_cls:SP::closure 53 < 54 attrib_cls, 55 std::pair<std::string,std::string>, 56 std::string, 57 std::string 58 > 59 { 60 member1 value; 61 member2 first; 62 member3 second; 63 }; 64 65 struct tagged_cls:SP::closure 66 < 67 tagged_cls, 68 tag, 69 std::string, 70 std::map<std::string,std::string>, 71 std::list<typename tag::variant_type> 72 > 73 { 74 member1 value; 75 member2 ID; 76 member3 attribs; 77 member4 children; 78 }; 79 80 struct xml_g:SP::grammar<xml_g> 81 { 82 std::list<tag> &tags; xml_gxml_g83 xml_g(std::list<tag> &a):tags(a){} 84 template <class Scan> 85 struct definition 86 { definitionxml_g::definition87 definition(const xml_g &s) 88 { 89 white = +SP::space_p 90 ; 91 92 tagged = (start_tag 93 >> *inner 94 >> end_tag 95 | simple_start_tag 96 ) 97 [store_tag(tagged.value,tagged.ID,tagged.attribs, 98 tagged.children)] 99 ; 100 101 end_tag = SP::str_p("</") 102 >> SP::f_str_p(tagged.ID) 103 >> '>' 104 ; 105 106 inner = (tagged 107 | str) [push_child(tagged.children,arg1)] 108 ; 109 110 str = SP::lexeme_d[+(SP::anychar_p - '<')] 111 [str.value=construct_<std::string>(arg1,arg2)] 112 ; 113 114 top = +tagged 115 [push_back(var(s.tags),arg1)] 116 ; 117 118 starter = SP::ch_p('<') 119 >> SP::lexeme_d[+SP::alpha_p] 120 [tagged.ID = construct_<std::string>(arg1,arg2)] 121 >> *attrib 122 [store_in_map(tagged.attribs,arg1)] 123 >> !white 124 ; 125 start_tag = starter 126 >> '>' 127 ; 128 129 simple_start_tag = starter 130 >> "/>" 131 ; 132 133 attrib = white 134 >>SP::lexeme_d[+SP::alpha_p] 135 [attrib.first = construct_<std::string>(arg1,arg2)] 136 >> !white 137 >> '=' 138 >> !white 139 >> '"' 140 >> SP::lexeme_d[+(SP::anychar_p - '"')] 141 [attrib.second = construct_<std::string>(arg1,arg2)] 142 >> SP::ch_p('"') 143 [attrib.value = construct_ 144 < 145 std::pair 146 < 147 std::string, 148 std::string 149 > 150 >(attrib.first,attrib.second)] 151 ; 152 BOOST_SPIRIT_DEBUG_RULE(tagged); 153 BOOST_SPIRIT_DEBUG_RULE(end_tag); 154 BOOST_SPIRIT_DEBUG_RULE(inner); 155 BOOST_SPIRIT_DEBUG_RULE(str); 156 BOOST_SPIRIT_DEBUG_RULE(top); 157 BOOST_SPIRIT_DEBUG_RULE(start_tag); 158 BOOST_SPIRIT_DEBUG_RULE(attrib); 159 BOOST_SPIRIT_DEBUG_RULE(white); 160 BOOST_SPIRIT_DEBUG_RULE(starter); 161 BOOST_SPIRIT_DEBUG_RULE(simple_start_tag); 162 } 163 164 // actions 165 push_back_f push_back; 166 push_child_f push_child; 167 store_in_map_f store_in_map; 168 store_tag_f store_tag; 169 // rules 170 SP::rule<Scan,tagged_cls::context_t> tagged; 171 SP::rule<Scan> end_tag; 172 SP::rule<Scan> inner; 173 SP::rule<Scan,str_cls::context_t> str; 174 SP::rule<Scan> top; 175 SP::rule<Scan> starter; 176 SP::rule<Scan> simple_start_tag; 177 SP::rule<Scan> start_tag; 178 SP::rule<Scan> white; 179 SP::rule<Scan,attrib_cls::context_t> attrib; startxml_g::definition180 SP::rule<Scan> const &start() const 181 { return top;} 182 }; 183 }; 184 185 #endif 186 187