tree_to_xml.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 183 行

CPP
183
字号
/*=============================================================================    Copyright (c) 2001-2007 Hartmut Kaiser    http://spirit.sourceforge.net/    Use, modification and distribution is subject to 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)=============================================================================*/#include <boost/detail/lightweight_test.hpp>#include <boost/iostreams/stream.hpp>#include <boost/preprocessor/cat.hpp>#include <boost/spirit/include/classic_core.hpp> #include <boost/spirit/include/classic_ast.hpp> #include <boost/spirit/include/classic_tree_to_xml.hpp> #include <iostream>#include <fstream>#include <string>using namespace BOOST_SPIRIT_CLASSIC_NS; ///////////////////////////////////////////////////////////////////////////////struct calculator : public grammar<calculator>{    static const int integerID = 1;    static const int factorID = 2;    static const int termID = 3;    static const int expressionID = 4;    template <typename ScannerT>    struct definition    {        definition(calculator const& /*self*/)        {            //  Start grammar definition            integer     =   leaf_node_d[ lexeme_d[                                (!ch_p('-') >> +digit_p)                            ] ];            factor      =   integer                        |   inner_node_d[ch_p('(') >> expression >> ch_p(')')]                        |   (root_node_d[ch_p('-')] >> factor);            term        =   factor >>                            *(  (root_node_d[ch_p('*')] >> factor)                              | (root_node_d[ch_p('/')] >> factor)                            );            expression  =   term >>                            *(  (root_node_d[ch_p('+')] >> term)                              | (root_node_d[ch_p('-')] >> term)                            );            //  End grammar definition            // turn on the debugging info.            BOOST_SPIRIT_DEBUG_RULE(integer);            BOOST_SPIRIT_DEBUG_RULE(factor);            BOOST_SPIRIT_DEBUG_RULE(term);            BOOST_SPIRIT_DEBUG_RULE(expression);        }        rule<ScannerT, parser_context<>, parser_tag<expressionID> >   expression;        rule<ScannerT, parser_context<>, parser_tag<termID> >         term;        rule<ScannerT, parser_context<>, parser_tag<factorID> >       factor;        rule<ScannerT, parser_context<>, parser_tag<integerID> >      integer;        rule<ScannerT, parser_context<>, parser_tag<expressionID> > const&        start() const { return expression; }    };};////////////////////////////////////////////////////////////////////////////////// this is a Boost.IoStreams source device usable to create a istream on /// top of a random access container (i.e. vector<>)template<typename Container>class container_device {public:    typedef typename Container::value_type char_type;    typedef boost::iostreams::sink_tag category;        container_device(Container& container)       : container_(container), pos_(0)    {}    /// Write up to n characters to the underlying data sink into the     /// buffer s, returning the number of characters written    std::streamsize write(const char_type* s, std::streamsize n)    {        std::streamsize result = 0;        if (pos_ != container_.size()) {            std::streamsize amt =                 static_cast<std::streamsize>(container_.size() - pos_);            std::streamsize result = (std::min)(n, amt);            std::copy(s, s + result, container_.begin() + pos_);            pos_ += result;        }        if (result < n) {            container_.insert(container_.end(), s, s + n);            pos_ = container_.size();        }        return n;    }    Container& container() { return container_; }    private:    typedef typename Container::size_type size_type;    Container& container_;    size_type pos_;};///////////////////////////////////////////////////////////////////////////////#define EXPECTED_XML_OUTPUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\<!DOCTYPE parsetree SYSTEM \"parsetree.dtd\">\n\<!-- 1+2 -->\n\<parsetree version=\"1.0\">\n\    <parsenode>\n\        <value>+</value>\n\        <parsenode>\n\            <value>1</value>\n\        </parsenode>\n\        <parsenode>\n\            <value>2</value>\n\        </parsenode>\n\    </parsenode>\n\</parsetree>\n"#define EXPECTED_XML_OUTPUT_WIDE BOOST_PP_CAT(L, EXPECTED_XML_OUTPUT)bool test(wchar_t const *text){    typedef std::basic_string<wchar_t>::iterator iterator_t;     typedef tree_match<iterator_t> parse_tree_match_t;     typedef parse_tree_match_t::tree_iterator iter_t;     std::basic_string<wchar_t> input(text);     calculator calc;     tree_parse_info<iterator_t> ast_info =         ast_parse(iterator_t(input.begin()), iterator_t(input.end()),             calc >> end_p, space_p);     std::basic_string<wchar_t> out;    {        typedef container_device<std::basic_string<wchar_t> > device_type;        boost::iostreams::stream<device_type> outsink(out);        basic_tree_to_xml<wchar_t>(outsink, ast_info.trees, input);     }    return out == EXPECTED_XML_OUTPUT_WIDE;} bool test(char const *text){    typedef std::string::iterator iterator_t;     typedef tree_match<iterator_t> parse_tree_match_t;     typedef parse_tree_match_t::tree_iterator iter_t;     std::string input(text);     calculator calc;     tree_parse_info<iterator_t> ast_info =         ast_parse(iterator_t(input.begin()), iterator_t(input.end()),             calc >> end_p, space_p);     std::string out;    {        typedef container_device<std::string> device_type;        boost::iostreams::stream<device_type> outsink(out);        basic_tree_to_xml<char>(outsink, ast_info.trees, input);     }    return out == EXPECTED_XML_OUTPUT;} int main() {     BOOST_TEST(test("1+2"));    if (std::has_facet<std::ctype<wchar_t> >(std::locale()))    {        BOOST_TEST(test(L"1+2"));    }    return boost::report_errors();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?