👨💻 Guia para Desenvolvedores
Este guia é destinado a desenvolvedores que querem contribuir para o projeto do interpretador Python, adicionar novas funcionalidades ou corrigir bugs.
🎯 Como Contribuir
1. Preparação do Ambiente
Antes de começar a desenvolver, certifique-se de que o ambiente está configurado:
2. Estrutura do Código
Convenções de Código
C (Parser/Interpreter):
Flex (Lexer):
C | |
---|---|
Bison (Parser):
Text Only | |
---|---|
3. Fluxo de Desenvolvimento
Adicionando Nova Funcionalidade
- Identificar onde adicionar:
- Lexer: Novos tokens em
lexer/lexer.l
- Parser: Novas regras gramaticais em
parser/parser.y
- AST: Novos tipos de nós em
parser/ast.h
-
Interpreter: Nova lógica em
parser/interpretador.c
-
Exemplo: Adicionar operador
//
(divisão inteira):
Corrigindo Bugs
-
Identificar o problema:
-
Adicionar testes:
-
Corrigir e testar:
Bash
4. Testes
Executando Testes Durante Desenvolvimento
Bash | |
---|---|
Adicionando Novos Testes
Teste de Funcionalidade:
Python | |
---|---|
Teste Unitário:
5. Debugging
Usando GDB
Logs e Debug
C | |
---|---|
6. Otimizações
Performance
C | |
---|---|
Memória
7. Documentação
Comentários no Código
Atualizar Documentação
Quando adicionar novas funcionalidades, atualize:
- README.md: Lista de funcionalidades
- docs/arquitetura.md: Documentação da arquitetura
- docs/uso.md: Exemplos de uso
- docs/testes.md: Documentação dos testes
8. Commits e Versionamento
Convenções de Commit
Bash | |
---|---|
Exemplos de Commits
Bash | |
---|---|
9. Checklist Antes do Commit
- [ ] Código compila sem warnings
- [ ] Todos os testes passam (
make test-complete
) - [ ] Novos testes foram adicionados
- [ ] Documentação foi atualizada
- [ ] Código segue as convenções do projeto
- [ ] Memória é liberada corretamente
- [ ] Tratamento de erros foi implementado
Referências
📚 Próximos Passos
Para começar a contribuir:
- Configure o ambiente se ainda não fez
- Execute os testes para entender o que já funciona
- Estude a arquitetura para entender o código
- Escolha uma funcionalidade da lista de sugestões
- Implemente e teste seguindo este guia
Contribuições são bem-vindas! Este projeto é uma excelente oportunidade para aprender sobre compiladores e interpretadores.
Processo de Desenvolvimento
Esta seção documenta o processo de desenvolvimento do interpretador Python, incluindo as dificuldades encontradas, soluções implementadas e lições aprendidas.
Desafios Encontrados
1. Tratamento da Indentação Python
Problema: Python usa indentação para definir blocos de código, mas Flex/Bison trabalham com tokens tradicionais como chaves {}
.
Dificuldades: - Como converter espaços/tabs em tokens que o parser possa entender? - Como detectar erros de indentação inconsistente? - Como manter a estrutura hierárquica dos blocos?
Solução Implementada:
O grupo perdeu muito tempo tentando processar a indentação, após muita pesquisa nós:
- Criamos um pré-processador Python (indent_preproc.py
) que:
- Converte indentação em tokens @INDENT@
e @DEDENT@
- Remove comentários e normaliza quebras de linha
- Detecta e reporta erros de indentação inconsistente
Código da solução:
Python | |
---|---|
2. Gerenciamento de Memória
Problema: C é uma linguagem sem garbage collection, exigindo gerenciamento manual de memória.
Dificuldades: - Como evitar memory leaks na AST? - Como gerenciar strings dinâmicas? - Como liberar estruturas complexas recursivamente?
Soluções Implementadas:
- Função destruir_ast()
que percorre recursivamente a árvore
- Uso de strdup()
para strings e free()
correspondente
- Estruturas de dados com funções de criação/destruição
Exemplo de solução:
C | |
---|---|
3. Precedência de Operadores
Problema: Como implementar a precedência correta de operadores em Bison?
Dificuldades: - Operadores com diferentes níveis de precedência - Operadores unários vs binários - Associatividade (esquerda vs direita)
Solução Implementada: - Uso das diretivas de precedência do Bison:
Text Only | |
---|---|
4. Tratamento de Erros
Problema: Como fornecer mensagens de erro úteis e específicas?
Dificuldades: - Erros em diferentes fases (léxica, sintática, semântica) - Como reportar a linha exata do erro? - Como distinguir diferentes tipos de erro?
Soluções Implementadas:
- Uso de yylineno
para rastrear linha atual
- Mensagens específicas para cada tipo de erro
- Tratamento de erros em diferentes níveis
Exemplos:
C | |
---|---|
Decisões de Design
1. Estrutura da AST
Decisão: Usar union em C para diferentes tipos de nós Justificativa: Permite representar diferentes tipos de instruções em uma única estrutura
2. Tabela de Símbolos
Decisão: A princípio, a tabela de símbolos foi criada como uma lista encadeada, devido a sua simplicidade na hora de fazer. No entanto, após a aula de tabela de símbolos, vimos que a melhor opção seria a Tabela Hash. Justificativa: Performance Alternativas consideradas: Lista encadeada(mais simples)
3. Sistema de Tipos
Decisão: Tipos dinâmicos com union Justificativa: Flexibilidade para operações entre tipos diferentes Alternativas consideradas: Tipos estáticos, sistema de tipos mais rigoroso
C | |
---|---|
Lições Aprendidas
1. Planejamento
Lição: O planejamento bem definido desde o início facilita muito o desenvolvimento Aplicação: Seguindo o 'guia de um interpretador' do professor, conseguimos nos planejar para cada etapa do desenvolvimento.
2. Testes Incrementais
Lição: Testar cada componente individualmente antes da integração Aplicação: Criamos testes unitários para AST, tabela de símbolos, etc.
3. Documentação Durante o Desenvolvimento
Lição: Documentar decisões e problemas enquanto ainda estão frescos Aplicação: Comentários no código e documentação técnica(falhamos aqui em alguns momentos)
4. Gerenciamento de Memória
Lição: Em C, sempre pensar sobre alocação e liberação de memória Aplicação: Funções de criação e destruição para cada estrutura
5. Tratamento de Erros
Lição: Mensagens de erro claras são essenciais para debugging Aplicação: Sistema de mensagens de erro detalhadas e específicas
Ferramentas e Tecnologias
Flex v2.6.4 (Analisador Léxico)
Vantagens: - Geração automática de código C - Reconhecimento eficiente de padrões - Integração fácil com Bison
Desafios: - Curva de aprendizado inicial - Debugging de regras complexas
Bison v3.8.2 (Analisador Sintático)
Vantagens: - Suporte a gramáticas complexas - Precedência de operadores automática - Geração de código otimizado
Desafios: - Sintaxe específica para ações semânticas - Debugging de conflitos de gramática
Funcionalidades Implementadas
- Tipos de dados: 4 (int, float, string, bool)
- Operadores: 15 (aritméticos, comparação, lógicos)
- Estruturas de controle: 2 (if/else, while)
- Funções built-in: 1 (print)
- Testes: 9 categorias principais
Próximos Passos
Melhorias de Desenvolvimento
- CI/CD: Integração contínua
- Cobertura de Testes: Aumentar cobertura
- Documentação: Documentação da API
- Benchmarks: Testes de performance
Histórico de Versão
Versão | Data | Descrição | Autor(es) |
---|---|---|---|
1.0 |
27/06/2025 | Criação do documento | Arthur Evangelista |
Este documento reflete o processo de desenvolvimento real e as decisões tomadas durante a implementação do interpretador Python.