tree_to_xml.ipp
来自「Boost provides free peer-reviewed portab」· IPP 代码 · 共 527 行 · 第 1/2 页
IPP
527 行
<< impl::string_lit<CharT>::get("<") << tag << attr1 << attr2 << impl::string_lit<CharT>::get(">") << encode(textlit) << impl::string_lit<CharT>::get("</") << tag << impl::string_lit<CharT>::get(">\n"); } }; // a xml comment template <typename CharT> class comment : public element<CharT> { public: comment (std::basic_ostream<CharT> &ostrm_, std::basic_string<CharT> const& commentlit) : element<CharT>(ostrm_, false) { if ('\0' != commentlit[0]) { this->output_space(); this->ostrm << impl::string_lit<CharT>::get("<!-- ") << encode(commentlit) << impl::string_lit<CharT>::get(" -->\n"); } } }; // a xml document template <typename CharT> class document : public element<CharT> { public: document (std::basic_ostream<CharT> &ostrm_) : element<CharT>(ostrm_) { this->get_indent() = -1; this->ostrm << impl::string_lit<CharT>::get( "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); } document (std::basic_ostream<CharT> &ostrm_, std::basic_string<CharT> const& mainnode, std::basic_string<CharT> const& dtd) : element<CharT>(ostrm_) { this->get_indent() = -1; this->ostrm << impl::string_lit<CharT>::get( "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); this->output_space(); this->ostrm << impl::string_lit<CharT>::get("<!DOCTYPE ") << mainnode << impl::string_lit<CharT>::get(" SYSTEM \"") << dtd << impl::string_lit<CharT>::get("\">\n"); } ~document() { BOOST_SPIRIT_ASSERT(-1 == this->get_indent()); } };} // end of namespace xmlnamespace impl { /////////////////////////////////////////////////////////////////////////// // look up the rule name from the given parser_id template <typename AssocContainerT> inline typename AssocContainerT::value_type::second_type get_rulename (AssocContainerT const &id_to_name_map, BOOST_SPIRIT_CLASSIC_NS::parser_id const &id) { typename AssocContainerT::const_iterator it = id_to_name_map.find(id); if (it != id_to_name_map.end()) return (*it).second; typedef typename AssocContainerT::value_type::second_type second_t; return second_t(); } // dump a parse tree as xml template < typename CharT, typename IteratorT, typename GetIdT, typename GetValueT > inline void token_to_xml (std::basic_ostream<CharT> &ostrm, IteratorT const &it, bool is_root, GetIdT const &get_token_id, GetValueT const &get_token_value) { BOOST_SPIRIT_OSSTREAM stream; stream << get_token_id(*it) << std::ends; xml::attribute<CharT> token_id ( impl::string_lit<CharT>::get("id"), BOOST_SPIRIT_GETSTRING(stream).c_str()); xml::attribute<CharT> is_root_attr ( impl::string_lit<CharT>::get("is_root"), impl::string_lit<CharT>::get(is_root ? "1" : "")); xml::attribute<CharT> nil; xml::text<CharT>(ostrm, impl::string_lit<CharT>::get("token"), get_token_value(*it).c_str(), token_id, is_root_attr.has_value() ? is_root_attr : nil); } template < typename CharT, typename TreeNodeT, typename AssocContainerT, typename GetIdT, typename GetValueT > inline void tree_node_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &node, AssocContainerT const& id_to_name_map, GetIdT const &get_token_id, GetValueT const &get_token_value) { typedef typename TreeNodeT::const_iterator node_iter_t; typedef typename TreeNodeT::value_type::parse_node_t::const_iterator_t value_iter_t; xml::attribute<CharT> nil; node_iter_t end = node.end(); for (node_iter_t it = node.begin(); it != end; ++it) { // output a node xml::attribute<CharT> id ( impl::string_lit<CharT>::get("rule"), get_rulename(id_to_name_map, (*it).value.id()).c_str()); xml::node<CharT> currnode (ostrm, impl::string_lit<CharT>::get("parsenode"), (*it).value.id() != 0 && id.has_value() ? id : nil); // first dump the value std::size_t cnt = std::distance((*it).value.begin(), (*it).value.end()); if (1 == cnt) { token_to_xml (ostrm, (*it).value.begin(), (*it).value.is_root(), get_token_id, get_token_value); } else if (cnt > 1) { xml::node<CharT> value (ostrm, impl::string_lit<CharT>::get("value")); bool is_root = (*it).value.is_root(); value_iter_t val_end = (*it).value.end(); for (value_iter_t val_it = (*it).value.begin(); val_it != val_end; ++val_it) { token_to_xml (ostrm, val_it, is_root, get_token_id, get_token_value); } } tree_node_to_xml(ostrm, (*it).children, id_to_name_map, get_token_id, get_token_value); // dump all subnodes } } template <typename CharT, typename TreeNodeT, typename AssocContainerT> inline void tree_node_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &node, AssocContainerT const& id_to_name_map) { typedef typename TreeNodeT::const_iterator node_iter_t; xml::attribute<CharT> nil; node_iter_t end = node.end(); for (node_iter_t it = node.begin(); it != end; ++it) { // output a node xml::attribute<CharT> id ( impl::string_lit<CharT>::get("rule"), get_rulename(id_to_name_map, (*it).value.id()).c_str()); xml::node<CharT> currnode (ostrm, impl::string_lit<CharT>::get("parsenode"), (*it).value.id() != parser_id() && id.has_value() ? id : nil); // first dump the value if ((*it).value.begin() != (*it).value.end()) { std::basic_string<CharT> tokens ((*it).value.begin(), (*it).value.end()); if (tokens.size() > 0) { // output all subtokens as one string (for better readability) xml::attribute<CharT> is_root ( impl::string_lit<CharT>::get("is_root"), impl::string_lit<CharT>::get((*it).value.is_root() ? "1" : "")); xml::text<CharT>(ostrm, impl::string_lit<CharT>::get("value"), tokens.c_str(), is_root.has_value() ? is_root : nil); } } // dump all subnodes tree_node_to_xml(ostrm, (*it).children, id_to_name_map); } }} // namespace impl///////////////////////////////////////////////////////////////////////////////// dump a parse tree as a xml stream (generic variant)template < typename CharT, typename TreeNodeT, typename AssocContainerT, typename GetIdT, typename GetValueT>inline voidbasic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree,std::basic_string<CharT> const &input_line, AssocContainerT const& id_to_name, GetIdT const &get_token_id, GetValueT const &get_token_value){ // generate xml dump xml::document<CharT> doc (ostrm, impl::string_lit<CharT>::get("parsetree"), impl::string_lit<CharT>::get("parsetree.dtd")); xml::comment<CharT> input (ostrm, input_line.c_str()); xml::attribute<CharT> ver ( impl::string_lit<CharT>::get("version"), impl::string_lit<CharT>::get("1.0")); xml::node<CharT> mainnode (ostrm, impl::string_lit<CharT>::get("parsetree"), ver); impl::tree_node_to_xml (ostrm, tree, id_to_name, get_token_id, get_token_value);}// dump a parse tree as a xml steam (for character based parsers)template <typename CharT, typename TreeNodeT, typename AssocContainerT>inline voidbasic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, std::basic_string<CharT> const &input_line, AssocContainerT const& id_to_name){ // generate xml dump xml::document<CharT> doc (ostrm, impl::string_lit<CharT>::get("parsetree"), impl::string_lit<CharT>::get("parsetree.dtd")); xml::comment<CharT> input (ostrm, input_line.c_str()); xml::attribute<CharT> ver ( impl::string_lit<CharT>::get("version"), impl::string_lit<CharT>::get("1.0")); xml::node<CharT> mainnode (ostrm, impl::string_lit<CharT>::get("parsetree"), ver); impl::tree_node_to_xml(ostrm, tree, id_to_name);}template <typename CharT, typename TreeNodeT>inline voidbasic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, std::basic_string<CharT> const &input_line){ return basic_tree_to_xml<CharT>(ostrm, tree, input_line, std::map<BOOST_SPIRIT_CLASSIC_NS::parser_id, std::basic_string<CharT> >());}BOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace boost::spirit#undef BOOST_SPIRIT_OSSTREAM#undef BOOST_SPIRIT_GETSTRING#endif // !defined(PARSE_TREE_XML_HPP)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?