Turns a parsed ISO/IEC 14977 EBNF syntax into a real
%{meta_identifier_atom => Grammar.IR.expr()} map -- one Grammar.IR
tree per rule, the same target category Ichor.ABNF.Actions and
Ichor.BNF.Actions both use.
Meta-identifier names are kept exactly as written (leading/trailing
whitespace trimmed off the token's own greedy trailing-space capture
-- ISO EBNF's IDENT allows an embedded literal space, but internal
spacing, e.g. syntax rule, is preserved, since ISO EBNF really does
allow multi-word identifiers). No case-insensitivity rule the way
ABNF's RFC 5234 has one.
An empty alternative (x = 'a' | ;) is expressed as single_definition
matching zero-width via a rule-level Opt around its own body, not a
token -- Aether's own lexer never treats a zero-length match as "the
next token" (needed so tokenization itself can't stall forever on an
always-matches-empty token), so a token-based encoding of "empty"
referenced from a rule could never actually match, at any position.
The exception operator (-) is a best-effort, not a full
language-theoretic set difference. ISO EBNF's factor - exception
means "every string factor generates that exception doesn't
generate" -- true set subtraction, which Grammar.IR has no
combinator for (NotPred is PEG lookahead at the current parse
position, not "matches factor's language minus exception's").
This translates it as Seq([NotPred(exception), factor]): reject
first if exception would also match here, then require factor --
correct when the excluded language is a lookahead-distinguishable
prefix of the included one (e.g. digit - '0', a factor that's a
plain alternation of single characters and an exception that's one of
them), but not a claim of full correctness for arbitrary
factor/exception pairs in general.
special_sequence (? ... ?, ISO's own escape hatch for
implementation-defined extensions the formal grammar doesn't cover)
has no executable meaning, so it's rejected the same deliberate way
ABNF's prose_val and regex's backreferences/named-groups/anchors
are: Ichor.Error, not silently ignored.