String Template
Last updated
Last updated
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 $).
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:
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).
Podemos ainda definir padrões utilizando outros padrões (como se fossem funções).
Também existe a possibilidade de utilizar listas para concatenar texto e argumentos de padrões:
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.
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:
Considerar que qualquer expressão tem a si associada uma variável (na linguagem destino) com o seu valor;
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: