English {#english}
Inside CrabPascal: The Five-Phase Compiler Pipeline
Every compiler textbook describes the same pipeline. CrabPascal v2.22.0 implements it faithfully in Rust — from raw .pas text to executable behavior. Understanding these five phases explains what check, run, and build-exe actually do under the hood.
The big picture
Source (.pas/.dpr)
│
▼
┌─────────────┐
│ 1. LEXER │ Text → Tokens
└──────┬──────┘
▼
┌─────────────┐
│ 2. PARSER │ Tokens → AST
└──────┬──────┘
▼
┌─────────────┐
│ 3. SEMANTIC │ AST → Validated AST + Symbols
└──────┬──────┘
▼
┌─────────────┐
│ 4. CODEGEN │ AST → C code OR Runtime bytecode
└──────┬──────┘
▼
┌─────────────┐
│ 5. OPTIMIZE │ (Optional) Peephole / C compiler opts
└──────┬──────┘
▼
Executable / Interpreted result
Phase 1: Lexical analysis
The lexer scans source character by character and emits tokens — keywords (var, begin), identifiers, literals, operators.
Input: var x: Integer;
Output: [VAR, IDENT("x"), COLON, IDENT("Integer"), SEMICOLON]
CrabPascal handles Delphi-style comments { }, //, and (* *), plus preprocessor directives when enabled.
Phase 2: Parsing
The parser consumes tokens and builds an Abstract Syntax Tree (AST). It validates grammatical structure — matching begin/end, proper declaration order, nested expressions.
A assignment like x := 10 + 5 becomes an Assignment node with a BinaryOp(Add) child expression. The AST is serialized in Rust with serde for debugging (save_ast = true in crabpascal.toml).
Phase 3: Semantic analysis
Grammar alone is not enough. The semantic analyzer:
- Builds a symbol table (variables, types, procedures)
- Resolves
usesclauses and unit search paths fromrtl/ - Checks type compatibility (
IntegervsString) - Validates OOP constructs (classes, inheritance, visibility)
This is where crab-pascal check stops — full validation, zero execution.
Phase 4: Code generation
CrabPascal splits here based on command:
run — Internal runtime walks the AST directly. Built-in functions (WriteLn, TJSONObject.Create, Horse routes) dispatch to Rust implementations.
build-exe — Codegen emits C source, then invokes gcc/clang. Example output for x := 10 + 5:
int x;
x = 10 + 5;
Phase 5: Optimization
Optional and layered:
- CrabPascal may apply basic AST simplifications
- gcc/clang apply their own optimizations when using
build-exe - The internal runtime prioritizes correctness over aggressive optimization (for now)
Which commands use which phases?
| Command | Phases executed |
|---|---|
check |
1 → 2 → 3 |
run |
1 → 2 → 3 → 4 (runtime) |
build-exe |
1 → 2 → 3 → 4 (C) → 5 (gcc) |
preproc |
Pre-phase 0 (text transform) |
Why this matters for contributors
Module boundaries in the Rust codebase mirror the pipeline: lexer/, parser/, semantic/, codegen/, runtime/. Sprint work typically targets one phase — parser hardening in one release, RTL coverage in the next.
When you report a bug, identifying the phase narrows the search instantly. Syntax error? Parser. "Unknown identifier" at valid code? Semantic or RTL shim. Crash at runtime? Runtime dispatch.
CrabPascal is not magic — it is a textbook compiler built with modern tools. The five phases are the map. 🦀
Português {#portugus}
Por dentro do CrabPascal: pipeline em cinco fases
Todo livro de compiladores descreve o mesmo pipeline. O CrabPascal v2.22.0 implementa isso fielmente em Rust — do texto .pas bruto ao comportamento executável. Entender as cinco fases explica o que check, run e build-exe fazem por baixo dos panos.
Visão geral
Fonte (.pas/.dpr)
│
▼
┌─────────────┐
│ 1. LEXER │ Texto → Tokens
└──────┬──────┘
▼
┌─────────────┐
│ 2. PARSER │ Tokens → AST
└──────┬──────┘
▼
┌─────────────┐
│ 3. SEMÂNTICA│ AST → AST validada + Símbolos
└──────┬──────┘
▼
┌─────────────┐
│ 4. CODEGEN │ AST → C ou bytecode do runtime
└──────┬──────┘
▼
┌─────────────┐
│ 5. OTIMIZAÇÃO│ (Opcional) Peephole / opts do gcc
└──────┬──────┘
▼
Resultado executável / interpretado
Fase 1: Análise léxica
O lexer percorre o fonte caractere a caractere e emite tokens — palavras-chave (var, begin), identificadores, literais, operadores.
Entrada: var x: Integer;
Saída: [VAR, IDENT("x"), COLON, IDENT("Integer"), SEMICOLON]
O CrabPascal trata comentários estilo Delphi { }, // e (* *), além de diretivas de pré-processador quando habilitadas.
Fase 2: Parsing
O parser consome tokens e constrói a Árvore de Sintaxe Abstrata (AST). Valida estrutura gramatical — begin/end pareados, ordem de declarações, expressões aninhadas.
Uma atribuição x := 10 + 5 vira nó Assignment com filho BinaryOp(Add). A AST é serializada em Rust com serde para debug (save_ast = true no crabpascal.toml).
Fase 3: Análise semântica
Gramática não basta. O analisador semântico:
- Constrói tabela de símbolos (variáveis, tipos, procedures)
- Resolve cláusulas
usese search paths dertl/ - Verifica compatibilidade de tipos (
IntegervsString) - Valida OOP (classes, herança, visibilidade)
É aqui que crab-pascal check para — validação completa, zero execução.
Fase 4: Geração de código
O CrabPascal bifurca conforme o comando:
run — Runtime interno percorre a AST diretamente. Built-ins (WriteLn, TJSONObject.Create, rotas Horse) despacham para implementações Rust.
build-exe — Codegen emite C e invoca gcc/clang. Exemplo para x := 10 + 5:
int x;
x = 10 + 5;
Fase 5: Otimização
Opcional e em camadas:
- CrabPascal pode aplicar simplificações básicas na AST
- gcc/clang aplicam otimizações próprias no
build-exe - O runtime interno prioriza correção sobre otimização agressiva (por ora)
Quais comandos usam quais fases?
| Comando | Fases executadas |
|---|---|
check |
1 → 2 → 3 |
run |
1 → 2 → 3 → 4 (runtime) |
build-exe |
1 → 2 → 3 → 4 (C) → 5 (gcc) |
preproc |
Pré-fase 0 (transformação de texto) |
Por que isso importa para contribuidores
Os módulos Rust espelham o pipeline: lexer/, parser/, semantic/, codegen/, runtime/. Trabalho de sprint costuma mirar uma fase — endurecimento do parser num release, cobertura RTL no seguinte.
Ao reportar bug, identificar a fase estreia a busca na hora. Erro de sintaxe? Parser. "Unknown identifier" em código válido? Semântica ou shim RTL. Crash em runtime? Dispatch do runtime.
CrabPascal não é mágica — é um compilador de livro-texto com ferramentas modernas. As cinco fases são o mapa. 🦀
Published on dev.to/@crabpascal · Código em CrabPascal
Top comments (0)