Update on the current project: I’ve finished the entry of the compilation and encountered two or three places where recursion occurs; as noted earlier, they result in code that is not BNF-like. That’s reality.
I’ve decided to attack the semantics problem in a consistent manner. For each production BNF, I will append a processing parser. A recursive descent parser consists of multiple parsers strung together using currying; about half of them consume input, the rest check whether the consumers are happy with the inputs. These processing parsers will evaluate the results of the parsing in the production, which will be stored during the parsing, and take appropriate actions. So, for example, Production 5, which in pure BNF form is
Name ::= NameStartChar (NameChar)*
and in Mythryl is currently
name = name_start_char & <name_char> ;
will become
name = name_start_char & <name_char> & five_p;
Some processors will place results in a result parameter before calling the next parser, while others will collate results and invoke callback functions. five_p will be of the former sort.