Notes - MIECT
Compiladores
Notes - MIECT
Compiladores
  • Compiladores
  • Compiladores, Linguagens e Gramáticas
    • Enquadramento
    • Compiladores
      • Interpretadores
      • Estrutura de um Compilador
    • Implementação de um Compilador
    • Linguagens: Definição como Conjunto
      • Conceito básicos e terminologia
      • Operações sobre palavras
      • Operações sobre linguagens
    • Introdução às gramáticas
      • Hierarquia de Chomsky
      • Autómatos
  • Introdução, Estrutura, Aplicação
    • Exemplos
      • Expr
      • Exemplo figuras
      • Exemplo visitor
      • Exemplo listener
    • Construção de gramáticas
      • Especificação de gramáticas
    • Estrutura léxica
    • Regras léxicas
      • Padrões léxicos típicos
      • Operador léxico “não ganancioso”
    • Estrutura sintática
      • Secção de Tokens
      • Acções no preâmbulo da gramática
    • Regras sintácticas
      • Padrões sintácticos típicos
      • Precedência
      • Associatividade
      • Herança de gramáticas
    • Outras funcionalidades
      • Tabelas CSV
      • Gramáticas ambíguas
      • Predicados semânticos
      • Separar analisador léxico do analisador sintáctico
      • “Ilhas” lexicais
      • Enviar tokens para canais diferentes
      • Reescrever a entrada
      • Desacoplar código da gramática - ParseTreeProperty
  • Análise Semântica
    • Estrutura de um Compilador
    • Sistema de Tipos
    • Gramáticas de Atributos
    • Tabela de símbolos
    • Instruções restringidas por contexto
    • ANTLR4: gestão de erros
  • Síntese
    • Síntese: Geração de código
    • String Template
    • Síntese: geração de código intermédio
  • Análise Lexical
    • Análise Lexical: Estrutura de um Compilador
    • Linguagens regulares
    • Gramáticas regulares
    • Expressões regulares
    • Conversão entre ER e GR
    • Reconhecimento de tokens
    • Autómatos finitos
    • Autómato finito não determinista
    • Autómato finito determinista
      • Projecto de autómato finito determinista
    • Conversão de AFND em AFD
    • Conversão de uma expressão regular num AFND
    • Autómato finito generalizado (AFG)
  • Gramática de Atributos
    • Conteúdo semântico
    • Gramática de atributos
    • Avaliação Dirigida pela Sintaxe
  • Análise Sintática Descendente
    • Análise Sintática
    • Análise Sintática Descendente
    • Analisador (parser) Recursivo-Descendente Preditivo
    • Questões a resolver
    • Fatorização à Esquerda
    • Eliminação de Recursividade á Esquerda
    • Conjuntos predict, first e follow
      • Conjunto first
      • Conjunto follow
    • Reconhecedor Descendente Preditivo
  • Análise Sintática Ascendente
    • Análise Sintática Ascendente
    • Construção de um reconhecedor ascendente
    • Tabela de decisão de um reconhecedor ascendente
    • Reconhecedor Ascendente
    • Tabela de Decisão de um Reconhecedor Ascendente
Powered by GitBook
On this page
  • String Template Group
  • String Template: dicionários e condicionais
  • String Template: Funções
  • String Template: listas
  • Geração de código: padrões comuns
  • Geração de código para expressões
  1. Síntese

String Template

PreviousSíntese: Geração de códigoNextSíntese: geração de código intermédio

Last updated 3 years ago

A biblioteca String Template fornece uma solução estruturada para a geração de código textual.

O software e documentação podem ser encontrados em www.stringtemplate.org .

Para ser utilizada é apenas necessário o pacote ST-4.?.jar (a instalação feita do antlr4 já incluiu este pacote).

Mesmo sendo um exemplo muito simples, podemos já verificar que a definição do padrão de texto, está separada do preenchimento dos “buracos” (atributos ou expressões) definidos, e da geração do texto final.

Podemos assim delegar em partes diferentes do gerador de código, a definição dos padrões (que passam a pertencer ao contexto do elemento de código a gerar), o preenchimento dos “buracos” definidos, e a geração do texto final de código.

Os padrões são blocos de texto e expressões.

O texto corresponde a código destino literal, e as expressões são em “buracos” que podem ser preenchidos com o texto que se quiser.

Sintaticamente, as expressões são identificadores delimitados por <expr> (ou por $).

String Template Group

Podemos também agrupar os padrões numa espécie de funções (módulo STGroup):

Podemos também colocar cada função num ficheiro:

Uma melhor opção é optar por ficheiros modulares contendo grupos de funções/padrões:

String Template: dicionários e condicionais

Neste módulos podemos ainda definir dicionários (arrays associativos).

Na definição de padrões podemos utilizar uma instrução condicional que só aplica o padrão caso o atributo seja adicionado:

O campo separator indica que em em cada operação add em stat, se irá utilizar esse sepa- rador (no caso, uma mudança de linha).

String Template: Funções

Podemos ainda definir padrões utilizando outros padrões (como se fossem funções).

String Template: listas

Também existe a possibilidade de utilizar listas para concatenar texto e argumentos de padrões:

Geração de código: padrões comuns

Uma geração de código modular requer um contexto uniforme que permita a inclusão de qualquer combinação de código a ser gerado.

Na sua forma mais simples, o padrão comum pode ser simplesmente uma sequência de instruções.

Com este padrão, podemos inserir no lugar do “buraco” stat a sequência de instruções que quisermos.

Naturalmente, que para uma geração de código mais complexa podemos considerar a inclusão de buracos para membros de classe, múltiplas classes, ou mesmo vários ficheiros.

Para a linguagem C, teríamos o seguinte padrão para um módulo de compilação:

Se a geração de código for guiada pela árvore sintáctica (como normalmente acontece), então os padrões de código a ser gerados devem ter em conta as definições gramaticais de cada símbolo, permitindo a sua aplicação modular em cada contexto.

Geração de código para expressões

Para ilustrar a simplicidade e poder de abstração do String Template vamos estudar o problema de geração de código para expressões.

Para resolver este problema de uma forma modular, podemos utilizar a seguinte estratégia:

  1. Considerar que qualquer expressão tem a si associada uma variável (na linguagem destino) com o seu valor;

  2. Para além dessa associação, podemos também associar a cada expressão um ST (stats) com as instruções que atribuem o valor adequado à variável.

Como habitual, para fazer estas associações podemos definir atributos na gramática, fazer uso do resultados das funções de um Visitor ou utilizar a classe ParseTreeProperty.

Desta forma, podemos fácil e de uma forma modular, gerar código para qualquer tipo de expressão.

Padrões para expressões (para Java) podem ser:

Para C apenas seria necessário mudar o padrão typeValue: