Pré-processador

Da Wikipédia, a enciclopédia livre
Ir para navegação Pular para pesquisar

Na ciência da computação , um pré - processador (ou pré - compilador ) [1] é um programa que processa seus dados de entrada para produzir uma saída que é usada como entrada para outro programa. A saída é considerada uma forma pré - processada dos dados de entrada, que costuma ser usada por alguns programas subsequentes, como compiladores . A quantidade e o tipo de processamento realizado dependem da natureza do pré-processador; alguns pré-processadores são capazes apenas de realizar substituições textuais relativamente simples e expansões de macro , enquanto outros têm o poder de linguagens de programação completas .

Um exemplo comum de programação de computador é o processamento realizado no código-fonte antes da próxima etapa de compilação. Em algumas linguagens de computador (por exemplo, C e PL / I ), há uma fase de tradução conhecida como pré-processamento . Também pode incluir processamento de macro, inclusão de arquivo e extensões de idioma.

Preprocessors lexicais

Os pré-processadores lexicais são os pré-processadores de nível mais baixo, pois requerem apenas análise lexical , ou seja, operam no texto de origem, antes de qualquer análise , realizando a substituição simples de sequências de caracteres tokenizadas por outras sequências de caracteres tokenizadas, de acordo com as as regras. Eles normalmente executam substituição de macro , inclusão textual de outros arquivos e compilação ou inclusão condicional.

C pré-processador

O exemplo mais comum disso é o pré-processador C , que usa linhas começando com '#' como diretivas . Como ele não sabe nada sobre a linguagem subjacente, seu uso foi criticado e muitos de seus recursos foram integrados diretamente em outras linguagens. Por exemplo, macros substituídas por inlining e modelos agressivos, incluindo importações em tempo de compilação (isso requer a preservação das informações de tipo no código do objeto, tornando esse recurso impossível de ser adaptado em uma linguagem); compilação condicional é efetivamente realizado com if-then-elsee eliminação de código morto em alguns idiomas. No entanto, um ponto importante a ser lembrado é que todas as diretivas do pré-processador devem começar em uma nova linha.

Outros preprocessors lexicais

Outros pré-processadores lexicais incluem o m4 de uso geral , mais comumente usado em sistemas de compilação de plataforma cruzada, como autoconf , e GEMA , um processador de macro de código aberto que opera em padrões de contexto.

Preprocessors sintáticas

Os pré-processadores sintáticos foram introduzidos com a família de linguagens Lisp . Sua função é transformar as árvores de sintaxe de acordo com uma série de regras definidas pelo usuário. Para algumas linguagens de programação, as regras são escritas na mesma linguagem do programa (reflexão em tempo de compilação). Esse é o caso com Lisp e OCaml . Algumas outras linguagens contam com uma linguagem totalmente externa para definir as transformações, como o pré-processador XSLT para XML ou sua contraparte de tipo estático CDuce .

Os pré-processadores sintáticos são normalmente usados ​​para personalizar a sintaxe de uma linguagem, estender uma linguagem adicionando novos primitivos ou incorporar uma linguagem de programação específica de domínio (DSL) dentro de uma linguagem de propósito geral.

Personalizando sintaxe

Um bom exemplo de customização de sintaxe é a existência de duas sintaxes diferentes na linguagem de programação Objective Caml . [2] Os programas podem ser escritos indiferentemente usando a "sintaxe normal" ou a "sintaxe revisada", e podem ser bem impressos com qualquer uma das sintaxes sob demanda.

Da mesma forma, vários programas escritos em OCaml personalizam a sintaxe da linguagem adicionando novos operadores.

Estendendo uma linguagem

Os melhores exemplos de extensão de linguagem por meio de macros são encontrados na família de linguagens Lisp . Enquanto as linguagens, por si mesmas, são núcleos funcionais simples dinamicamente tipados, as distribuições padrão de Scheme ou Common Lisp permitem programação imperativa ou orientada a objetos, bem como tipagem estática. Quase todos esses recursos são implementados por pré-processamento sintático, embora seja importante notar que a fase de "expansão macro" da compilação é tratada pelo compilador em Lisp. Isso ainda pode ser considerado uma forma de pré-processamento, uma vez que ocorre antes de outras fases de compilação.

Especializando uma linguagem

Uma das características incomuns da família de linguagens Lisp é a possibilidade de usar macros para criar uma DSL interna. Normalmente, em um grande projeto baseado em Lisp , um módulo pode ser escrito em uma variedade de minilínguas , uma talvez usando um dialeto baseado em SQL de Lisp , outro escrito em um dialeto especializado para GUIs ou impressão bonita, etc. Lisp comum A biblioteca padrão de contém um exemplo deste nível de abstração sintática na forma da macro LOOP, que implementa uma minilinguagem semelhante a Algol para descrever iterações complexas, enquanto ainda permite o uso de operadores Lisp padrão.

O pré-processador / linguagem MetaOCaml fornece recursos semelhantes para DSLs externos. Este pré-processador pega a descrição da semântica de uma linguagem (ou seja, um interpretador) e, combinando interpretação em tempo de compilação e geração de código, transforma essa definição em um compilador para a linguagem de programação OCaml - e dessa linguagem, seja para bytecode ou para Código nativo.

Uso geral de pré-processamento

A maioria dos pré-processadores são específicos para uma tarefa particular de processamento de dados (por exemplo, compilar a linguagem C). Um pré-processador pode ser promovido como sendo de propósito geral , o que significa que não se destina a um uso específico ou linguagem de programação, e deve ser usado para uma ampla variedade de tarefas de processamento de texto.

M4 é provavelmente o exemplo mais conhecido de um pré-processador de propósito geral, embora o pré-processador C às vezes seja usado em uma função não específica do C. Exemplos:

  • usando o pré-processador C para o pré-processamento de JavaScript . [3] [4]
  • usando o pré-processador C para processamento de dispositivo no kernel do Linux . [5]
  • usando M4 (ver exemplo no artigo) ou pré-processador C [6] como um mecanismo de template , para geração de HTML .
  • imake , uma interface make usando o pré-processador C, escrito para o X Window System, mas agora obsoleto em favor do automake .
  • grompp , um pré-processador para arquivos de entrada de simulação para GROMACS (um código-fonte aberto, rápido e gratuito para alguns problemas em química computacional ) que chama o pré-processador C do sistema (ou outro pré-processador conforme determinado pelo arquivo de entrada de simulação) para analisar a topologia, usando principalmente os mecanismos #define e #include para determinar a topologia efetiva no tempo de execução do grompp.

GPP é um pré-processador léxico de uso geral que se assemelha ao cpp. Entre outras coisas, ele pode ser usado para pré-processamento de arquivos markdown. [7]

Veja também

Referências

  1. ^ "O que é um pré-compilador?" .
  2. ^ A sintaxe revisada do site da linguagem The Caml
  3. ^ Mostre como usar o pré-processador C em arquivos JavaScript. "JavaScript não é força industrial" por T. Snyder .
  4. ^ "O pré-processador C em Javascript?" . modo expresso .
  5. ^ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?id=b40b25fff8205dd18124d8fc87b2c9c57f269b5f
  6. ^ Mostre como usar o pré-processador C como mecanismo de template . "Usando um pré-processador C como uma ferramenta de autoria de HTML" por J. Korpela , 2000.
  7. ^ https://adityam.github.io/context-blog/post/markdown-with-gpp/

Ligações externas