Exercícios Micro (para juiz online)
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
stdoutcom formato exatamente definido. - Sem logs: qualquer texto extra (debug) em
stdoutreprova. Se quiser depurar, usestderr(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.
- Treina: separar identificadores, números, delimitadores e operadores; diferenciar palavras reservadas; decidir por “maior consumo” (lookahead para
- 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.
- Treina: rastrear posição, atualizar em
Etapa 3 (Parser manual)
- E3-1: Precedência/associatividade de expressão
- Treina:
Expression/Term/Factore parênteses. - Avaliação: imprimir árvore em formato padronizado (ex.: prefixo ou indentado).
- Treina:
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.
- Treina: pilha de escopos e
Etapa 6 (Tipos)
- E6-1: Type checking de expressões
- Treina: bottom-up e mensagens de erro.
- Avaliação:
OKou 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.
- Se o lexema for uma dessas palavras, o tipo deve ser
- 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 comoASSIGN. - 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:
LeCcomeç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,cole métodospeek()/advance()simplifica muito. - Para palavras reservadas: reconheça como
IDENTIFIERprimeiro e depois cheque em umMap<String, TokenType>. - Sempre que reconhecer
:faça lookahead para decidir entre:e:=.