Exercícios Micro (para juiz online)

Data de Publicação

17/03/2026

Data de Modificação

17/03/2026

Objetivo

Estes exercícios são curtos e autocontidos (“micro”) e servem para treinar (e avaliar) técnicas que serão reutilizadas no compilador do projeto principal.

A ideia é não amarrar o design do compilador nas Etapas 1–3, mas ainda assim permitir avaliação automatizada com contratos claros (entrada/saída).

Como a correção automática funciona (juiz online)

Cada exercício define:

  • Entrada: texto em stdin (uma ou mais linhas).
  • Saída: texto em stdout com formato exatamente definido.
  • Sem logs: qualquer texto extra (debug) em stdout reprova. Se quiser depurar, use stderr (se a plataforma permitir) ou remova antes de submeter.
  • Determinismo: a mesma entrada deve sempre gerar a mesma saída.

Se desejar, é possível adotar este padrão único de execução:

java -jar exercicio.jar < input.txt

O juiz compara stdout com o esperado.

Catálogo de exercícios possíveis (por etapa)

Etapa 2 (Léxico) — recomendados para implementar primeiro

  • E2-A: Tokenização completa
    • Treina: separar identificadores, números, delimitadores e operadores; diferenciar palavras reservadas; decidir por “maior consumo” (lookahead para :=, <=, >=); ignorar whitespace.
    • Avaliação: comparar lista de tokens emitidos.
  • E2-B: Erro léxico com linha/coluna
    • Treina: rastrear posição, atualizar em \n, e reportar erro no ponto certo.
    • Avaliação: saída padronizada de erro (linha/coluna/caractere) ou OK.

Etapa 3 (Parser manual)

  • E3-1: Precedência/associatividade de expressão
    • Treina: Expression/Term/Factor e parênteses.
    • Avaliação: imprimir árvore em formato padronizado (ex.: prefixo ou indentado).

Etapa 4 (ANTLR + Visitor)

  • E4-1: AST via Visitor
    • Treina: gramática + visitor para AST.
    • Avaliação: imprimir AST em formato padronizado.

Etapa 5 (Escopo)

  • E5-1: Checagem de “não declarada” e duplicada
    • Treina: pilha de escopos e lookup.
    • Avaliação: lista padronizada de erros.

Etapa 6 (Tipos)

  • E6-1: Type checking de expressões
    • Treina: bottom-up e mensagens de erro.
    • Avaliação: OK ou erro(s) padronizados.

Etapa 7 (Codegen)

  • E7-1: “Smoke test” de execução
    • Treina: gerar bytecode que executa e imprime resultado.
    • Avaliação: comparar stdout.

Exercícios da Etapa 2 (prontos para implementar agora)

E2-A — Tokenização completa (inclui lookahead)

Objetivo

Ler um trecho de código e imprimir a sequência de tokens reconhecidos.

Regras (contrato)

  • Ignorar espaços, tabs e quebras de linha.
  • Reconhecer:
    • IDENTIFIER: [A-Za-z][A-Za-z0-9]*
    • NUMBER: [0-9]+
    • ASSIGN: :=
    • RELOP: <=, >=
    • OP: um caractere entre + - * / = < >
    • DELIM: um caractere entre ( ) ; :
  • Palavras reservadas: program, var, integer, begin, end, if, then, else, while, do, writeln
    • Se o lexema for uma dessas palavras, o tipo deve ser KEYWORD.
  • Ao final, imprimir EOF.

Regra de “maior consumo” (maximal munch): - Se houver duas possibilidades no mesmo ponto (ex.: : e :=), o scanner deve escolher a que consome mais caracteres (:=). - O mesmo vale para < versus <= e > versus >=.

Entrada

Texto arbitrário (1 ou mais linhas) via stdin. Considere que o programa termina no EOF do stdin.

Saída

Uma linha por token, exatamente:

[TIPO, "lexema"]

Onde TIPO ∈ {KEYWORD, IDENTIFIER, NUMBER, OP, DELIM, ASSIGN, RELOP, EOF}.

Exemplo (não é caso de teste oficial)

Entrada:

var x : integer;
x := 10 + 5;

Saída (ilustrativa):

[KEYWORD, "var"]
[IDENTIFIER, "x"]
[DELIM, ":"]
[KEYWORD, "integer"]
[DELIM, ";"]
[IDENTIFIER, "x"]
[ASSIGN, ":="]
[NUMBER, "10"]
[OP, "+"]
[NUMBER, "5"]
[DELIM, ";"]
[EOF, ""]

Critério de avaliação

  • 100% por comparação exata do stdout.
  • Qualquer token extra/faltando reprova.

E2-B — Erro léxico com linha e coluna

Objetivo

Detectar um caractere inválido e reportar sua posição.

Regras

  • Considere válidos: letras, dígitos, whitespace, e os símbolos + - * / ( ) ; : = < >.
  • O token := deve ser reconhecido como ASSIGN.
  • Qualquer outro caractere deve gerar erro.

Entrada

Texto (1 ou mais linhas) via stdin.

Saída

Se não houver erro léxico, imprima:

OK

Se houver erro, imprima exatamente uma linha:

LEXICAL_ERROR line=<L> col=<C> char="<X>"

Onde:

  • L e C começam em 1.
  • <X> é o caractere inválido.

Critério de avaliação

  • O juiz usa casos com múltiplas linhas para validar line/col.
  • A coluna deve refletir a posição do caractere na linha atual (após \n, reinicia).

Observações de implementação (para o aluno)

  • Manter pos, line, col e métodos peek()/advance() simplifica muito.
  • Para palavras reservadas: reconheça como IDENTIFIER primeiro e depois cheque em um Map<String, TokenType>.
  • Sempre que reconhecer : faça lookahead para decidir entre : e :=.
De volta ao topo