Another good introductory book is N. Wirth's "Compilerbau" from 1986 (compiler construction) which is about 100 pages long and explains concise, well designed code for the toy language PL/0, including parser, code generator and virtual machine. It also shows how to write a parser that reads in the grammar to parse in EBNF notation. The book is in German but I wrote a summary and translated the code to Python as an exercise, see http://www.d12k.org/cmplr/w86/intro.html.