Believe it or not, but I've gone thru similar path of thinking. And finally decided to settle with the solution/recommendation as I explained before. Here's the reasoning.
The parser/scanner for a language might be just a verifier - for syntactic correctness... or token type recognizer - for code colorizer. In these simple cases you don't need AST tree, parse tree is enough.
If you build interpreter, you need AST. Next, AST node of specific type represents the most generic form of language construct. Let's look at TRY, but for c#, it's easier.
Your AstTryNode would probably have properties that would contain subelements of the try: TryBody, CatchBlockList (list of nodes), FinalBlock (optional).
CatchBlockList might be empty list, or FinalBlock might be empty, but AstTryNode must still have these properties. Now, the main function of parser becomes not just describing a language in some "readable"
way, but MAPPING the input text of Try-block to the elements/properties of TryAstNode. You have to have this mapping somewhere. You may describe BNF rule for a node in several language-equivalent ways,
but if it is a set of variations, you'll have to do an extra job of mapping. I reasoned that the best way and easiest way to do this is to build one generic definition of the construct:
Try-Catch-Finally-block is a TryBlock followed by zero or more CatchBlocks followed by optional FinallyBlock. Then mapping inside AST node initializer becomes trivial.
That seems kinda giving up some freedom in grammar expressions, but you have to remember that the goal is AST construction, not nicely looking stuff.
There is one big trouble with this approach, and I still do not have a good solution for this. Writing a rule as a sequence of optional sub-clauses works ok
if each clause has distinctive starting keyword - like TRY construct. If there are no such keywords, you get shift/reduce conflicts. (this is limitation of LALR parsing algorithm, not Irony per se).
That's what happened for c# and Java grammar, that's why you see all these expanded expressions with variations, instead of a single sum of optional elements.
But for these grammars, we do not need ASTs, we needed just recognition of constructs - for colorizing the text.
Not sure how satisfying is my explanation, but that's all I have - in any case, I do not have a better solution - tried, but could not find anything satisfying.