
Hi Yury,
Thanks, we were close this season but the injuries to our star players hurt us badly.
Ok for the parser question, I would have an alternation that allowed any of those groups to be parsed in any order. Then call the production that contains that alternation with a ZeroOrMore(), which gives it a quantifier. This would effectively allow zero to many groups to be defined in any order.
Now in a root production that calls into those productions, use an OnSuccess callback on one of the root terms. That callback will get an IParserState passed to it. You can look at the state.AstNodeBuilder.Matches to see what AST nodes it constructed. Build up a dictionary of which groups you require. Then loop through the AST to see which were defined and flag those as defined in your dictionary (perhaps by removing items as you go from it). If there are any left, then use the state.ReportError method to report the error in the resulting parse data and make the error range be the end of the document. If you set up your language to support squiggles for errors, you should see the error show up when appropriate.
I hope that helps!