
O que é um analisador (parser)?
- VersionDude
- Análise
- 5 min de leitura
Um analisador transforma um fluxo de carateres em dados estruturados utilizáveis por um programa — o passo entre o texto em bruto e o sentido.
Um analisador (parser) é o componente que lê um texto de entrada e constrói dele uma representação estruturada com a qual um programa pode realmente trabalhar. O texto em bruto é apenas uma sequência de carateres sem significado intrínseco para o software; o analisador é o passo que transforma esse fluxo plano em algo dotado de forma e hierarquia. Situa-se na fronteira entre o texto escrito por um humano ou gerado por uma máquina e os dados estruturados de que o resto de um programa precisa.
Duas etapas: tokenizar, depois construir uma árvore

A maioria dos analisadores funciona em dois passos distintos. O primeiro passo, um tokenizador ou lexer, agrupa os carateres em unidades significativas — etiquetas, palavras, números, operadores, símbolos — de modo que a entrada já não sejam carateres individuais mas uma sequência de tokens. O segundo passo, a construção da árvore, dispõe estes tokens numa hierarquia segundo uma gramática, produzindo uma árvore estruturada. Separar estas duas tarefas mantém cada uma mais simples, e é um esquema que voltará a ver vezes sem conta.
A tokenização sozinha resolve muita ambiguidade. Considere como os carateres que formam uma etiqueta de abertura, um nome de atributo e um valor entre aspas devem ser reconhecidos como coisas distintas antes que qualquer estrutura possa ser construída; o tokenizador é o que estabelece estas distinções. É só depois de a entrada ser um fluxo limpo de tokens que o passo de construção da árvore pode raciocinar sobre como se aninham e se relacionam uns com os outros.
Os analisadores estão por toda a parte
Os analisadores estão verdadeiramente por toda a parte assim que se começa a olhar. Os compiladores analisam o código-fonte numa árvore sintática abstrata antes de gerarem instruções de máquina; os navegadores analisam o HTML e o CSS para construir as estruturas que renderizam; e as aplicações comuns analisam JSON, XML, YAML e ficheiros de configuração a cada arranque. Quase todo o programa que aceita texto de entrada tem um analisador algures no seu interior, mesmo que o autor nunca o pense com este nome.
Por que a saída é uma árvore
A saída de um analisador é geralmente uma árvore, e o tipo de árvore depende do domínio. Para uma linguagem de programação, é uma árvore sintática abstrata que capta a estrutura das expressões e das instruções; para uma página web, é o DOM, a árvore de elementos e de nós de texto que o navegador constrói a partir do HTML. Em ambos os casos, é a árvore, e não o texto original, sobre a qual operam os passos seguintes.
A razão por que uma árvore é a saída natural é que a maioria das linguagens e dos formatos de documento é intrinsecamente aninhada. Uma expressão contém subexpressões, um elemento contém elementos filhos, um bloco de configuração contém blocos aninhados. Uma lista plana de tokens não pode captar este aninhamento, mas uma árvore exprime-o diretamente, o que explica por que a análise é tão frequentemente descrita como a transformação de um fluxo unidimensional numa estrutura de vários níveis.
O que torna a análise do HTML invulgar
O que torna a análise do HTML invulgar entre todos estes exemplos é a sua recuperação de erros padronizada. O markup do mundo real está cheio de erros — etiquetas não fechadas, elementos mal colocados, atributos em posições estranhas — e ainda assim as páginas têm de se apresentar. A especificação HTML responde a isto definindo exatamente como um analisador deve tratar cada tipo de entrada malformada, em vez de deixar cada implementação adivinhar.
A consequência desta especificação precisa é uma interoperabilidade notável. Porque as regras de recuperação de erros estão detalhadas ao pormenor, cada navegador moderno constrói a mesma árvore DOM a partir da mesma entrada quebrada, em vez de cada um improvisar de forma diferente. É por isso que uma página malformada se apresenta de maneira coerente entre navegadores, e isso contrasta com formatos mais rigorosos como o XML, que rejeitam simplesmente uma entrada não bem formada em vez de tentar repará-la.
Indulgente versus rigoroso, por conceção
Este contraste põe em evidência um compromisso de conceção deliberado. Um analisador indulgente como o do HTML privilegia a resiliência e o facto de o utilizador ver sempre algo, ao preço de deixar passar em silêncio os erros. Um analisador rigoroso como o do XML privilegia a correção e a previsibilidade, ao preço de rejeitar à partida uma entrada imperfeita. Nenhum é universalmente melhor; cada um se adequa à tarefa para que foi concebido, e reconhecer que filosofia segue um formato diz-lhe muito sobre o seu comportamento.
Um modelo mental para toda a stack
Assim que se começa a ver o software como uma série de analisadores que transformam texto em estrutura, grande parte da stack web torna-se mais fácil de raciocinar. O navegador que analisa o HTML em DOM, o motor que analisa o JavaScript numa árvore sintática, o servidor que analisa um corpo de pedido JSON — são todos a mesma ideia aplicada em lugares diferentes. Este único prisma, do texto que se torna dados estruturados através de um analisador, é um dos modelos mentais mais úteis de toda a programação.



Este contraste põe em evidência um compromisso de conceção deliberado. Um analisador indulgente como o do HTML privilegia a resiliência e o facto de o utilizador ver sempre algo, ao preço de deixar passar em silêncio os erros. Um analisador rigoroso como o do XML privilegia a correção e a previsibilidade, ao preço de rejeitar à partida uma entrada imperfeita. Nenhum é universalmente melhor; cada um se adequa à tarefa para que foi concebido, e reconhecer que filosofia segue um formato diz-lhe muito sobre o seu comportamento.