📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados em Módulo 14: Hardware e Compiladores. Recomendado revisar antes de começar.
v1.0 — Compiladores, Tokenização Léxica, Gramática EBNF e Abstract Syntax Tree
Trilha de Especialização Pedagógica — Projeto 1 de 4
- ➡️ v1 (este): Compiladores · Tokenizer Léxico · Parser Descendente Recursivo · Árvore AST
- v2: Tabela de Símbolos, Tipagem & Análise Semântica
- v3: Geração de Bytecode para Máquina Virtual Customizada
- v4: Otimização de Código & Compilação JIT (Just-In-Time)
🎓 Nível Profissional Simulado: Engenheiro de Compiladores / Core Developer. Criar uma linguagem de programação é o ápice da engenharia de computação. Compreender como um compilador lê código-fonte, divide em tokens, constrói uma Árvore de Sintaxe Abstrata (AST) e avalia expressões matemáticas com precedência de operadores é o que separa desenvolvedores comuns dos arquitetos que constroem ferramentas como Babel, SWC e motores V8.
Construir do zero o front-end de um Compilador para uma Mini-Linguagem de Programação, implementando um Analisador Léxico (Tokenizer/Lexer) com Expressões Regulares, um Parser Descendente Recursivo com precedência de operadores matemáticos ($*$, $/$, $+$, $-$) e a geração de uma Abstract Syntax Tree (AST) avaliada por um interpretador Tree-Walk.
“Precisamos de um compilador educacional completo para processar expressões matemáticas e atribuições de variáveis (exemplo:
total = 10 + 20 * 2). O sistema deve ler o código em texto puro, emitir a lista de tokens reconhecidos com tipo e valor, validar a gramática sintática, construir a árvore AST hierárquica e calcular o resultado final respeitando a ordem de precedência da multiplicação sobre a soma.”
| ID | Tipo | Descrição | Origem no Briefing |
|---|---|---|---|
| RF01 | Funcional | Reconhecer tokens: Identificadores, Números, Operadores (+, -, *, /), Atribuição (=). |
“emitir lista de tokens” |
| RF02 | Funcional | Construir nós da Árvore de Sintaxe Abstrata (AST) para expressões binárias. | “construir a árvore AST” |
| RF03 | Funcional | Respeitar rigorosamente a precedência de multiplicação e divisão antes de soma e subtração. | “ordem de precedência” |
| RF04 | Funcional | Avaliar e calcular o valor final da árvore sintática. | “calcular o resultado final” |
| RNF01 | Não-Funcional | Código puro em Python 3 sem dependência de bibliotecas de parsing externas (sem ANTLR/Yacc). | Fundamentos de Compiladores |
| RNF02 | Não-Funcional | Tratamento de erros de sintaxe com indicação do token inválido. | Usabilidade |
| ID | User Story | Prioridade |
|---|---|---|
| US01 | Como estudante, quero tokenizar um código fonte e inspecionar a sequência de tokens léxicos. | Alta |
| US02 | Como usuário, quero avaliar expressões como 10 + 20 * 2 e obter 50 (e não 60). |
Alta |
# Branch da funcionalidade
git checkout -b feature/US01-lexer-parser-ast
# Executar o mini-compilador
python mini_compiler.py
mini_compiler.py)import re
class Token:
def __init__(self, tipo, valor):
self.tipo = tipo
self.valor = valor
def tokenizar(codigo):
token_specs = [
('NUMERO', r'\d+(\.\d+)?'),
('ATRIBUICAO', r'='),
('OP_MULT', r'[\*/]'),
('OP_SOMA', r'[\+-]'),
('ID', r'[A-Za-z_][A-Za-z0-9_]*'),
('ESPACO', r'\s+'),
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specs)
tokens = []
for mo in re.finditer(tok_regex, codigo):
if mo.lastgroup != 'ESPACO':
tokens.append(Token(mo.lastgroup, mo.group()))
return tokens
No seu editor/IDE, abra a pasta deste projeto (File > Open Folder) ou navegue via terminal:
cd compiladores_01_lexico_sintatico_ast
go run main.go
# ou python main.py
[!TIP] Dica para execução a partir da raiz do repositório: Se você abriu o repositório completo no VS Code, basta navegar até a pasta antes de executar: cd catalogo_projetos/compiladores_01_lexico_sintatico_ast`
tokens = tokenizar("resultado = 5 + 3 * 10")
assert len(tokens) == 6
assert tokens[0].tipo == "ID" and tokens[0].valor == "resultado"
A visualização arquitetural abaixo detalha a separação de responsabilidades e o fluxo de dados implementado na subpasta cli-python/:
flowchart TD
subgraph Entrada["Camada de Entrada & CLI"]
IN1["Interface de Comando / API"] --> IN2["Parser & Sanitização"]
end
subgraph Dominio["Camada de Domínio & Regras"]
DM1["Modelos de Domínio"] --> DM2["Processamento Algorítmico"]
end
subgraph Armazenamento["Persistência & Recursos"]
ST1["Banco de Dados / Arquivo"] --> ST2["Transações ACID & Logs"]
end
subgraph Qualidade["Validação & Qualidade"]
QA1["Testes Automatizados"] --> QA2["Checkpoints CP-01..05 PASS"]
end
Entrada --> Dominio
Dominio --> Armazenamento
Armazenamento --> Qualidade
style Entrada fill:#e3f2fd,stroke:#1976d2,stroke-width:1.5px
style Dominio fill:#fffde7,stroke:#fbc02d,stroke-width:1.5px
style Armazenamento fill:#e8f5e9,stroke:#388e3c,stroke-width:1.5px
style Qualidade fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1.5px
| ID | Persona | História de Usuário | Critério de Aceite | Prioridade |
|---|---|---|---|---|
| US-01 | Desenvolvedor de Linguagens | Desejo analisador léxico (Tokenizer) que extraia tokens tipados | Identificação precisa de identificadores, números, operadores e literais | Alta |
| US-02 | Engenheiro de Compiladores | Desejo analisador sintático (Parser) Recursive Descent gerando AST | Construção de árvore sintática abstrata respeitando precedência de operadores | Alta |
| US-03 | Arquiteto de Software | Desejo avaliador/interpretador que execute a AST e produza resultados | Execução interpretada com tabela de símbolos para variáveis e escopo | Alta |
| US-04 | Estudante de Computação | Desejo mensagens de erro sintático com linha e coluna precisas | Detecção e relato amigável de erros léxicos e sintáticos com posição | Média |
| US-05 | Auditor de Código | Desejo suíte de testes com gramáticas formais e expressões complexas | Testes unitários cobrindo precedência matemática, parênteses e atribuição | Média |
| ID | Descrição do Requisito | Criticidade |
|---|---|---|
| RF-01 | Lexer baseado em autômatos/regex gerando lista ordenada de tokens | Alta |
| RF-02 | Parser Recursive Descent construindo nós AST tipados | Alta |
| RF-03 | Avaliador da AST com suporte a expressões aritméticas e variáveis | Alta |
| RF-04 | Visualizador em texto da árvore sintática hierárquica | Média |
| RF-05 | Suíte de testes automatizados com validação de gramática | Média |
| ID | Especificação Arquitetural | Criticidade |
|---|---|---|
| RNF-01 | Zero uso de geradores externos de parser (PLY, ANTLR) para valor didático | Alta |
| RNF-02 | Complexidade linear O(N) no processo de análise léxica | Alta |
| RNF-03 | Tratamento de exceções léxicas e sintáticas sem colapso do processo | Média |
| RNF-04 | Conformidade com especificações formais de linguagens de programação | Média |
| RNF-05 | Isolamento dos fontes na pasta cli-python/ | Alta |
| User Story | Requisito Funcional | Requisito Não-Funcional | Módulo / Artefato de Código | Status de Homologação |
|---|---|---|---|---|
| US-01 | RF-01 |
RNF-01, RNF-02 |
cli-python/mini_compiler.py |
Testado |
| US-02 | RF-02 |
RNF-01, RNF-04 |
cli-python/mini_compiler.py |
Testado |
| US-03 | RF-03 |
RNF-01, RNF-03 |
cli-python/mini_compiler.py |
Testado |
| US-04 | RF-04 |
RNF-03, RNF-05 |
cli-python/mini_compiler.py |
Testado |
| US-05 | RF-05 |
RNF-01, RNF-04 |
cli-python/mini_compiler.py |
Testado |
| Checkpoint | Escopo da Validação | Artefato Verificado | Status |
|---|---|---|---|
| CP-01 | Inicialização & Estrutura de Pastas | cli-python/ |
PASS ✅ |
| CP-02 | Modelagem de Domínio & Regras Centrais | Domain Models |
PASS ✅ |
| CP-03 | Persistência & Operações de I/O | Storage / Data |
PASS ✅ |
| CP-04 | Interface de Operação & Usabilidade | CLI / GUI / API |
PASS ✅ |
| CP-05 | Homologação com Suíte de Testes | Test Suite |
PASS ✅ |