Pular para conteúdo

Aula 20 - Projeto Capstone: Interpretador Simplificado Autônomo 🏆

Objetivo Pedagógico

Objetivo: Construção de um interpretador autônomo completo para uma mini-linguagem de programação (Lexer, Parser, AST e Máquina de Avaliação com Tabela de Símbolos).


📑 1. Fundamentos Teóricos & Análise Técnica

O Projeto Capstone de Hardware e Compiladores convida o estudante a atingir o mais elevado patamar da ciência da computação: criar sua própria linguagem de programação funcional e autônoma.

O desafio consiste em projetar e implementar o MiniLang, um interpretador completo para uma linguagem imperativa com as seguintes características: 1. Analisador Léxico Robusto: Reconhecimento de identificadores, números inteiros, operadores aritméticos (+, -, *, /) e palavras-chave (let, print). 2. Parser Descendente Recursivo: Construção de uma AST tipada respeitando a precedência padrão de operadores matemáticos. 3. Tabela de Símbolos (Environment): Gerenciamento de variáveis em memória com suporte a escopos locais e globais. 4. Avaliador de AST (Tree-Walking Interpreter): Varredura recursiva da árvore sintática executando os nós e imprimindo resultados na saída padrão.

📐 Arquitetura Conceitual & Diagrama de Fluxo

graph TD
    Program["Programa Fonte: 'let a = 10; print a * 2;'"] --> Lexer["Lexer (Gera Lista de Tokens)"]
    Lexer --> Parser["Parser (Gera AST em Memória)"]
    Parser --> Evaluator["Avaliador (Tree-Walking Interpreter)"]
    Evaluator <--> Env["Tabela de Símbolos (Ambiente de Variáveis)"]
    Evaluator --> Stdout["Saída do Terminal: 20"]
    style Program fill:#e1f5fe,stroke:#01579b
    style Lexer fill:#fff3e0,stroke:#e65100
    style Evaluator fill:#e8f5e9,stroke:#2e7d32
    style Stdout fill:#f3e5f5,stroke:#7b1fa2

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Pipeline Completo de Compilação: Integração transparente entre fase léxica, sintática e semântica. - Tratamento Preciso de Erros: Mensagens de erro informando exatamente a linha do código com falha sintática. - Ambiente com Escopo Dinâmico ou Léxico: Resolução de identificadores de variáveis sem colisão de escopos. - Zero Dependências Externas: Implementação pura construída com os recursos essenciais da linguagem hospedeira.


🛠️ 2. Implementação Prática em Compiladores, Engenharia de Linguagens e AST Walkers

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// interpreter_eval.c (Núcleo do Avaliador de AST do Interpretador)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Tabela de Símbolos simples em memória
typedef struct {
    char name[32];
    int value;
} Variable;

Variable symbol_table[100];
int var_count = 0;

void set_var(const char* name, int val) {
    for (int i = 0; i < var_count; i++) {
        if (strcmp(symbol_table[i].name, name) == 0) {
            symbol_table[i].value = val;
            return;
        }
    }
    strcpy(symbol_table[var_count].name, name);
    symbol_table[var_count].value = val;
    var_count++;
}

int get_var(const char* name) {
    for (int i = 0; i < var_count; i++) {
        if (strcmp(symbol_table[i].name, name) == 0) return symbol_table[i].value;
    }
    printf("Erro Semântico: Variável '%s' indefinida!\n", name);
    exit(1);
}

int main() {
    // Simula execução de: let x = 50; let y = 20; print x + y;
    set_var("x", 50);
    set_var("y", 20);
    int resultado = get_var("x") + get_var("y");
    printf("[MiniLang Output]: %d\n", resultado);
    return 0;
}

💡 Análise Passo a Passo do Código

  1. Tabela de Símbolos Funcional: Armazena o mapeamento entre os identificadores textuais e seus valores em memória.
  2. Avaliação Semântica: Verifica se a variável foi previamente declarada antes de permitir seu uso em operações matemáticas.
  3. Execução Direta: Resolve expressões em tempo de execução, simulando o comportamento de linguagens interpretadas como Python ou Lua.

🎯 3. Próximos Passos & Sequência Didática