Boost.Spirit.Qi crashes when assigning rule to a sequence including itself

后端 未结 1 501
长发绾君心
长发绾君心 2020-12-21 06:20

I have the following MWE:

#include 

#include 
#include 
#include &l         


        
1条回答
  •  青春惊慌失措
    2020-12-21 06:52

    I'm not sure what you were trying to achieve, but copy() would seem to be what you're after

        parser = parser.copy() >> parser2;
    

    See it Live on Coliru


    Background

    The problem is Qi takes non-terminals by reference, so you get the parser semantics a PEG grammar would suggest.

    Besides that, Proto expression trees (expression templates) do take some of their arguments by reference.

    These two combined have a potential to really mess up your life, especially when construction parsers dynamically. In short, I'd argue that, outside

    • using inherited attributes
    • and qi::symbols (including the Nabialek trick)

    constructing rules on the fly is not well supported in Spirit V2. Proto x11 / Spirit X3 may change this for the better.

    See more background here:

    • C++ Boost qi recursive rule construction
    • Generating Spirit parser expressions from a variadic list of alternative parser expressions
    • Can Boost Spirit Rules be parameterized

    Sample code

    #include 
    #include 
    #include 
    
    namespace spirit = boost::spirit;
    namespace qi = boost::spirit::qi;
    namespace phoenix = boost::phoenix;
    
    
    int main() {
    
        std::string input("1 2");
    
        qi::rule parser;
        qi::rule parser2;
        qi::rule parser3;
    
        parser = qi::int_[
            std::cerr << phoenix::val("First int: ") << qi::_1 << std::endl
        ];
    
        parser2 = qi::int_[
            std::cerr << phoenix::val("Second int: ") << qi::_1 << std::endl
        ];
    
        try {
            // Comment out these two lines, (finished below ...)
            parser3 = parser >> parser2;
            phrase_parse(input.begin(), input.end(), parser3, qi::space);
    
            parser = parser.copy() >> parser2;
            phrase_parse(input.begin(), input.end(), parser, qi::space);
        }
        catch (...) {
            std::cerr << "Exception caught." << std::endl;
        }
    
    } 
    

    0 讨论(0)
提交回复
热议问题