First commit

This commit is contained in:
mguinhos committed 2026-10-06 23:05:44 +00:00
1 parent dccc52bd7c
commit 02ef7c706c
7 files changed
+187 -3

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
Marcel Guinhos de Menezes Feitosa (00000855041)
Aloisio
+3 -3
View File
@@ -41,9 +41,7 @@ TEST_SRCS := tests/test_main.c tests/test_lexer.c tests/test_parser.c $(LIB_SRCS
ARGS ?= examples/testaparidade.pas ARGS ?= examples/testaparidade.pas
.PHONY: all help build run test clean .PHONY: help all build run test clean
all: build
help: help:
@echo "micro-Pascal - alvos disponiveis" @echo "micro-Pascal - alvos disponiveis"
@@ -53,6 +51,8 @@ help:
@echo " make test compila e executa a suite de testes" @echo " make test compila e executa a suite de testes"
@echo " make clean remove o diretorio build" @echo " make clean remove o diretorio build"
all: build
build: $(BIN) build: $(BIN)
$(BIN): $(APP_SRCS) $(BIN): $(APP_SRCS)
+6
View File
@@ -36,6 +36,12 @@ micro-pascal/
Todos os arquivos de cabecalho residem em include/. Todos os arquivos de cabecalho residem em include/.
## Requisitos de compilacao
- Compilador C99 (gcc/cc ou clang).
- GNU Make.
- Alvos suportados: Linux e Windows.
## Uso ## Uso
``` ```
+18
View File
@@ -9,24 +9,30 @@ static char* lerArquivo(const char* caminho, long* tamanho)
{ {
FILE* arquivo = fopen(caminho, "rb"); FILE* arquivo = fopen(caminho, "rb");
char* conteudo; char* conteudo;
if (arquivo == NULL) { if (arquivo == NULL) {
return NULL; return NULL;
} }
fseek(arquivo, 0, SEEK_END); fseek(arquivo, 0, SEEK_END);
*tamanho = ftell(arquivo); *tamanho = ftell(arquivo);
fseek(arquivo, 0, SEEK_SET); fseek(arquivo, 0, SEEK_SET);
conteudo = (char*)malloc((size_t)(*tamanho) + 1); conteudo = (char*)malloc((size_t)(*tamanho) + 1);
if (conteudo == NULL) { if (conteudo == NULL) {
fclose(arquivo); fclose(arquivo);
return NULL; return NULL;
} }
if (fread(conteudo, 1, (size_t)(*tamanho), arquivo) != (size_t)(*tamanho)) { if (fread(conteudo, 1, (size_t)(*tamanho), arquivo) != (size_t)(*tamanho)) {
free(conteudo); free(conteudo);
fclose(arquivo); fclose(arquivo);
return NULL; return NULL;
} }
conteudo[*tamanho] = '\0'; conteudo[*tamanho] = '\0';
fclose(arquivo); fclose(arquivo);
return conteudo; return conteudo;
} }
@@ -34,18 +40,24 @@ static void imprimirTokens(const char* fonte)
{ {
Lexer lexer; Lexer lexer;
Token token; Token token;
lexerInicializar(&lexer, fonte); lexerInicializar(&lexer, fonte);
do { do {
token = lexerProximoToken(&lexer); token = lexerProximoToken(&lexer);
if (token.kind == TOKEN_ERRO) { if (token.kind == TOKEN_ERRO) {
tokenLiberar(&token); tokenLiberar(&token);
break; break;
} }
printf("%s [%s]\n", tokenKindNome(token.kind), token.lexema); printf("%s [%s]\n", tokenKindNome(token.kind), token.lexema);
if (token.kind == TOKEN_EOF) { if (token.kind == TOKEN_EOF) {
tokenLiberar(&token); tokenLiberar(&token);
break; break;
} }
tokenLiberar(&token); tokenLiberar(&token);
} while (1); } while (1);
} }
@@ -64,11 +76,13 @@ int main(int argc, char** argv)
caminho = argv[1]; caminho = argv[1];
modo = "--ast"; modo = "--ast";
if (argc >= 3) { if (argc >= 3) {
modo = argv[2]; modo = argv[2];
} }
fonte = lerArquivo(caminho, &tamanho); fonte = lerArquivo(caminho, &tamanho);
if (fonte == NULL) { if (fonte == NULL) {
printf("Nao foi possivel abrir o arquivo [%s]\n", caminho); printf("Nao foi possivel abrir o arquivo [%s]\n", caminho);
return 1; return 1;
@@ -84,20 +98,24 @@ int main(int argc, char** argv)
Lexer lexer; Lexer lexer;
Parser parser; Parser parser;
AstNo* programa; AstNo* programa;
lexerInicializar(&lexer, fonte); lexerInicializar(&lexer, fonte);
parserInicializar(&parser, &lexer); parserInicializar(&parser, &lexer);
programa = parserAnalisarPrograma(&parser); programa = parserAnalisarPrograma(&parser);
tokenLiberar(&parser.atual); tokenLiberar(&parser.atual);
if (parser.houve_erro) { if (parser.houve_erro) {
astLiberar(programa); astLiberar(programa);
free(fonte); free(fonte);
return 1; return 1;
} }
printf("Analise sintatica concluida com sucesso.\n"); printf("Analise sintatica concluida com sucesso.\n");
astImprimir(programa, 0); astImprimir(programa, 0);
astLiberar(programa); astLiberar(programa);
} }
free(fonte); free(fonte);
return 0; return 0;
} }
+73
View File
@@ -23,22 +23,27 @@ static int lexerAcabou(const Lexer* lexer)
static char lexerEspiar(const Lexer* lexer, size_t deslocamento) static char lexerEspiar(const Lexer* lexer, size_t deslocamento)
{ {
size_t indice = lexer->posicao + deslocamento; size_t indice = lexer->posicao + deslocamento;
if (indice >= lexer->tamanho) { if (indice >= lexer->tamanho) {
return '\0'; return '\0';
} }
return lexer->fonte[indice]; return lexer->fonte[indice];
} }
static char lexerAvancar(Lexer* lexer) static char lexerAvancar(Lexer* lexer)
{ {
char atual = lexer->fonte[lexer->posicao]; char atual = lexer->fonte[lexer->posicao];
lexer->posicao++; lexer->posicao++;
if (atual == '\n') { if (atual == '\n') {
lexer->linha++; lexer->linha++;
lexer->coluna = 1; lexer->coluna = 1;
} else { } else {
lexer->coluna++; lexer->coluna++;
} }
return atual; return atual;
} }
@@ -56,21 +61,26 @@ static char* lexerCopiarIntervalo(const Lexer* lexer, size_t inicio, size_t fim)
{ {
size_t comprimento = fim - inicio; size_t comprimento = fim - inicio;
char* resultado = (char*)malloc(comprimento + 1); char* resultado = (char*)malloc(comprimento + 1);
if (resultado == NULL) { if (resultado == NULL) {
return NULL; return NULL;
} }
memcpy(resultado, lexer->fonte + inicio, comprimento); memcpy(resultado, lexer->fonte + inicio, comprimento);
resultado[comprimento] = '\0'; resultado[comprimento] = '\0';
return resultado; return resultado;
} }
static Token lexerCriarToken(const Lexer* lexer, TokenKind kind, size_t inicio, int linha, int coluna) static Token lexerCriarToken(const Lexer* lexer, TokenKind kind, size_t inicio, int linha, int coluna)
{ {
Token token; Token token;
token.kind = kind; token.kind = kind;
token.lexema = lexerCopiarIntervalo(lexer, inicio, lexer->posicao); token.lexema = lexerCopiarIntervalo(lexer, inicio, lexer->posicao);
token.linha = linha; token.linha = linha;
token.coluna = coluna; token.coluna = coluna;
return token; return token;
} }
@@ -79,72 +89,93 @@ static TokenKind lexerPalavraReservada(const char* lexema)
if (strcmp(lexema, "program") == 0) { if (strcmp(lexema, "program") == 0) {
return TOKEN_PROGRAM; return TOKEN_PROGRAM;
} }
if (strcmp(lexema, "if") == 0) { if (strcmp(lexema, "if") == 0) {
return TOKEN_IF; return TOKEN_IF;
} }
if (strcmp(lexema, "then") == 0) { if (strcmp(lexema, "then") == 0) {
return TOKEN_THEN; return TOKEN_THEN;
} }
if (strcmp(lexema, "else") == 0) { if (strcmp(lexema, "else") == 0) {
return TOKEN_ELSE; return TOKEN_ELSE;
} }
if (strcmp(lexema, "while") == 0) { if (strcmp(lexema, "while") == 0) {
return TOKEN_WHILE; return TOKEN_WHILE;
} }
if (strcmp(lexema, "do") == 0) { if (strcmp(lexema, "do") == 0) {
return TOKEN_DO; return TOKEN_DO;
} }
if (strcmp(lexema, "repeat") == 0) { if (strcmp(lexema, "repeat") == 0) {
return TOKEN_REPEAT; return TOKEN_REPEAT;
} }
if (strcmp(lexema, "until") == 0) { if (strcmp(lexema, "until") == 0) {
return TOKEN_UNTIL; return TOKEN_UNTIL;
} }
if (strcmp(lexema, "integer") == 0) { if (strcmp(lexema, "integer") == 0) {
return TOKEN_INTEGER; return TOKEN_INTEGER;
} }
if (strcmp(lexema, "real") == 0) { if (strcmp(lexema, "real") == 0) {
return TOKEN_REAL; return TOKEN_REAL;
} }
if (strcmp(lexema, "char") == 0) { if (strcmp(lexema, "char") == 0) {
return TOKEN_CHAR; return TOKEN_CHAR;
} }
if (strcmp(lexema, "begin") == 0) { if (strcmp(lexema, "begin") == 0) {
return TOKEN_BEGIN; return TOKEN_BEGIN;
} }
if (strcmp(lexema, "end") == 0) { if (strcmp(lexema, "end") == 0) {
return TOKEN_END; return TOKEN_END;
} }
if (strcmp(lexema, "write") == 0) { if (strcmp(lexema, "write") == 0) {
return TOKEN_WRITE; return TOKEN_WRITE;
} }
if (strcmp(lexema, "var") == 0) { if (strcmp(lexema, "var") == 0) {
return TOKEN_VAR; return TOKEN_VAR;
} }
if (strcmp(lexema, "div") == 0) { if (strcmp(lexema, "div") == 0) {
return TOKEN_DIV; return TOKEN_DIV;
} }
if (strcmp(lexema, "and") == 0) { if (strcmp(lexema, "and") == 0) {
return TOKEN_AND; return TOKEN_AND;
} }
if (strcmp(lexema, "or") == 0) { if (strcmp(lexema, "or") == 0) {
return TOKEN_OR; return TOKEN_OR;
} }
if (strcmp(lexema, "not") == 0) { if (strcmp(lexema, "not") == 0) {
return TOKEN_NOT; return TOKEN_NOT;
} }
return TOKEN_IDENTIFICADOR; return TOKEN_IDENTIFICADOR;
} }
static Token lexerErro(Lexer* lexer, char caractere, int linha, int coluna) static Token lexerErro(Lexer* lexer, char caractere, int linha, int coluna)
{ {
Token token; Token token;
lexer->houve_erro = 1; lexer->houve_erro = 1;
token.kind = TOKEN_ERRO; token.kind = TOKEN_ERRO;
printf("Erro léxico no caracter [%c]\n", caractere); printf("Erro léxico no caracter [%c]\n", caractere);
token.lexema = lexerCopiarIntervalo(lexer, lexer->posicao, lexer->posicao); token.lexema = lexerCopiarIntervalo(lexer, lexer->posicao, lexer->posicao);
token.linha = linha; token.linha = linha;
token.coluna = coluna; token.coluna = coluna;
return token; return token;
} }
@@ -154,11 +185,14 @@ static Token lexerLerIdentificador(Lexer* lexer)
int linha = lexer->linha; int linha = lexer->linha;
int coluna = lexer->coluna; int coluna = lexer->coluna;
Token token; Token token;
while (!lexerAcabou(lexer) && (ehLetra(lexerEspiar(lexer, 0)) || ehDigito(lexerEspiar(lexer, 0)))) { while (!lexerAcabou(lexer) && (ehLetra(lexerEspiar(lexer, 0)) || ehDigito(lexerEspiar(lexer, 0)))) {
lexerAvancar(lexer); lexerAvancar(lexer);
} }
token = lexerCriarToken(lexer, TOKEN_IDENTIFICADOR, inicio, linha, coluna); token = lexerCriarToken(lexer, TOKEN_IDENTIFICADOR, inicio, linha, coluna);
token.kind = lexerPalavraReservada(token.lexema); token.kind = lexerPalavraReservada(token.lexema);
return token; return token;
} }
@@ -168,23 +202,30 @@ static Token lexerLerNumero(Lexer* lexer)
int linha = lexer->linha; int linha = lexer->linha;
int coluna = lexer->coluna; int coluna = lexer->coluna;
TokenKind kind = TOKEN_INTEIRO_LITERAL; TokenKind kind = TOKEN_INTEIRO_LITERAL;
if (lexerEspiar(lexer, 0) == '.') { if (lexerEspiar(lexer, 0) == '.') {
lexerAvancar(lexer); lexerAvancar(lexer);
while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) { while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) {
lexerAvancar(lexer); lexerAvancar(lexer);
} }
return lexerCriarToken(lexer, TOKEN_REAL_LITERAL, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_REAL_LITERAL, inicio, linha, coluna);
} }
while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) { while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) {
lexerAvancar(lexer); lexerAvancar(lexer);
} }
if (lexerEspiar(lexer, 0) == '.' && ehDigito(lexerEspiar(lexer, 1))) { if (lexerEspiar(lexer, 0) == '.' && ehDigito(lexerEspiar(lexer, 1))) {
kind = TOKEN_REAL_LITERAL; kind = TOKEN_REAL_LITERAL;
lexerAvancar(lexer); lexerAvancar(lexer);
while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) { while (!lexerAcabou(lexer) && ehDigito(lexerEspiar(lexer, 0))) {
lexerAvancar(lexer); lexerAvancar(lexer);
} }
} }
return lexerCriarToken(lexer, kind, inicio, linha, coluna); return lexerCriarToken(lexer, kind, inicio, linha, coluna);
} }
@@ -194,13 +235,18 @@ static Token lexerLerChar(Lexer* lexer)
int linha = lexer->linha; int linha = lexer->linha;
int coluna = lexer->coluna; int coluna = lexer->coluna;
char conteudo; char conteudo;
lexerAvancar(lexer); lexerAvancar(lexer);
if (lexerAcabou(lexer)) { if (lexerAcabou(lexer)) {
return lexerErro(lexer, '\'', linha, coluna); return lexerErro(lexer, '\'', linha, coluna);
} }
conteudo = lexerEspiar(lexer, 0); conteudo = lexerEspiar(lexer, 0);
if (conteudo == '\\') { if (conteudo == '\\') {
char escapado = lexerEspiar(lexer, 1); char escapado = lexerEspiar(lexer, 1);
if (escapado == 'n' || escapado == 't') { if (escapado == 'n' || escapado == 't') {
lexerAvancar(lexer); lexerAvancar(lexer);
lexerAvancar(lexer); lexerAvancar(lexer);
@@ -212,10 +258,13 @@ static Token lexerLerChar(Lexer* lexer)
} else { } else {
return lexerErro(lexer, conteudo, linha, coluna); return lexerErro(lexer, conteudo, linha, coluna);
} }
if (lexerEspiar(lexer, 0) != '\'') { if (lexerEspiar(lexer, 0) != '\'') {
return lexerErro(lexer, lexerEspiar(lexer, 0), linha, coluna); return lexerErro(lexer, lexerEspiar(lexer, 0), linha, coluna);
} }
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_CHAR_LITERAL, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_CHAR_LITERAL, inicio, linha, coluna);
} }
@@ -229,10 +278,12 @@ Token lexerProximoToken(Lexer* lexer)
while (!lexerAcabou(lexer)) { while (!lexerAcabou(lexer)) {
atual = lexerEspiar(lexer, 0); atual = lexerEspiar(lexer, 0);
if (atual == ' ' || atual == '\n' || atual == '\t' || atual == '\r') { if (atual == ' ' || atual == '\n' || atual == '\t' || atual == '\r') {
lexerAvancar(lexer); lexerAvancar(lexer);
continue; continue;
} }
break; break;
} }
@@ -241,6 +292,7 @@ Token lexerProximoToken(Lexer* lexer)
token.lexema = lexerCopiarIntervalo(lexer, lexer->posicao, lexer->posicao); token.lexema = lexerCopiarIntervalo(lexer, lexer->posicao, lexer->posicao);
token.linha = lexer->linha; token.linha = lexer->linha;
token.coluna = lexer->coluna; token.coluna = lexer->coluna;
return token; return token;
} }
@@ -252,12 +304,15 @@ Token lexerProximoToken(Lexer* lexer)
if (ehLetra(atual)) { if (ehLetra(atual)) {
return lexerLerIdentificador(lexer); return lexerLerIdentificador(lexer);
} }
if (ehDigito(atual)) { if (ehDigito(atual)) {
return lexerLerNumero(lexer); return lexerLerNumero(lexer);
} }
if (atual == '\'') { if (atual == '\'') {
return lexerLerChar(lexer); return lexerLerChar(lexer);
} }
if (atual == '.' && ehDigito(lexerEspiar(lexer, 1))) { if (atual == '.' && ehDigito(lexerEspiar(lexer, 1))) {
return lexerLerNumero(lexer); return lexerLerNumero(lexer);
} }
@@ -265,61 +320,79 @@ Token lexerProximoToken(Lexer* lexer)
switch (atual) { switch (atual) {
case '<': case '<':
lexerAvancar(lexer); lexerAvancar(lexer);
if (lexerEspiar(lexer, 0) == '=') { if (lexerEspiar(lexer, 0) == '=') {
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_MENOR_IGUAL, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MENOR_IGUAL, inicio, linha, coluna);
} }
if (lexerEspiar(lexer, 0) == '>') { if (lexerEspiar(lexer, 0) == '>') {
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_DIFERENTE, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_DIFERENTE, inicio, linha, coluna);
} }
return lexerCriarToken(lexer, TOKEN_MENOR, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MENOR, inicio, linha, coluna);
case '>': case '>':
lexerAvancar(lexer); lexerAvancar(lexer);
if (lexerEspiar(lexer, 0) == '=') { if (lexerEspiar(lexer, 0) == '=') {
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_MAIOR_IGUAL, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MAIOR_IGUAL, inicio, linha, coluna);
} }
return lexerCriarToken(lexer, TOKEN_MAIOR, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MAIOR, inicio, linha, coluna);
case '=': case '=':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_IGUAL, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_IGUAL, inicio, linha, coluna);
case '+': case '+':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_MAIS, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MAIS, inicio, linha, coluna);
case '-': case '-':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_MENOS, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MENOS, inicio, linha, coluna);
case '*': case '*':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_MULTIPLICACAO, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_MULTIPLICACAO, inicio, linha, coluna);
case '/': case '/':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_DIVISAO, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_DIVISAO, inicio, linha, coluna);
case ':': case ':':
lexerAvancar(lexer); lexerAvancar(lexer);
if (lexerEspiar(lexer, 0) == '=') { if (lexerEspiar(lexer, 0) == '=') {
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_ATRIBUICAO, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_ATRIBUICAO, inicio, linha, coluna);
} }
return lexerCriarToken(lexer, TOKEN_DOIS_PONTOS, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_DOIS_PONTOS, inicio, linha, coluna);
case '(': case '(':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_ABRE_PARENTESES, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_ABRE_PARENTESES, inicio, linha, coluna);
case ')': case ')':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_FECHA_PARENTESES, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_FECHA_PARENTESES, inicio, linha, coluna);
case ',': case ',':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_VIRGULA, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_VIRGULA, inicio, linha, coluna);
case ';': case ';':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_PONTO_VIRGULA, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_PONTO_VIRGULA, inicio, linha, coluna);
case '.': case '.':
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerCriarToken(lexer, TOKEN_PONTO, inicio, linha, coluna); return lexerCriarToken(lexer, TOKEN_PONTO, inicio, linha, coluna);
default: default:
lexerAvancar(lexer); lexerAvancar(lexer);
return lexerErro(lexer, atual, linha, coluna); return lexerErro(lexer, atual, linha, coluna);
} }
} }
+9
View File
@@ -51,13 +51,16 @@ void astLiberar(AstNo* no)
if (no == NULL) { if (no == NULL) {
return; return;
} }
astLiberar(no->esquerda); astLiberar(no->esquerda);
astLiberar(no->direita); astLiberar(no->direita);
astLiberar(no->terceiro); astLiberar(no->terceiro);
astLiberar(no->proximo); astLiberar(no->proximo);
if (no->valor != NULL) { if (no->valor != NULL) {
free(no->valor); free(no->valor);
} }
free(no); free(no);
} }
@@ -65,20 +68,26 @@ void astImprimir(const AstNo* no, int profundidade)
{ {
int i; int i;
const AstNo* atual; const AstNo* atual;
if (no == NULL) { if (no == NULL) {
return; return;
} }
for (i = 0; i < profundidade; i++) { for (i = 0; i < profundidade; i++) {
printf(" "); printf(" ");
} }
printf("%s", astKindNome(no->kind)); printf("%s", astKindNome(no->kind));
if (no->valor != NULL) { if (no->valor != NULL) {
printf(" (%s)", no->valor); printf(" (%s)", no->valor);
} }
printf("\n"); printf("\n");
astImprimir(no->esquerda, profundidade + 1); astImprimir(no->esquerda, profundidade + 1);
astImprimir(no->direita, profundidade + 1); astImprimir(no->direita, profundidade + 1);
astImprimir(no->terceiro, profundidade + 1); astImprimir(no->terceiro, profundidade + 1);
for (atual = no->proximo; atual != NULL; atual = atual->proximo) { for (atual = no->proximo; atual != NULL; atual = atual->proximo) {
astImprimir(atual, profundidade); astImprimir(atual, profundidade);
} }
+76
View File
@@ -7,17 +7,21 @@
static AstNo* parserCriarNo(AstKind kind, const char* valor) static AstNo* parserCriarNo(AstKind kind, const char* valor)
{ {
AstNo* no = (AstNo*)malloc(sizeof(AstNo)); AstNo* no = (AstNo*)malloc(sizeof(AstNo));
no->kind = kind; no->kind = kind;
if (valor != NULL) { if (valor != NULL) {
no->valor = (char*)malloc(strlen(valor) + 1); no->valor = (char*)malloc(strlen(valor) + 1);
strcpy(no->valor, valor); strcpy(no->valor, valor);
} else { } else {
no->valor = NULL; no->valor = NULL;
} }
no->esquerda = NULL; no->esquerda = NULL;
no->direita = NULL; no->direita = NULL;
no->terceiro = NULL; no->terceiro = NULL;
no->proximo = NULL; no->proximo = NULL;
return no; return no;
} }
@@ -37,6 +41,7 @@ void parserInicializar(Parser* parser, Lexer* lexer)
parser->houve_erro = 0; parser->houve_erro = 0;
parser->total_erros = 0; parser->total_erros = 0;
parser->silencioso = 0; parser->silencioso = 0;
parserAvancar(parser); parserAvancar(parser);
} }
@@ -48,11 +53,14 @@ void parserSilenciarErros(Parser* parser, int silenciar)
static void parserErro(Parser* parser) static void parserErro(Parser* parser)
{ {
const char* lexema = parser->atual.lexema; const char* lexema = parser->atual.lexema;
if (lexema == NULL) { if (lexema == NULL) {
lexema = ""; lexema = "";
} }
parser->houve_erro = 1; parser->houve_erro = 1;
parser->total_erros++; parser->total_erros++;
if (!parser->silencioso) { if (!parser->silencioso) {
printf("Erro de sintaxe no token [%s]\n", lexema); printf("Erro de sintaxe no token [%s]\n", lexema);
} }
@@ -69,6 +77,7 @@ static int parserConsumir(Parser* parser, TokenKind kind)
parserAvancar(parser); parserAvancar(parser);
return 1; return 1;
} }
return 0; return 0;
} }
@@ -77,7 +86,9 @@ static int parserEsperar(Parser* parser, TokenKind kind)
if (parserConsumir(parser, kind)) { if (parserConsumir(parser, kind)) {
return 1; return 1;
} }
parserErro(parser); parserErro(parser);
return 0; return 0;
} }
@@ -99,20 +110,25 @@ static int parserEmInicioDeComando(Parser* parser)
static AstNo* parserAnalisarBloco(Parser* parser); static AstNo* parserAnalisarBloco(Parser* parser);
static AstNo* parserAnalisarComando(Parser* parser); static AstNo* parserAnalisarComando(Parser* parser);
static AstNo* parserAnalisarExpressao(Parser* parser); static AstNo* parserAnalisarExpressao(Parser* parser);
static AstNo* parserAnalisarTipo(Parser* parser) static AstNo* parserAnalisarTipo(Parser* parser)
{ {
switch (parser->atual.kind) { switch (parser->atual.kind) {
case TOKEN_INTEGER: case TOKEN_INTEGER:
parserAvancar(parser); parserAvancar(parser);
return parserCriarNo(AST_TIPO, "integer"); return parserCriarNo(AST_TIPO, "integer");
case TOKEN_REAL: case TOKEN_REAL:
parserAvancar(parser); parserAvancar(parser);
return parserCriarNo(AST_TIPO, "real"); return parserCriarNo(AST_TIPO, "real");
case TOKEN_CHAR: case TOKEN_CHAR:
parserAvancar(parser); parserAvancar(parser);
return parserCriarNo(AST_TIPO, "char"); return parserCriarNo(AST_TIPO, "char");
default: default:
parserErro(parser); parserErro(parser);
return NULL; return NULL;
} }
} }
@@ -128,15 +144,18 @@ static AstNo* parserAnalisarDeclVar(Parser* parser)
astLiberar(decl); astLiberar(decl);
return NULL; return NULL;
} }
identificador = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL); identificador = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL);
decl->esquerda = identificador; decl->esquerda = identificador;
ultimo = identificador; ultimo = identificador;
while (parserVerificar(parser, TOKEN_VIRGULA)) { while (parserVerificar(parser, TOKEN_VIRGULA)) {
parserAvancar(parser); parserAvancar(parser);
if (!parserEsperar(parser, TOKEN_IDENTIFICADOR)) { if (!parserEsperar(parser, TOKEN_IDENTIFICADOR)) {
return decl; return decl;
} }
ultimo->proximo = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL); ultimo->proximo = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL);
ultimo = ultimo->proximo; ultimo = ultimo->proximo;
} }
@@ -144,11 +163,14 @@ static AstNo* parserAnalisarDeclVar(Parser* parser)
if (!parserEsperar(parser, TOKEN_DOIS_PONTOS)) { if (!parserEsperar(parser, TOKEN_DOIS_PONTOS)) {
return decl; return decl;
} }
tipo = parserAnalisarTipo(parser); tipo = parserAnalisarTipo(parser);
decl->direita = tipo; decl->direita = tipo;
if (!parserEsperar(parser, TOKEN_PONTO_VIRGULA)) { if (!parserEsperar(parser, TOKEN_PONTO_VIRGULA)) {
return decl; return decl;
} }
return decl; return decl;
} }
@@ -156,58 +178,72 @@ static AstNo* parserAnalisarSecaoVar(Parser* parser)
{ {
AstNo* secao = parserCriarNo(AST_SECAO_VAR, NULL); AstNo* secao = parserCriarNo(AST_SECAO_VAR, NULL);
AstNo* ultimo = NULL; AstNo* ultimo = NULL;
if (!parserEsperar(parser, TOKEN_VAR)) { if (!parserEsperar(parser, TOKEN_VAR)) {
astLiberar(secao); astLiberar(secao);
return NULL; return NULL;
} }
while (parserVerificar(parser, TOKEN_IDENTIFICADOR)) { while (parserVerificar(parser, TOKEN_IDENTIFICADOR)) {
AstNo* decl = parserAnalisarDeclVar(parser); AstNo* decl = parserAnalisarDeclVar(parser);
if (decl == NULL) { if (decl == NULL) {
break; break;
} }
if (ultimo == NULL) { if (ultimo == NULL) {
secao->esquerda = decl; secao->esquerda = decl;
} else { } else {
ultimo->proximo = decl; ultimo->proximo = decl;
} }
ultimo = decl; ultimo = decl;
} }
return secao; return secao;
} }
static AstNo* parserAnalisarExprBasica(Parser* parser) static AstNo* parserAnalisarExprBasica(Parser* parser)
{ {
AstNo* no; AstNo* no;
switch (parser->atual.kind) { switch (parser->atual.kind) {
case TOKEN_ABRE_PARENTESES: case TOKEN_ABRE_PARENTESES:
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_EXPRESSAO_PARENTESES, NULL); no = parserCriarNo(AST_EXPRESSAO_PARENTESES, NULL);
no->esquerda = parserAnalisarExpressao(parser); no->esquerda = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_FECHA_PARENTESES); parserEsperar(parser, TOKEN_FECHA_PARENTESES);
return no; return no;
case TOKEN_NOT: case TOKEN_NOT:
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_EXPRESSAO_UNARIA, "not"); no = parserCriarNo(AST_EXPRESSAO_UNARIA, "not");
no->esquerda = parserAnalisarExprBasica(parser); no->esquerda = parserAnalisarExprBasica(parser);
return no; return no;
case TOKEN_INTEIRO_LITERAL: case TOKEN_INTEIRO_LITERAL:
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema); no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
return no; return no;
case TOKEN_REAL_LITERAL: case TOKEN_REAL_LITERAL:
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema); no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
return no; return no;
case TOKEN_CHAR_LITERAL: case TOKEN_CHAR_LITERAL:
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema); no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
return no; return no;
case TOKEN_IDENTIFICADOR: case TOKEN_IDENTIFICADOR:
no = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, parser->atual.lexema); no = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
return no; return no;
default: default:
parserErro(parser); parserErro(parser);
return NULL; return NULL;
} }
} }
@@ -215,10 +251,12 @@ static AstNo* parserAnalisarExprBasica(Parser* parser)
static AstNo* parserAnalisarExpMul(Parser* parser) static AstNo* parserAnalisarExpMul(Parser* parser)
{ {
AstNo* esquerda = parserAnalisarExprBasica(parser); AstNo* esquerda = parserAnalisarExprBasica(parser);
while (parser->atual.kind == TOKEN_MULTIPLICACAO || parser->atual.kind == TOKEN_DIVISAO || parser->atual.kind == TOKEN_DIV) { while (parser->atual.kind == TOKEN_MULTIPLICACAO || parser->atual.kind == TOKEN_DIVISAO || parser->atual.kind == TOKEN_DIV) {
char operador[8]; char operador[8];
AstNo* direita; AstNo* direita;
AstNo* novo; AstNo* novo;
strcpy(operador, parser->atual.lexema); strcpy(operador, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
direita = parserAnalisarExprBasica(parser); direita = parserAnalisarExprBasica(parser);
@@ -227,16 +265,19 @@ static AstNo* parserAnalisarExpMul(Parser* parser)
novo->direita = direita; novo->direita = direita;
esquerda = novo; esquerda = novo;
} }
return esquerda; return esquerda;
} }
static AstNo* parserAnalisarExpAd(Parser* parser) static AstNo* parserAnalisarExpAd(Parser* parser)
{ {
AstNo* esquerda = parserAnalisarExpMul(parser); AstNo* esquerda = parserAnalisarExpMul(parser);
while (parser->atual.kind == TOKEN_MAIS || parser->atual.kind == TOKEN_MENOS) { while (parser->atual.kind == TOKEN_MAIS || parser->atual.kind == TOKEN_MENOS) {
char operador[8]; char operador[8];
AstNo* direita; AstNo* direita;
AstNo* novo; AstNo* novo;
strcpy(operador, parser->atual.lexema); strcpy(operador, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
direita = parserAnalisarExpMul(parser); direita = parserAnalisarExpMul(parser);
@@ -245,16 +286,19 @@ static AstNo* parserAnalisarExpAd(Parser* parser)
novo->direita = direita; novo->direita = direita;
esquerda = novo; esquerda = novo;
} }
return esquerda; return esquerda;
} }
static AstNo* parserAnalisarExpRel(Parser* parser) static AstNo* parserAnalisarExpRel(Parser* parser)
{ {
AstNo* esquerda = parserAnalisarExpAd(parser); AstNo* esquerda = parserAnalisarExpAd(parser);
while (parser->atual.kind == TOKEN_IGUAL || parser->atual.kind == TOKEN_DIFERENTE || parser->atual.kind == TOKEN_MENOR || parser->atual.kind == TOKEN_MAIOR || parser->atual.kind == TOKEN_MENOR_IGUAL || parser->atual.kind == TOKEN_MAIOR_IGUAL) { while (parser->atual.kind == TOKEN_IGUAL || parser->atual.kind == TOKEN_DIFERENTE || parser->atual.kind == TOKEN_MENOR || parser->atual.kind == TOKEN_MAIOR || parser->atual.kind == TOKEN_MENOR_IGUAL || parser->atual.kind == TOKEN_MAIOR_IGUAL) {
char operador[8]; char operador[8];
AstNo* direita; AstNo* direita;
AstNo* novo; AstNo* novo;
strcpy(operador, parser->atual.lexema); strcpy(operador, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
direita = parserAnalisarExpAd(parser); direita = parserAnalisarExpAd(parser);
@@ -263,16 +307,19 @@ static AstNo* parserAnalisarExpRel(Parser* parser)
novo->direita = direita; novo->direita = direita;
esquerda = novo; esquerda = novo;
} }
return esquerda; return esquerda;
} }
static AstNo* parserAnalisarExpOrAnd(Parser* parser) static AstNo* parserAnalisarExpOrAnd(Parser* parser)
{ {
AstNo* esquerda = parserAnalisarExpRel(parser); AstNo* esquerda = parserAnalisarExpRel(parser);
while (parser->atual.kind == TOKEN_OR || parser->atual.kind == TOKEN_AND) { while (parser->atual.kind == TOKEN_OR || parser->atual.kind == TOKEN_AND) {
char operador[8]; char operador[8];
AstNo* direita; AstNo* direita;
AstNo* novo; AstNo* novo;
strcpy(operador, parser->atual.lexema); strcpy(operador, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
direita = parserAnalisarExpRel(parser); direita = parserAnalisarExpRel(parser);
@@ -281,6 +328,7 @@ static AstNo* parserAnalisarExpOrAnd(Parser* parser)
novo->direita = direita; novo->direita = direita;
esquerda = novo; esquerda = novo;
} }
return esquerda; return esquerda;
} }
@@ -292,59 +340,72 @@ static AstNo* parserAnalisarExpressao(Parser* parser)
static AstNo* parserAnalisarAtribuicao(Parser* parser) static AstNo* parserAnalisarAtribuicao(Parser* parser)
{ {
AstNo* no = parserCriarNo(AST_ATRIBUICAO, parser->atual.lexema); AstNo* no = parserCriarNo(AST_ATRIBUICAO, parser->atual.lexema);
parserAvancar(parser); parserAvancar(parser);
if (!parserEsperar(parser, TOKEN_ATRIBUICAO)) { if (!parserEsperar(parser, TOKEN_ATRIBUICAO)) {
return no; return no;
} }
no->esquerda = parserAnalisarExpressao(parser); no->esquerda = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_PONTO_VIRGULA); parserEsperar(parser, TOKEN_PONTO_VIRGULA);
return no; return no;
} }
static AstNo* parserAnalisarIteracao(Parser* parser) static AstNo* parserAnalisarIteracao(Parser* parser)
{ {
AstNo* no; AstNo* no;
if (parser->atual.kind == TOKEN_WHILE) { if (parser->atual.kind == TOKEN_WHILE) {
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_ITERACAO, "while"); no = parserCriarNo(AST_ITERACAO, "while");
no->esquerda = parserAnalisarExpressao(parser); no->esquerda = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_DO); parserEsperar(parser, TOKEN_DO);
no->direita = parserAnalisarComando(parser); no->direita = parserAnalisarComando(parser);
return no; return no;
} }
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_ITERACAO, "repeat"); no = parserCriarNo(AST_ITERACAO, "repeat");
no->esquerda = parserAnalisarComando(parser); no->esquerda = parserAnalisarComando(parser);
parserEsperar(parser, TOKEN_UNTIL); parserEsperar(parser, TOKEN_UNTIL);
no->direita = parserAnalisarExpressao(parser); no->direita = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_PONTO_VIRGULA); parserEsperar(parser, TOKEN_PONTO_VIRGULA);
return no; return no;
} }
static AstNo* parserAnalisarDecisao(Parser* parser) static AstNo* parserAnalisarDecisao(Parser* parser)
{ {
AstNo* no; AstNo* no;
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_DECISAO, NULL); no = parserCriarNo(AST_DECISAO, NULL);
no->esquerda = parserAnalisarExpressao(parser); no->esquerda = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_THEN); parserEsperar(parser, TOKEN_THEN);
no->direita = parserAnalisarComando(parser); no->direita = parserAnalisarComando(parser);
if (parserVerificar(parser, TOKEN_ELSE)) { if (parserVerificar(parser, TOKEN_ELSE)) {
parserAvancar(parser); parserAvancar(parser);
no->terceiro = parserAnalisarComando(parser); no->terceiro = parserAnalisarComando(parser);
} }
return no; return no;
} }
static AstNo* parserAnalisarEscrita(Parser* parser) static AstNo* parserAnalisarEscrita(Parser* parser)
{ {
AstNo* no; AstNo* no;
parserAvancar(parser); parserAvancar(parser);
no = parserCriarNo(AST_ESCRITA, NULL); no = parserCriarNo(AST_ESCRITA, NULL);
parserEsperar(parser, TOKEN_ABRE_PARENTESES); parserEsperar(parser, TOKEN_ABRE_PARENTESES);
no->esquerda = parserAnalisarExpressao(parser); no->esquerda = parserAnalisarExpressao(parser);
parserEsperar(parser, TOKEN_FECHA_PARENTESES); parserEsperar(parser, TOKEN_FECHA_PARENTESES);
parserEsperar(parser, TOKEN_PONTO_VIRGULA); parserEsperar(parser, TOKEN_PONTO_VIRGULA);
return no; return no;
} }
@@ -353,7 +414,9 @@ static AstNo* parserAnalisarComando(Parser* parser)
switch (parser->atual.kind) { switch (parser->atual.kind) {
case TOKEN_BEGIN: { case TOKEN_BEGIN: {
AstNo* bloco = parserAnalisarBloco(parser); AstNo* bloco = parserAnalisarBloco(parser);
parserEsperar(parser, TOKEN_PONTO_VIRGULA); parserEsperar(parser, TOKEN_PONTO_VIRGULA);
return bloco; return bloco;
} }
case TOKEN_IDENTIFICADOR: case TOKEN_IDENTIFICADOR:
@@ -367,6 +430,7 @@ static AstNo* parserAnalisarComando(Parser* parser)
return parserAnalisarEscrita(parser); return parserAnalisarEscrita(parser);
default: default:
parserErro(parser); parserErro(parser);
return NULL; return NULL;
} }
} }
@@ -382,20 +446,26 @@ static AstNo* parserAnalisarBloco(Parser* parser)
astLiberar(lista); astLiberar(lista);
return NULL; return NULL;
} }
while (parserEmInicioDeComando(parser)) { while (parserEmInicioDeComando(parser)) {
AstNo* comando = parserAnalisarComando(parser); AstNo* comando = parserAnalisarComando(parser);
if (comando == NULL) { if (comando == NULL) {
break; break;
} }
if (ultimo == NULL) { if (ultimo == NULL) {
lista->esquerda = comando; lista->esquerda = comando;
} else { } else {
ultimo->proximo = comando; ultimo->proximo = comando;
} }
ultimo = comando; ultimo = comando;
} }
parserEsperar(parser, TOKEN_END); parserEsperar(parser, TOKEN_END);
bloco->esquerda = lista; bloco->esquerda = lista;
return bloco; return bloco;
} }
@@ -407,6 +477,7 @@ AstNo* parserAnalisarPrograma(Parser* parser)
astLiberar(programa); astLiberar(programa);
return NULL; return NULL;
} }
if (parserVerificar(parser, TOKEN_IDENTIFICADOR)) { if (parserVerificar(parser, TOKEN_IDENTIFICADOR)) {
free(programa->valor); free(programa->valor);
programa->valor = (char*)malloc(strlen(parser->atual.lexema) + 1); programa->valor = (char*)malloc(strlen(parser->atual.lexema) + 1);
@@ -415,14 +486,19 @@ AstNo* parserAnalisarPrograma(Parser* parser)
} else { } else {
parserErro(parser); parserErro(parser);
} }
parserEsperar(parser, TOKEN_PONTO_VIRGULA); parserEsperar(parser, TOKEN_PONTO_VIRGULA);
if (parserVerificar(parser, TOKEN_VAR)) { if (parserVerificar(parser, TOKEN_VAR)) {
programa->esquerda = parserAnalisarSecaoVar(parser); programa->esquerda = parserAnalisarSecaoVar(parser);
} }
programa->direita = parserAnalisarBloco(parser); programa->direita = parserAnalisarBloco(parser);
parserEsperar(parser, TOKEN_PONTO); parserEsperar(parser, TOKEN_PONTO);
if (!parserVerificar(parser, TOKEN_EOF)) { if (!parserVerificar(parser, TOKEN_EOF)) {
parserErro(parser); parserErro(parser);
} }
return programa; return programa;
} }