blob: fb0a4c614e9e7586dd6e86f403174fcaece14711 [file] [log] [blame]
// 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 <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_attribute.hpp>
#include <boost/spirit/include/phoenix1.hpp>
#include "tag.hpp"
#include "actions.hpp"
#include <boost/variant.hpp>
#include <string>
#include <utility>
namespace SP = BOOST_SPIRIT_CLASSIC_NS;
using phoenix::arg1;
using phoenix::arg2;
using phoenix::construct_;
using phoenix::var;
struct str_cls:SP::closure<str_cls,std::string>
{ member1 value;};
struct attrib_cls:SP::closure
<
attrib_cls,
std::pair<std::string,std::string>,
std::string,
std::string
>
{
member1 value;
member2 first;
member3 second;
};
struct tagged_cls:SP::closure
<
tagged_cls,
tag,
std::string,
std::map<std::string,std::string>,
std::list<typename tag::variant_type>
>
{
member1 value;
member2 ID;
member3 attribs;
member4 children;
};
struct xml_g:SP::grammar<xml_g>
{
std::list<tag> &tags;
xml_g(std::list<tag> &a):tags(a){}
template <class Scan>
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_<std::string>(arg1,arg2)]
;
top = +tagged
[push_back(var(s.tags),arg1)]
;
starter = SP::ch_p('<')
>> SP::lexeme_d[+SP::alpha_p]
[tagged.ID = construct_<std::string>(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_<std::string>(arg1,arg2)]
>> !white
>> '='
>> !white
>> '"'
>> SP::lexeme_d[+(SP::anychar_p - '"')]
[attrib.second = construct_<std::string>(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<Scan,tagged_cls::context_t> tagged;
SP::rule<Scan> end_tag;
SP::rule<Scan> inner;
SP::rule<Scan,str_cls::context_t> str;
SP::rule<Scan> top;
SP::rule<Scan> starter;
SP::rule<Scan> simple_start_tag;
SP::rule<Scan> start_tag;
SP::rule<Scan> white;
SP::rule<Scan,attrib_cls::context_t> attrib;
SP::rule<Scan> const &start() const
{ return top;}
};
};
#endif