Earlier quoted context omitted.
Compilers are some of the simplest "complicated" programs out there if you start by throwing yacc/bison/antlr/parser generators in the garbage. Production compilers are complicated because of the feature set of languages and performance requirements. You can write a lexer + parser + treewalk interpreter for a simple language in a day if you know what you are doing.
The hardest part (IMHO) about getting a simple language running, particularly for beginners, is the “expression”. Mostly for your typical algebraic style infix expressions with precedence. Just getting the grammar straight on the naturally recursive structures can be a trick. They also touch a large portion of the code generation and run time. Get: (a + c/2) * sqrt(b) working and you’re 80% there.
(a + c/2) * sqrt(b)
is not a simple language. (* (+ a (/ c 2)) (sqrt b))
would be a simple and precise to parse language, and the typical compiler for this is written in a day. Search for SIOD