This course provides an overview of different programming paradigms followed by a detailed study of the compilation process for a procedural programming language.  Students will gain an in-depth understanding of compiler design by considering fundamental issues such as parsing, building and manipulating intermediate representations of a program, and code generation.  These principles will be put into practice through the construction of a fully functioning compiler for a simple procedural language using the widely available tools such as LEX and YACC and a general purpose programming language (C/C++ or Java).  The assignment and the project are designed to reinforce various concepts that are typically abstracted by tools during compiler construction in order to provide the students with a complete picture of the compiler design and implementation process.