First commit
This commit is contained in:
1 parent
dccc52bd7c
commit
02ef7c706c
7 files changed
+187
-3
No files matched your search
@@ -0,0 +1,2 @@
|
|||||||
|
Marcel Guinhos de Menezes Feitosa (00000855041)
|
||||||
|
Aloisio
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user