Re: X3: Using dynamic Repetition Parser Directives

Seth <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
On 01-02-16 08:50, Seth wrote:
>
> That said, I think you're far better off writing a custom parser here.

Just for fun, added that too:

http://coliru.stacked-crooked.com/a/87053f2f3f00862d

    #include <iostream>
    #include <boost/spirit/home/x3.hpp>
    #include <boost/fusion/adapted/std_tuple.hpp>
    #include <boost/spirit/home/x3/binary.hpp>

    namespace x3 = boost::spirit::x3;

    namespace hessian {

        typedef std::string string_t;

        namespace parser {

            struct bstring : x3::parser<bstring> {
                using attribute_type = hessian::string_t;

                // string ::= s b1 b0 <utf8-data> string
                //       ::= S b1 b0 <utf8-data>
                //       ::= [x00-x1f] <utf8-data>
                // NOTE: The length means number of UTF16 characters but
    the content is given in UTF8 characters!
                template <typename It, typename Ctx, typename Attr>
                    bool parse(It& f, It const& l, Ctx&,
    x3::unused_type, Attr& attr) const {
                        auto saved = f;
                        char type;
                        size_t len;
                        auto tied = std::tie(type, len);

                        while (x3::parse(f,l,x3::char_("sS") >>
    x3::big_word,tied)) {
                            if
    (!x3::parse(f,l,x3::repeat(len)[x3::char_],attr))
                                break;
                            if (type == 'S')
                                return true;
                        }

                        f = saved;
                        return false;
                    }
            };

        }
    }

    #include <iomanip>

    std::string as_hex(std::string const& what) {
        std::ostringstream oss;
        oss << std::hex << std::setfill('0');
        for (uint8_t ch : what) {
            if (std::isprint(ch)) oss << ch;
            else                  oss << "\\x" << std::setw(2) << int{ch};
        }

        return oss.str();
    }

    void test_string() {
        const std::string text("s\x00\x07hello, S\x00\x05world", 18);
        try {
            hessian::string_t attr;
            auto f = text.begin(), l = text.end();
            bool ok = x3::parse(f, l, x3::eps >
    hessian::parser::bstring{}, attr);

            if (ok)
                std::cout << "Parsed: '" << as_hex(attr) << "'\n";
            else
                std::cout << "Failed\n";

            if(f!=l)
                std::cout << "Remaining: '" << as_hex({f,l}) << "'\n";

        } catch (const
    x3::expectation_failure<std::string::const_iterator> &exception) {
            std::cout << exception.what() << " " << exception.which() <<
    " " << std::string(exception.where(), text.end())
                      << std::endl;
        }
    }

    int main()
    {
        test_string();
    }

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.