xml_g.hpp 5.0 KB

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