How to implement Backus-Naur Form in Python
This post contains an example of a lexical scanner which doesn't need third-party libraries. It may not do all you want, but you should be able to use it as a basis for something that fits your needs.
I don't know if your applications all relate to lexical scanning - but if not, ply is a fairly easy to use parser (given that you need to know broadly how parsers work).
have a look at https://github.com/erikrose/parsimonious
Parsimonious aims to be the fastest arbitrary-lookahead parser written in pure Python—and the most usable. It's based on parsing expression grammars (PEGs), which means you feed it a simplified sort of EBNF notation.
I had good experiences with grako.
I used it for parseWKT.
It takes a EBNF as input and generates a PEG parser from it.
I think it would be reasonable simple to write a BNF to EBNF Parser in grako, which would then generate a parser from the EBNF