Aula 17 - Análise Léxica e Autômatos Finitos 🔍
Objetivo Pedagógico
Objetivo: Fundamentos da primeira fase de um compilador: conversão de fluxo de caracteres brutos em fluxo de Tokens semânticos, Expressões Regulares e Autômatos Finitos Determinísticos (AFD).
📑 1. Fundamentos Teóricos & Análise Técnica
Um Compilador é um pipeline complexo de transformação de programas que traduz código-fonte de alto nível para linguagem de máquina ou bytecode intermediário. A primeira fase desse pipeline é a Análise Léxica (Lexical Analysis / Scanning).
O papel do Lexer: 1. Lê o arquivo de código-fonte caractere por caractere a partir de um buffer de entrada. 2. Descarta elementos sintáticos irrelevantes para a semântica da execução (espaços em branco, quebras de linha redundantes e comentários). 3. Agrupa sequências de caracteres (Lexemas) e produz uma sequência estruturada de Tokens (<TIPO, VALOR, LINHA, COLUNA>).
A fundamentação teórica baseia-se na equivalência entre Expressões Regulares (Regex) e Autômatos Finitos Determinísticos (AFD) formalizada pelo algoritmo de Thompson e o algoritmo de subconjuntos de Powerset, permitindo ao lexer transitar entre estados discretos a cada caractere lido em tempo linear \(O(n)\).
📐 Arquitetura Conceitual & Diagrama de Fluxo
flowchart LR
Source["Código Fonte: 'let x = 42;'"] --> Lexer["Analisador Léxico (Scanner / AFD)"]
Lexer --> Tokens["Fluxo de Tokens Estruturados:<br>[TOKEN_LET, 'let']<br>[TOKEN_IDENT, 'x']<br>[TOKEN_ASSIGN, '=']<br>[TOKEN_INT, '42']<br>[TOKEN_SEMICOLON, ';']"]
Tokens --> Parser["Próxima Fase: Analisador Sintático"]
style Source fill:#e1f5fe,stroke:#01579b
style Lexer fill:#fff3e0,stroke:#e65100
style Tokens fill:#e8f5e9,stroke:#2e7d32 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Autômatos Finitos Determinísticos (AFD): Garantia de que cada caractere lido conduza a no máximo uma transição de estado sem retrocessos (backtracking). - Regra do Lexema Mais Longo (Maximal Munch): O lexer consome a maior sequência válida possível (ex: == é reconhecido como operador de igualdade, não duas atribuições =). - Tabela de Símbolos Preliminar: Registro de identificadores e palavras reservadas da linguagem. - Rastreamento de Coordenadas de Erro: Armazenamento da linha e coluna de cada token para mensagens de erro precisas.
🛠️ 2. Implementação Prática em Teoria de Compiladores e Análise Léxica
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// simple_lexer.c (Implementação Manual de Analisador Léxico em C)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
typedef enum {
TOKEN_EOF,
TOKEN_KEYWORD,
TOKEN_IDENT,
TOKEN_NUMBER,
TOKEN_ASSIGN,
TOKEN_PLUS
} TokenType;
typedef struct {
TokenType type;
char text[64];
int line;
} Token;
Token next_token(const char** src, int* line) {
while (**src && isspace(**src)) {
if (**src == '\n') (*line)++;
(*src)++;
}
if (!**src) return (Token){TOKEN_EOF, "EOF", *line};
if (isalpha(**src)) {
Token t = {TOKEN_IDENT, "", *line};
int i = 0;
while (isalnum(**src)) t.text[i++] = *(*src)++;
t.text[i] = '\0';
if (strcmp(t.text, "let") == 0 || strcmp(t.text, "fn") == 0) t.type = TOKEN_KEYWORD;
return t;
}
if (isdigit(**src)) {
Token t = {TOKEN_NUMBER, "", *line};
int i = 0;
while (isdigit(**src)) t.text[i++] = *(*src)++;
t.text[i] = '\0';
return t;
}
if (**src == '=') { (*src)++; return (Token){TOKEN_ASSIGN, "=", *line}; }
if (**src == '+') { (*src)++; return (Token){TOKEN_PLUS, "+", *line}; }
(*src)++;
return (Token){TOKEN_EOF, "UNKNOWN", *line};
}
💡 Análise Passo a Passo do Código
- Ignora Espaços e Quebras: O ponteiro de leitura avança sobre espaços em branco e incrementa o contador de linhas para relatórios de erro.
- Reconhecimento de Identificadores e Palavras-Chave: Acumula caracteres alfanuméricos e compara com
letoufnpara diferenciar keywords de variáveis. - Estrutura de Token Completa: Retorna uma tupla contendo o tipo, o texto bruto e a linha exata no código-fonte.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto