2

Let's say we want to parse a recursive block like this. When "skip_comments_tag" is prefixed to the block, we skip all comments(/*...*/) within this block recursively.

{
    {}
    {
        skip_comments_tag{
            {} /*comments*/ 
            { /*comments*/ } 
        }
    }
}

It's easy to come up with a recursive parser as in Coliru.

namespace Parser {
    auto const ruleComment = x3::lit("/*") >> *(x3::char_ - "*/") >> "*/" | x3::space;

    x3::rule<struct SBlockId> const ruleBlock;
    auto const ruleBlock_def = x3::lit('{') >> *(ruleBlock | "skip_comments_tag" >> x3::skip(ruleComment)[ruleBlock]) >> '}';

    BOOST_SPIRIT_DEFINE(ruleBlock)
}

But it doesn't compile (when the parse function is called) because it will generate an infinite context (by x3::make_context in x3::skip_directive). x3::no_case and x3::with also have this problem because they all use x3::make_context in the implementation.

Questions:

  1. Is there always a better way to write parsers for this kind of questions to avoid such compile error and how?
  2. Or is the x3::make_context implementation considered to be flawed for this kind of questions?
wanghan02
  • 1,227
  • 7
  • 14

1 Answers1

1

Honestly, I do think this is a limitation in the make_context facility, and yes, it has bitten me before.

You might be able to skirt it by using TU separation (BOOST_SPIRIT_DECLARE, BOOST_SPIRIT_DEFINE and BOOST_SPIRIT_INSTANTIATE macros).

Honestly, I'd report it at the mailing list: [spirit-general]

See also http://boost.2283326.n4.nabble.com/Horrible-compiletimes-and-memory-usage-while-compiling-a-parser-with-X3-td4689104i20.html (FWIW I feel the "sequence partitioning" issue is unrelated)

sehe
  • 374,641
  • 47
  • 450
  • 633