I would like to parse about 5-10 different message types that share a common format (such as JSON, for example) but each have specific fields that need to be validated. Each message should eventually be parsed into a custom class/struct that has types that don't require any sort of casting (e.g. a field is an int instead of a variant/tuple). I see two approaches to the problem:
Write a grammar for each specific message that handles the validation for both the message format (JSON boilerplate, in this example) and validates the content of the fields, returning a truly custom struct
Write a grammar that only validates the structure (just the JSON rules) and returns a more generic object (with fields that are variants/tuples, etc.) and validate/translate at a higher level into a custom struct (casting and checking the various variant fields)
I see these as the pros and cons of each:
Pros for 1:
- All validation is done within boost::spirit
- Karma generators (if written) would look like existing spirit parsing code
Cons for 1:
- A new grammar has to be written and maintained for each new message type that may be invented in the future (and the spirit syntax is not intuitive)
Pros for 2:
- Complex spirit code is written once and rarely touched
Cons for 2:
- Validation and translation of generic message objects is going to be messy code that spirit was supposed to eliminate in the first place
Which method is preferable? Is there a third way to parse into multiple types using one grammar?
Here's some example messages and the classes they should eventually reside in:
{"messageType": "messageTypeA", "numberParam": 1}
{"messageType": "messageTypeB", "stringParam": "Test"}
class MessageTypeA
{
public:
double numberParam;
};
class MessageTypeB
{
public:
std::string stringParam;
};