
FYI, Bison supports parsers using either LALR(1) (Look-Ahead Left-to-Right with 1 token lookahead) [https://en.wikipedia.org/wiki/LALR_parser] or GLR (generalized Left-To-Right) [https://en.wikipedia.org/wiki/GLR_parser].
O'Reilly's book "flex & bison" by John Levine is a helpful reference. [https://www.amazon.com/flex-bison-Text-Processing-Tools/dp/0...]
Multiple grammars are fine, you just instruct Flex and Bison to use static or add prefixes. No worries about ODR or LTO.
If your build system can't handle generated code, that's an indictment of your build system. I know that's a bit harsh, but there are plenty of build systems which can handle generated code and cross-compile just fine. Flex and Bison work fine on Windows.
The easiest start would be "Compiler Construction using Flex and Bison" by Anthony A. Aaby, available as free pdf, and for adding LLVM to the mix the link would be: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/
There needs much more to be said, e.g. links to such languages which were written in a day and are not necessarily lisp or scheme. That would be too easy.
The mapping from regular and context free languages to state machines and their table-based implementations was covered in depth in the Compilers course I took. A table based state machine is literally the textbook algorithm for parsing these classes of languages, and implementing them has been almost entirely automated by tools like Flex and Bison since the 80s.
I used Flex and Bison since the project was in C. Getting up and running and understanding how the tools have to be set up with different options was a bit tricky, but after that, my parser was up and running in about two hours, compared to probably four times that for the hand written DDL. Our DML subset was also much larger and more complex than our DDL, so I was very happy with the development speed increase.
I had this idea that using a parser generator was slow and wasteful since many modern tutorials online write them by hand and speak against parser generators (possibly because there isn't a catch all for all languages). Turns out dev speed is way more important to me up front, because in the case that I notice parsing speed actually being an issue I should be happy that my MVP has gotten enough use.
It's also nice because a lexer and parser can be pretty easily black-boxed and swapped out for your hand written, just keep the AST and API the same and you should be good.
All that said, that's personal preferences and writing the parser by hand is definitely good experience and more extensible, especially for error handling. Nice work!