Introduction: compilers and related tools, compilation phases, organization of a compiler. Formal languages: notations, automata, grammars. Scanning: tokens, design of the scanner. Parsing: design of a bottom-up and top-down parser. Symbol tables. Semantic analysis: type systems and checking. Intermediate code generation: forms of intermediate code, syntax directed translation. Final code generation: the target machine, memory management and activation records, simple final code generation, instruction selection, register allocation. Code optimization. Tools for automatic compiler generation: lex/flex, yacc/bison, meta-compilers. Lab: design and implementation of a compiler for a hypothetical programming language.