Boost Qi Composing rules using Functions

前端 未结 1 376
一向
一向 2021-01-22 03:56

I\'m trying to define some Boost::spirit::qi parsers for multiple subsets of a language with minimal code duplication. To do this, I created a few basic rule building functions.

相关标签:
1条回答
  • 2021-01-22 04:39

    Quite simply: using auto with Spirit (or any EDSL based on Boost Proto and Boost Phoenix) is most likely Undefined Behaviour¹

    Now, you can usually fix this using

    • BOOST_SPIRIT_AUTO
    • boost::proto::deep_copy
    • the new facility that's coming in the most recent version of Boost (TODO add link)

    In this case,

    template<typename AttrName, typename Value>
    auto attribute(AttrName attrName, Value value) {
        return boost::proto::deep_copy(attrName >> ':' >> value);
    }
    

    fixes it: Live On Coliru

    Alternatively

    1. you could use qi::lazy[] with inherited attributes.

      I do very similar things in the prop_key rule in Reading JSON file with C++ and BOOST.

    2. you could have a look at the Keyword List Operator from the Spirit Repository. It's designed to allow easier construction of grammars like:

      no_constraint_person_rule %=
          kwd("name")['=' > parse_string ]
        / kwd("age")   ['=' > int_]
        / kwd("size")   ['=' > double_ > 'm']
        ;
      
    3. This you could potentially combine with the Nabialek Trick. I'd search the answers on SO for examples. (One is Grammar balancing issue)


    ¹ Except for entirely stateless actors (Eric Niebler on this) and expression placeholders. See e.g.

    • Assigning parsers to auto variables
    • undefined behaviour somewhere in boost::spirit::qi::phrase_parse
    • C++ Boost qi recursive rule construction
    • boost spirit V2 qi bug associated with optimization level

    Some examples

    • Define parsers parameterized with sub-parsers in Boost Spirit
    • Generating Spirit parser expressions from a variadic list of alternative parser expressions
    0 讨论(0)
提交回复
热议问题