Writing Compilers and Interpreters (3rd edition): A Software Engineering Approach