// Copyright (c) 2005 Carl Barron. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef XML_G_H #define XML_G_H #define BOOST_SPIRIT_DEBUG #ifndef BOOST_SPIRIT_CLOSURE_LIMIT #define BOOST_SPIRIT_CLOSURE_LIMIT 10 #endif #ifndef PHOENIX_LIMIT #define PHOENIX_LIMIT 10 #endif #if BOOST_SPIRIT_CLOSURE_LIMIT < 6 #undef BOOST_SPIRIT_CLOSURE_LIMIT #define BOOST_SPIRIT_CLOSURE_LIMIT 6 #endif #if PHOENIX_LIMIT < BOOST_SPIRIT_CLOSURE_LIMIT #undef PHOENIX_LIMIT #define PHOENIX_LIMIT BOOST_SPIRIT_CLOSURE_LIMIT #endif #if 0 #ifdef BOOST_SPIRIT_DEBUG_FLAGS #undef BOOST_SPIRIT_DEBUG_FLAGS #endif #define BOOST_SPIRIT_DEBUG_FLAGS (BOOST_SPIRIT_DEBUG_FLAGS_MAX - BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES) #endif #include #include #include #include "tag.hpp" #include "actions.hpp" #include #include #include namespace SP = BOOST_SPIRIT_CLASSIC_NS; using phoenix::arg1; using phoenix::arg2; using phoenix::construct_; using phoenix::var; struct str_cls:SP::closure { member1 value;}; struct attrib_cls:SP::closure < attrib_cls, std::pair, std::string, std::string > { member1 value; member2 first; member3 second; }; struct tagged_cls:SP::closure < tagged_cls, tag, std::string, std::map, std::list > { member1 value; member2 ID; member3 attribs; member4 children; }; struct xml_g:SP::grammar { std::list &tags; xml_g(std::list &a):tags(a){} template struct definition { definition(const xml_g &s) { white = +SP::space_p ; tagged = (start_tag >> *inner >> end_tag | simple_start_tag ) [store_tag(tagged.value,tagged.ID,tagged.attribs, tagged.children)] ; end_tag = SP::str_p("> SP::f_str_p(tagged.ID) >> '>' ; inner = (tagged | str) [push_child(tagged.children,arg1)] ; str = SP::lexeme_d[+(SP::anychar_p - '<')] [str.value=construct_(arg1,arg2)] ; top = +tagged [push_back(var(s.tags),arg1)] ; starter = SP::ch_p('<') >> SP::lexeme_d[+SP::alpha_p] [tagged.ID = construct_(arg1,arg2)] >> *attrib [store_in_map(tagged.attribs,arg1)] >> !white ; start_tag = starter >> '>' ; simple_start_tag = starter >> "/>" ; attrib = white >>SP::lexeme_d[+SP::alpha_p] [attrib.first = construct_(arg1,arg2)] >> !white >> '=' >> !white >> '"' >> SP::lexeme_d[+(SP::anychar_p - '"')] [attrib.second = construct_(arg1,arg2)] >> SP::ch_p('"') [attrib.value = construct_ < std::pair < std::string, std::string > >(attrib.first,attrib.second)] ; BOOST_SPIRIT_DEBUG_RULE(tagged); BOOST_SPIRIT_DEBUG_RULE(end_tag); BOOST_SPIRIT_DEBUG_RULE(inner); BOOST_SPIRIT_DEBUG_RULE(str); BOOST_SPIRIT_DEBUG_RULE(top); BOOST_SPIRIT_DEBUG_RULE(start_tag); BOOST_SPIRIT_DEBUG_RULE(attrib); BOOST_SPIRIT_DEBUG_RULE(white); BOOST_SPIRIT_DEBUG_RULE(starter); BOOST_SPIRIT_DEBUG_RULE(simple_start_tag); } // actions push_back_f push_back; push_child_f push_child; store_in_map_f store_in_map; store_tag_f store_tag; // rules SP::rule tagged; SP::rule end_tag; SP::rule inner; SP::rule str; SP::rule top; SP::rule starter; SP::rule simple_start_tag; SP::rule start_tag; SP::rule white; SP::rule attrib; SP::rule const &start() const { return top;} }; }; #endif