Etapa 4: Gramática e Gerador ANTLR4
Objetivos
- Substituir o parser manual por um gerador de parsers industrial (ANTLR4).
- Aprender a linguagem de descrição de gramáticas
.g4. - Utilizar o padrão Visitor para converter a árvore concreta do ANTLR (ParseTree) na sua AST.
Fundamentação Teórica
Ferramentas como ANTLR geram automaticamente o código do Lexer e Parser a partir de uma especificação formal. Isso reduz erros e facilita a manutenção. No entanto, o ANTLR gera uma Parse Tree (Árvore Concreta), que contém todos os tokens (vírgulas, parênteses). Nosso objetivo é transformar isso na nossa AST (mais limpa) que definimos na Etapa 1.
Atividades Práticas
1. Preparação
- Instale o plugin do ANTLR4 na sua IDE.
- Adicione a dependência do ANTLR4 Runtime no
pom.xml.
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.13.1</version>
</dependency>2. Definindo a Gramática (MiniPascal.g4)
Crie o arquivo na pasta src/main/antlr4/br/com/compiler/parser. Exemplo de estrutura:
grammar MiniPascal;
// Parser Rules
program: 'program' ID ';' varDecl? block '.' EOF;
varDecl: 'var' (ID (',' ID)* ':' type ';')+;
type: 'integer' | 'boolean' | 'string';
// ... outras regras (command, expression, etc) ...
// Lexer Rules
ID: [a-zA-Z][a-zA-Z0-9]*;
NUMBER: [0-9]+;
WS: [ \t\r\n]+ -> skip;
3. Gerando o Código
Execute o comando Maven (ou use o plugin da IDE) para gerar as classes Java (MiniPascalLexer, MiniPascalParser, MiniPascalBaseVisitor, etc).
4. Implementando o Visitor
Crie uma classe MyVisitor que estende MiniPascalBaseVisitor<AstNode>. Você deve sobrescrever os métodos visit para construir seus nós.
Exemplo:
public class MyVisitor extends MiniPascalBaseVisitor<AstNode> {
@Override
public AstNode visitAssignment(MiniPascalParser.AssignmentContext ctx) {
// ctx.ID() retorna o token do identificador
Identifier id = new Identifier(ctx.ID().getText());
// ctx.expression() retorna o contexto da expressão filho
Expression expr = (Expression) visit(ctx.expression());
return new AssignmentCommand(id, expr);
}
@Override
public AstNode visitBinaryExpr(MiniPascalParser.BinaryExprContext ctx) {
Expression left = (Expression) visit(ctx.expression(0));
Expression right = (Expression) visit(ctx.expression(1));
String op = ctx.op.getText();
return new BinaryExpression(left, right, op);
}
}O que entregar
- Arquivo
MiniPascal.g4completo. - Classe
MyVisitorimplementando a conversão. - Atualize seu programa principal para usar o ANTLR Lexer/Parser, passar pelo Visitor e imprimir a AST. A saída deve ser idêntica (ou superior) à da Etapa 3.