Skip to content
Vitor Xavier de Souza edited this page Nov 9, 2021 · 9 revisions

ANTLR Exemplo

O que é?

ANTLR (Another Tool for Language Recognition) é um poderoso gerador para leitura, processamento, execução, ou tradução de texto estruturado ou arquivos binários. É comumente utilizado para arquitetar linguagens, ferramentas e frameworks. A partir de uma gramática, o ANTLR gera um analisador que pode executar e navegar em uma árvore estruturada.

Análise Léxica e Sintática

O analisador léxico reconhece caracteres individuais e os transforma em símbolos, que o analisador sintático usa para criar estruturas lógicas.

As regras são geralmente definidas sintáticas e então léxicas, mesmo que coerentemente sejam aplicadas na ordem inversa. É importante lembrar também que as regras léxicas são analisadas na ordem em que aparecem, podem ser ambíguas e devem começar com letra maiúscula, embora por costume todo o nome seja definido em letras maiúsculas, enquanto as regras sintáticas devem começar com letras minúsculas, embora também por hábito costumam ser definidas somente por letras minúsculas.

Como exemplo é possível citar o identificador, em diversas linguagens de programação esta pode ser qualquer combinação de caracteres, porém determinadas combinações, como "class" ou "function" não são permitidas, pois indicam uma estrutura de classe ou função. Assim a ordem das regras resolve a ambiguidade utilizando a primeira correspondência, e por tal motivo símbolos que identificam classes ou funções são definidos primeiro, enquanto o de identificadores é colocado por último.

É importante notar também que é possível indicar ao ANTLR para ignorar regras durante a análise, exemplos comuns são espaços em branco e comentários, que geralmente são dispensáveis para se realizar a análise sintática.

Exemplo SomaSimples

No ANTLR a primeira etapa no desenvolvimento de uma linguagem é definir suas regras léxicas, ou seja, os caracteres individuais para formar um símbolo aceito dentro da linguagem, e então as regras sintáticas, que utiliza os símbolos definidos pelas regras léxicas para criar as estruturas lógicas.

grammar SomaSimples;

/* Regras sintáticas */

operation: NUMBER '+' NUMBER; #somaFunction


/* Regras léxicas */

NUMBER: [0-9]+ ;

WHITESPACE: ' ' -> skip;

Regras léxicas de SomaSimples

  • NUMBER: [0-9]+; Define que um símbolo chamado 'NUMBER', que deve ser composto por caracteres de 0-9, em qualquer quantidade a partir de um.

  • WHITESPACE: ' ' -> skip; Define que caracteres ' ' serão denominados 'WHITESPACE', e devem ser ignorados na análise.

Regras sintáticas de SomaSimples

  • operation: NUMBER '+' NUMBER; #somaFunction Define que o conjunto de um símbolo 'NUMBER' acrescido do carácter '+', e de outro símbolo 'NUMBER', constitui uma estrutura lógica denominada 'operation', e que a função responsável por executar essa estrutura deve chamar 'somaFunction'.

Observação

Por ser a primeira regra sintática, a regra 'operation' é também a regra principal da gramática 'SomaSimples', assim outras regras sintáticas só seriam acessíveis se estivessem contidas nela.

Entrada SomaSimples

O texto de entrada a ser analisado deve respeitar a primeira regra sintática definida na gramática, no caso de 'SomaSimples', a regra sintática 'operation', caso contrário não representará um entrada válida e assim o ANTLR se torna incapaz de interpretá-la.

10 + 19

No exemplo de entrada acima para a gramática 'SomaSimples', seria identificado que o texto é composto de um símbolo compatível com a definição de 'NUMBER', um carácter '+', e outro símbolo que também corresponde com a definição de 'NUMBER', conjunto esse que caracteriza a regra sintática 'operation', e contando que esta representa a operação principal da linguagem 'SomaSimples', descreve uma entrada válida.

Visitor SomaSimples

O ANTLR disponibiliza dois modos para implementar as ações das regras sintáticas, Parser e Visitor, neste projeto foi feito o uso de Visitors, portanto um dos arquivos auxiliares gerados pelo ANTLR, que possui sufixo 'BaseVisitor', contém uma implementação base de todas as regras sintáticas definidas na linguagem, a partir do qual podemos estender e implementar as funções que necessitam de ações customizadas, conforme demonstrado no trecho abaixo.

public override int VisitSomaFunction([NotNull] LanguageParser.SomaFunctionContext context)
{
    int num1 = int.Parse(context.NUMBER(0).GetText());
    int num2 = int.Parse(context.NUMBER(1).GetText());
    return num1 + num2;
}

Como o nome para a função de 'operation' foi definido como #somaFunction, o nome da função gerado pelo ANTLR é definido como 'SomaFunction', acrescido do prefixo 'Visit', e é uma sobrescrita, pois a implementação base foi realizada no BaseVisitor, portanto a definição acima representa somente as ações customizadas necessárias para atingir o objeto da regra 'operation', o conjunto de símbolos e demais estruturas lógicas utilizadas pela regra sintática são acessíveis a partir do parâmetro context, que neste caso da acesso aos símbolos 'NUMBER', que são convertidos para números inteiros e então a soma deles é realizada e retornada para a execução.

Instalação

Java

  1. Baixar e instalar o Java Development Kit ou OpenJDK.

  2. Alterar a variável de ambiente do Java para a nova versão instalada.

    Exemplo: [Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Java\jdk1.8.0_231", 'Machine')

  3. Editar a variável de ambiente PATH para incluir o caminho da variável do Java.

    Exemplo: [Environment]::SetEnvironmentVariable("PATH", $Env:Path + ";%JAVA_HOME%\bin", 'Machine')

ANTLR4

  1. Criar o diretório C:\JavaLib.

  2. Baixar o arquivo do ANTLR4 4.9.2 e adicionar no diretório C:\JavaLib

  3. Incluir o caminho do arquivo na variável CLASSPATH.

    Exemplo: [Environment]::SetEnvironmentVariable("CLASSPATH", $Env:CLASSPATH + ";C:\JavaLib\antlr-4.9.2-complete.jar", 'Machine')

Comandos de atalho (Opcional)

É possível facilitar o acesso ao ANTLR4 através da criação de arquivos auxiliares, com seu diretório registrado na variável de ambiente PATH.

  1. Criar o diretório C:\JavaLib\antlr4.

  2. Criar o arquivo 'antlr4.bat', com o conteúdo descrito abaixo.

    antlr4.bat

    java org.antlr.v4.Tool %*
  3. Criar o arquivo 'grun.bat', com o conteúdo descrito abaixo.

    grun.bat

    @ECHO OFF
    SET TEST_CURRENT_DIR=%CLASSPATH:.;=%
    if "%TEST_CURRENT_DIR%" == "%CLASSPATH%" ( SET CLASSPATH=.;%CLASSPATH% )
    @ECHO ON
    java org.antlr.v4.gui.TestRig %*
  4. Adicionar o diretório na variável de ambiente PATH.

    Exemplo: [Environment]::SetEnvironmentVariable("PATH", $Env:Path + ";C:\JavaLib\antlr4", 'Machine')

NET Core

Para projetos utilizando o ANTLR4 com .NET Core, é necessário o uso do pacote Antlr4.Runtime.Standard, no projeto onde o ANTLR esteja configurado.

Gerar Arquivos Auxiliares

Com os comandos de atalho criados utilize o comando abaixo para gerar os arquivos do ANTLR4 a partir do g4.

antlr4 -Dlanguage=<linguagem destino> <nome arquivo>.g4 <opções>

Exemplo: antlr4 -Dlanguage=CSharp Language.g4 -visitor -no-listener

Caso não possua os atalhos utilizar o comando completo, exibido abaixo.

java -jar antlr<versão-instalada>.jar -Dlanguage=<linguagem destino> <nome arquivo>.g4 <opções>

Exemplo: java -jar antlr-4.8-complete.jar -Dlanguage=CSharp Language.g4 -visitor -no-listener

Referências