In this course we explore the fundamental concepts and techniques behind a compiler: (1) Formal languages: regular languages, context-free languages, attribute grammars; (2) Meta-tools to create lexical analyzers; (3) Parsing: top-down and bottom-up, error recovery, meta-tools to use and create syntax analyzers; (4) Symbol tables. Semantic analysis: kinds of semantic checking, static type systems, dynamic type checking; (5) Generation of intermediate code; (6) Optimization, register allocation; (7) Generation of object code.