Files
micro-pascal/tests/test_parser.c
T
2026-10-06 22:12:02 +00:00

112 lines
4.0 KiB
C

#include "micropascal-tests/testes.h"
#include "micropascal-lexer/lexer.h"
#include "micropascal-parser/parser.h"
#include <string.h>
static int programaValido(const char* fonte)
{
Lexer lexer;
Parser parser;
AstNo* programa;
int valido;
lexerInicializar(&lexer, fonte);
parserInicializar(&parser, &lexer);
parserSilenciarErros(&parser, 1);
programa = parserAnalisarPrograma(&parser);
valido = !parser.houve_erro;
tokenLiberar(&parser.atual);
astLiberar(programa);
return valido;
}
static const char* PROGRAMA_SIMPLES =
"program P;\n"
"var\n"
" x : integer;\n"
"begin\n"
" x := 1;\n"
"end.\n";
static const char* PROGRAMA_PARIDADE =
"program TestaParidade;\n"
"var\n"
" n : integer;\n"
"begin\n"
" n := 2 * 13 + 5;\n"
" if n = (n div 2)*2 then\n"
" write('p')\n"
" ;\n"
" else\n"
" write('i')\n"
" ;\n"
"end.\n";
static const char* PROGRAMA_IMPARES =
"program SomaImpares;\n"
"var\n"
" n : integer;\n"
" i, proximoImpar, soma : integer;\n"
"begin\n"
" n := 4;\n"
" i := 0;\n"
" soma := 0;\n"
" while i < n do\n"
" begin\n"
" proximoImpar := 2*i + 1;\n"
" soma := soma + proximoImpar;\n"
" i := i + 1;\n"
" end;\n"
" write(soma);\n"
" write('\\n');\n"
"end.\n";
static const char* PROGRAMA_REPEAT =
"program Contador;\n"
"var\n"
" i : integer;\n"
"begin\n"
" i := 0;\n"
" repeat\n"
" i := i + 1;\n"
" until i >= 10;\n"
"end.\n";
static const char* PROGRAMA_TIPOS =
"program Tipos;\n"
"var\n"
" a, b : integer;\n"
" c : real;\n"
" d : char;\n"
"begin\n"
" a := 1;\n"
" b := 2;\n"
" c := 1.5 + 2.5;\n"
" d := 'x';\n"
"end.\n";
void runParserTests(ResultadoTeste* resultado_testes)
{
TESTE_ASSERT(resultado_testes, programaValido(PROGRAMA_SIMPLES), "programa simples valido");
TESTE_ASSERT(resultado_testes, programaValido(PROGRAMA_PARIDADE), "programa TestaParidade valido");
TESTE_ASSERT(resultado_testes, programaValido(PROGRAMA_IMPARES), "programa SomaImpares valido");
TESTE_ASSERT(resultado_testes, programaValido(PROGRAMA_REPEAT), "programa com repeat until valido");
TESTE_ASSERT(resultado_testes, programaValido(PROGRAMA_TIPOS), "programa com varios tipos valido");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := 1 + 2 * 3;\nend.\n"), "precedencia multiplicacao sobre soma");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := (1 + 2) * 3;\nend.\n"), "parenteses");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := not a and b or c;\nend.\n"), "operadores not and or");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := a = b;\nend.\n"), "igualdade");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := a <> b;\nend.\n"), "diferente");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n x := a <= b;\nend.\n"), "menor ou igual");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n if a then b := 1;\nend.\n"), "decisao sem else");
TESTE_ASSERT(resultado_testes, programaValido("program P;\nbegin\n while a do b := 1;\nend.\n"), "iteracao while");
TESTE_ASSERT(resultado_testes, !programaValido("program P\nbegin end.\n"), "falta ponto e virgula apos nome");
TESTE_ASSERT(resultado_testes, !programaValido("program P;\nbegin\n x := ;\nend.\n"), "expressao ausente");
TESTE_ASSERT(resultado_testes, !programaValido("program P;\nbegin\n x := 1 +\nend.\n"), "operando ausente");
TESTE_ASSERT(resultado_testes, !programaValido("program P;\nbegin\n if a then\nend.\n"), "comando ausente apos then");
TESTE_ASSERT(resultado_testes, !programaValido("program P;\nvar x integer;\nbegin end.\n"), "falta dois pontos na declaracao");
TESTE_ASSERT(resultado_testes, !programaValido("program P;\nbegin\n x := 1\nend.\n"), "falta ponto e virgula no comando");
}