0

Is there a better way of doing this with Spirit? I'm parsing a sequential series of key value pairs, with some line endings and other cruft in between. The format is not so consistent that I can just pull key values pairs out with a single rule. So I've got an adapter and production rules like:

BOOST_FUSION_ADAPT_STRUCT(
  Record,
  ( std::string, messageHeader )
  ( double, field1 )
  ( std::string, field2 )
  ( Type3, field3 )
  // ...
  ( TypeN, fieldN )
)

template< typename Iterator, typename Skipper >
class MyGrammar : public qi::grammar< Iterator, Record(), Skipper >
{
public:
  MyGrammar() : MyGrammar::base_type{ record }
  {
    record =
      qi::string( "Message header" )
      >> field1 >> field2
      // ...
      >> fieldN;
    field1 = qi::lit( "field 1:" ) >> qi::double_;
    // ...
  }

  // field rule declarations...
};

This is a straightforward if tedious way of going about it, and I've already exceeded the compiler's rule complexity threshold once, which forced me to refactor the fields into separate rules. Also if there's an error parsing a message, the parser always shows the error being at the beginning of the string, like the rule doesn't give it enough context to figure out where the problem actually is. I assume this is from the way the >> operator works.

Edit:

In response to sehe's question, I've run into two problems with this approach and the MSVC 15 compiler. The first was a compiler error on my top-level production when it hit somewhere in the vicinity of 80 components separated by >>:

recursive type or function dependency context too complex

So I pushed everything I could down into subordinate rules to reduce the complexity. Unfortunately now, after adding still more rules, I'm running into:

fatal error C1060: compiler is out of heap space

So I find that I do need some way to further decompose the problem that's not just a long series of concatenated production rules...

flatline
  • 42,083
  • 4
  • 31
  • 38
  • That's a lot of questions with very little code. I'll leave the "error handling" question out of scope. What is the actual question regarding the rest? What is wrong with the approach and what would you like to change? – sehe Mar 22 '19 at 17:36
  • I added some more specifics on what the problem is. I guess I'm looking for a different way to structure the grammar, because this approach is simply exceeding the compiler's resources. Unfortunately, due to an inability to share the code verbatim, and the issue having to do with a large number of rules, it will take considerable effort to create a "minimally" reproducible example. – flatline Mar 22 '19 at 18:56
  • What version of MSVC are you on? Can you use X3? I might have inspiration to help a bit there (in fact I think I already have some things lying around) – sehe Mar 23 '19 at 14:00
  • 1
    https://stackoverflow.com/questions/45673378/boost-spirit-x3-parse-into-structs/45683933#45683933 e.g. (that was back when MSVC didn't support X3 yet). Slightly similar approach https://stackoverflow.com/a/49722855/85371 – sehe Mar 23 '19 at 14:41
  • 1
    Inspiration to use Fusion to also get the field names and maybe use that to generate parser expressions: https://stackoverflow.com/questions/19657065/is-it-possible-to-generate-a-fusion-map-from-an-adapted-struct/19658340#19658340 – sehe Mar 23 '19 at 14:42
  • MSVC 15.8. The heap space issue is apparently a not-uncommon issue with some spirit grammars, and it's something that I've run into with VS2017 in other circumstances. There are a few ways to work around it, I can get my full grammar to compile with the 64-bit toolchain for example, but that is a less than ideal solution as e.g. VS Express does not have this option available. – flatline Mar 25 '19 at 17:36
  • I'm going to check out x3, this is not something I've worked with before, thanks for the other links, I'll see how they work out! – flatline Mar 25 '19 at 17:37

0 Answers0