---
title: 'Compiler Principles: A Learning Path from Expressions to Executable Programs'
url: https://doc.liz6.com/en/compilers/00-learning-path
locale: en
area: compilers
tags:
- Compilers
date: 2026-09-12
modified: 2026-09-12
description: For readers who can write functions, recursion, arrays, and simple mappings. Choose a language you are familiar with to implement the exercises; at the beginning, there is no requirement to master assembly, LLVM, or automata proofs. The main thread revolves around a small language that supports integers, variables, parentheses, and addition, subtraction, multiplication, and division, avoiding the pitfall of switching to unrelated toy languages in each chapter.
---

# Compiler Principles: A Learning Path from Expressions to Executable Programs

For readers who can write functions, recursion, arrays, and simple mappings. Choose a language you are familiar with to implement the exercises; at the beginning, there is no requirement to master assembly, LLVM, or automata proofs. The main thread revolves around a small language that supports integers, variables, parentheses, and addition, subtraction, multiplication, and division, avoiding the pitfall of switching to unrelated toy languages in each chapter.

## What you will build

Deliver a small language that can report error locations, distinguish between syntax and name errors, and execute or generate code, while explaining the meaning of inputs and outputs at each stage.

## Required reading and checkpoints

1. [Lexer Design](01-lexical-analysis/02-lexer-design.md) → [Recursive Descent and LL Analysis](02-syntax-analysis/01-recursive-descent-and-ll-analysis.md) → [AST Design and Error Recovery](02-syntax-analysis/03-ast-design-and-error-recovery.md).

   First, convert characters into tokens, then build the AST according to precedence. Self-check: The trees for `1+2*3` and `(1+2)*3` are different; when a closing parenthesis is missing, provide the location instead of crashing.

2. [Symbol Tables and Scopes](03-semantic-analysis/01-symbol-tables-and-scopes.md) → [Type Systems](03-semantic-analysis/02-type-systems.md).

   Add local variables, block scopes, and Boolean values to the small language. Self-check: Variable shadowing with the same name can be explained; referencing undefined names and performing operations on incorrect types are identified before execution.

3. [LLVM IR in Practice](04-intermediate-representation/02-llvm-ir-in-practice.md) → [Linking and Loading](07-runtime/02-linking-and-loading.md).

   Connect the checked program to an execution path. You can start by writing an AST interpreter, then use the LLVM examples in the text to understand IR, object files, and linking. Self-check: Two implementations yield consistent results for the same valid input, and you can distinguish between successful compilation and successful linking.

## Optional branches

[Regular Expressions and Automata](01-lexical-analysis/01-regular-expressions-and-automata.md) explains the foundation of lexical recognition; [LR Parsing](02-syntax-analysis/02-lr-parsing.md) is another parsing route, and you do not need to implement both LL and LR simultaneously to complete this introductory path. Afterward, read [SSA](04-intermediate-representation/01-ssa-form.md) → [Data Flow Analysis](05-optimization/01-data-flow-analysis.md) → [Classic Optimizations](05-optimization/02-classic-optimizations.md). Before and after optimization, you must compare semantics, not just look at the reduction in instructions. JIT, GC, register allocation, and LSP are optional readings based on project needs.

## Completion task

Retain a set of normal inputs, precedence boundaries, error inputs, and scope counterexamples. Use a one-page diagram to illustrate the relationship between characters, tokens, AST, semantic checks, and execution results, demonstrating the entire process of locating and diagnosing an error from input. If you do not understand the ABI, connect to the [Systems Programming Path](../systems-programming/00-learning-path.md); there is no need to read the kernel content in advance.

Skipping long proofs and implementation details is allowed during the first reading, but you must complete the self-checks for each phase. When you find yourself "knowing the terms but unable to explain the results," return to the current example, change a condition, and then proceed to the next article; there is no need to read the entire table of contents first.
