First commit
This commit is contained in:
1 parent
dccc52bd7c
commit
02ef7c706c
8 files changed
+427
-243
No files matched your search
+144
-68
@@ -7,17 +7,21 @@
|
||||
static AstNo* parserCriarNo(AstKind kind, const char* valor)
|
||||
{
|
||||
AstNo* no = (AstNo*)malloc(sizeof(AstNo));
|
||||
|
||||
no->kind = kind;
|
||||
|
||||
if (valor != NULL) {
|
||||
no->valor = (char*)malloc(strlen(valor) + 1);
|
||||
strcpy(no->valor, valor);
|
||||
} else {
|
||||
no->valor = NULL;
|
||||
}
|
||||
|
||||
no->esquerda = NULL;
|
||||
no->direita = NULL;
|
||||
no->terceiro = NULL;
|
||||
no->proximo = NULL;
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
@@ -37,6 +41,7 @@ void parserInicializar(Parser* parser, Lexer* lexer)
|
||||
parser->houve_erro = 0;
|
||||
parser->total_erros = 0;
|
||||
parser->silencioso = 0;
|
||||
|
||||
parserAvancar(parser);
|
||||
}
|
||||
|
||||
@@ -48,11 +53,14 @@ void parserSilenciarErros(Parser* parser, int silenciar)
|
||||
static void parserErro(Parser* parser)
|
||||
{
|
||||
const char* lexema = parser->atual.lexema;
|
||||
|
||||
if (lexema == NULL) {
|
||||
lexema = "";
|
||||
}
|
||||
|
||||
parser->houve_erro = 1;
|
||||
parser->total_erros++;
|
||||
|
||||
if (!parser->silencioso) {
|
||||
printf("Erro de sintaxe no token [%s]\n", lexema);
|
||||
}
|
||||
@@ -69,6 +77,7 @@ static int parserConsumir(Parser* parser, TokenKind kind)
|
||||
parserAvancar(parser);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -77,43 +86,50 @@ static int parserEsperar(Parser* parser, TokenKind kind)
|
||||
if (parserConsumir(parser, kind)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
parserErro(parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parserEmInicioDeComando(Parser* parser)
|
||||
{
|
||||
switch (parser->atual.kind) {
|
||||
case TOKEN_BEGIN:
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
case TOKEN_WHILE:
|
||||
case TOKEN_REPEAT:
|
||||
case TOKEN_IF:
|
||||
case TOKEN_WRITE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
case TOKEN_BEGIN:
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
case TOKEN_WHILE:
|
||||
case TOKEN_REPEAT:
|
||||
case TOKEN_IF:
|
||||
case TOKEN_WRITE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarBloco(Parser* parser);
|
||||
static AstNo* parserAnalisarComando(Parser* parser);
|
||||
static AstNo* parserAnalisarExpressao(Parser* parser);
|
||||
|
||||
static AstNo* parserAnalisarTipo(Parser* parser)
|
||||
{
|
||||
switch (parser->atual.kind) {
|
||||
case TOKEN_INTEGER:
|
||||
parserAvancar(parser);
|
||||
return parserCriarNo(AST_TIPO, "integer");
|
||||
case TOKEN_REAL:
|
||||
parserAvancar(parser);
|
||||
return parserCriarNo(AST_TIPO, "real");
|
||||
case TOKEN_CHAR:
|
||||
parserAvancar(parser);
|
||||
return parserCriarNo(AST_TIPO, "char");
|
||||
default:
|
||||
parserErro(parser);
|
||||
return NULL;
|
||||
case TOKEN_INTEGER:
|
||||
parserAvancar(parser);
|
||||
|
||||
return parserCriarNo(AST_TIPO, "integer");
|
||||
case TOKEN_REAL:
|
||||
parserAvancar(parser);
|
||||
|
||||
return parserCriarNo(AST_TIPO, "real");
|
||||
case TOKEN_CHAR:
|
||||
parserAvancar(parser);
|
||||
|
||||
return parserCriarNo(AST_TIPO, "char");
|
||||
default:
|
||||
parserErro(parser);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,15 +144,18 @@ static AstNo* parserAnalisarDeclVar(Parser* parser)
|
||||
astLiberar(decl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
identificador = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL);
|
||||
decl->esquerda = identificador;
|
||||
ultimo = identificador;
|
||||
|
||||
while (parserVerificar(parser, TOKEN_VIRGULA)) {
|
||||
parserAvancar(parser);
|
||||
|
||||
if (!parserEsperar(parser, TOKEN_IDENTIFICADOR)) {
|
||||
return decl;
|
||||
}
|
||||
|
||||
ultimo->proximo = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, NULL);
|
||||
ultimo = ultimo->proximo;
|
||||
}
|
||||
@@ -144,11 +163,14 @@ static AstNo* parserAnalisarDeclVar(Parser* parser)
|
||||
if (!parserEsperar(parser, TOKEN_DOIS_PONTOS)) {
|
||||
return decl;
|
||||
}
|
||||
|
||||
tipo = parserAnalisarTipo(parser);
|
||||
decl->direita = tipo;
|
||||
|
||||
if (!parserEsperar(parser, TOKEN_PONTO_VIRGULA)) {
|
||||
return decl;
|
||||
}
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
@@ -156,69 +178,85 @@ static AstNo* parserAnalisarSecaoVar(Parser* parser)
|
||||
{
|
||||
AstNo* secao = parserCriarNo(AST_SECAO_VAR, NULL);
|
||||
AstNo* ultimo = NULL;
|
||||
|
||||
if (!parserEsperar(parser, TOKEN_VAR)) {
|
||||
astLiberar(secao);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (parserVerificar(parser, TOKEN_IDENTIFICADOR)) {
|
||||
AstNo* decl = parserAnalisarDeclVar(parser);
|
||||
|
||||
if (decl == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ultimo == NULL) {
|
||||
secao->esquerda = decl;
|
||||
} else {
|
||||
ultimo->proximo = decl;
|
||||
}
|
||||
|
||||
ultimo = decl;
|
||||
}
|
||||
|
||||
return secao;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarExprBasica(Parser* parser)
|
||||
{
|
||||
AstNo* no;
|
||||
|
||||
switch (parser->atual.kind) {
|
||||
case TOKEN_ABRE_PARENTESES:
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_EXPRESSAO_PARENTESES, NULL);
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_FECHA_PARENTESES);
|
||||
return no;
|
||||
case TOKEN_NOT:
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_EXPRESSAO_UNARIA, "not");
|
||||
no->esquerda = parserAnalisarExprBasica(parser);
|
||||
return no;
|
||||
case TOKEN_INTEIRO_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
return no;
|
||||
case TOKEN_REAL_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
return no;
|
||||
case TOKEN_CHAR_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
return no;
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
no = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
return no;
|
||||
default:
|
||||
parserErro(parser);
|
||||
return NULL;
|
||||
case TOKEN_ABRE_PARENTESES:
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_EXPRESSAO_PARENTESES, NULL);
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_FECHA_PARENTESES);
|
||||
|
||||
return no;
|
||||
case TOKEN_NOT:
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_EXPRESSAO_UNARIA, "not");
|
||||
no->esquerda = parserAnalisarExprBasica(parser);
|
||||
|
||||
return no;
|
||||
case TOKEN_INTEIRO_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
|
||||
return no;
|
||||
case TOKEN_REAL_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
|
||||
return no;
|
||||
case TOKEN_CHAR_LITERAL:
|
||||
no = parserCriarNo(AST_EXPRESSAO_LITERAL, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
|
||||
return no;
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
no = parserCriarNo(AST_EXPRESSAO_IDENTIFICADOR, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
|
||||
return no;
|
||||
default:
|
||||
parserErro(parser);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarExpMul(Parser* parser)
|
||||
{
|
||||
AstNo* esquerda = parserAnalisarExprBasica(parser);
|
||||
|
||||
while (parser->atual.kind == TOKEN_MULTIPLICACAO || parser->atual.kind == TOKEN_DIVISAO || parser->atual.kind == TOKEN_DIV) {
|
||||
char operador[8];
|
||||
AstNo* direita;
|
||||
AstNo* novo;
|
||||
|
||||
strcpy(operador, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
direita = parserAnalisarExprBasica(parser);
|
||||
@@ -227,16 +265,19 @@ static AstNo* parserAnalisarExpMul(Parser* parser)
|
||||
novo->direita = direita;
|
||||
esquerda = novo;
|
||||
}
|
||||
|
||||
return esquerda;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarExpAd(Parser* parser)
|
||||
{
|
||||
AstNo* esquerda = parserAnalisarExpMul(parser);
|
||||
|
||||
while (parser->atual.kind == TOKEN_MAIS || parser->atual.kind == TOKEN_MENOS) {
|
||||
char operador[8];
|
||||
AstNo* direita;
|
||||
AstNo* novo;
|
||||
|
||||
strcpy(operador, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
direita = parserAnalisarExpMul(parser);
|
||||
@@ -245,16 +286,19 @@ static AstNo* parserAnalisarExpAd(Parser* parser)
|
||||
novo->direita = direita;
|
||||
esquerda = novo;
|
||||
}
|
||||
|
||||
return esquerda;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarExpRel(Parser* 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) {
|
||||
char operador[8];
|
||||
AstNo* direita;
|
||||
AstNo* novo;
|
||||
|
||||
strcpy(operador, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
direita = parserAnalisarExpAd(parser);
|
||||
@@ -263,16 +307,19 @@ static AstNo* parserAnalisarExpRel(Parser* parser)
|
||||
novo->direita = direita;
|
||||
esquerda = novo;
|
||||
}
|
||||
|
||||
return esquerda;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarExpOrAnd(Parser* parser)
|
||||
{
|
||||
AstNo* esquerda = parserAnalisarExpRel(parser);
|
||||
|
||||
while (parser->atual.kind == TOKEN_OR || parser->atual.kind == TOKEN_AND) {
|
||||
char operador[8];
|
||||
AstNo* direita;
|
||||
AstNo* novo;
|
||||
|
||||
strcpy(operador, parser->atual.lexema);
|
||||
parserAvancar(parser);
|
||||
direita = parserAnalisarExpRel(parser);
|
||||
@@ -281,6 +328,7 @@ static AstNo* parserAnalisarExpOrAnd(Parser* parser)
|
||||
novo->direita = direita;
|
||||
esquerda = novo;
|
||||
}
|
||||
|
||||
return esquerda;
|
||||
}
|
||||
|
||||
@@ -292,82 +340,98 @@ static AstNo* parserAnalisarExpressao(Parser* parser)
|
||||
static AstNo* parserAnalisarAtribuicao(Parser* parser)
|
||||
{
|
||||
AstNo* no = parserCriarNo(AST_ATRIBUICAO, parser->atual.lexema);
|
||||
|
||||
parserAvancar(parser);
|
||||
|
||||
if (!parserEsperar(parser, TOKEN_ATRIBUICAO)) {
|
||||
return no;
|
||||
}
|
||||
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarIteracao(Parser* parser)
|
||||
{
|
||||
AstNo* no;
|
||||
|
||||
if (parser->atual.kind == TOKEN_WHILE) {
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_ITERACAO, "while");
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_DO);
|
||||
no->direita = parserAnalisarComando(parser);
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_ITERACAO, "repeat");
|
||||
no->esquerda = parserAnalisarComando(parser);
|
||||
parserEsperar(parser, TOKEN_UNTIL);
|
||||
no->direita = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarDecisao(Parser* parser)
|
||||
{
|
||||
AstNo* no;
|
||||
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_DECISAO, NULL);
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_THEN);
|
||||
no->direita = parserAnalisarComando(parser);
|
||||
|
||||
if (parserVerificar(parser, TOKEN_ELSE)) {
|
||||
parserAvancar(parser);
|
||||
no->terceiro = parserAnalisarComando(parser);
|
||||
}
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarEscrita(Parser* parser)
|
||||
{
|
||||
AstNo* no;
|
||||
|
||||
parserAvancar(parser);
|
||||
no = parserCriarNo(AST_ESCRITA, NULL);
|
||||
parserEsperar(parser, TOKEN_ABRE_PARENTESES);
|
||||
no->esquerda = parserAnalisarExpressao(parser);
|
||||
parserEsperar(parser, TOKEN_FECHA_PARENTESES);
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
static AstNo* parserAnalisarComando(Parser* parser)
|
||||
{
|
||||
switch (parser->atual.kind) {
|
||||
case TOKEN_BEGIN: {
|
||||
AstNo* bloco = parserAnalisarBloco(parser);
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
return bloco;
|
||||
}
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
return parserAnalisarAtribuicao(parser);
|
||||
case TOKEN_WHILE:
|
||||
case TOKEN_REPEAT:
|
||||
return parserAnalisarIteracao(parser);
|
||||
case TOKEN_IF:
|
||||
return parserAnalisarDecisao(parser);
|
||||
case TOKEN_WRITE:
|
||||
return parserAnalisarEscrita(parser);
|
||||
default:
|
||||
parserErro(parser);
|
||||
return NULL;
|
||||
case TOKEN_BEGIN: {
|
||||
AstNo* bloco = parserAnalisarBloco(parser);
|
||||
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
|
||||
return bloco;
|
||||
}
|
||||
case TOKEN_IDENTIFICADOR:
|
||||
return parserAnalisarAtribuicao(parser);
|
||||
case TOKEN_WHILE:
|
||||
case TOKEN_REPEAT:
|
||||
return parserAnalisarIteracao(parser);
|
||||
case TOKEN_IF:
|
||||
return parserAnalisarDecisao(parser);
|
||||
case TOKEN_WRITE:
|
||||
return parserAnalisarEscrita(parser);
|
||||
default:
|
||||
parserErro(parser);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,20 +446,26 @@ static AstNo* parserAnalisarBloco(Parser* parser)
|
||||
astLiberar(lista);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (parserEmInicioDeComando(parser)) {
|
||||
AstNo* comando = parserAnalisarComando(parser);
|
||||
|
||||
if (comando == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ultimo == NULL) {
|
||||
lista->esquerda = comando;
|
||||
} else {
|
||||
ultimo->proximo = comando;
|
||||
}
|
||||
|
||||
ultimo = comando;
|
||||
}
|
||||
|
||||
parserEsperar(parser, TOKEN_END);
|
||||
bloco->esquerda = lista;
|
||||
|
||||
return bloco;
|
||||
}
|
||||
|
||||
@@ -407,6 +477,7 @@ AstNo* parserAnalisarPrograma(Parser* parser)
|
||||
astLiberar(programa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parserVerificar(parser, TOKEN_IDENTIFICADOR)) {
|
||||
free(programa->valor);
|
||||
programa->valor = (char*)malloc(strlen(parser->atual.lexema) + 1);
|
||||
@@ -415,14 +486,19 @@ AstNo* parserAnalisarPrograma(Parser* parser)
|
||||
} else {
|
||||
parserErro(parser);
|
||||
}
|
||||
|
||||
parserEsperar(parser, TOKEN_PONTO_VIRGULA);
|
||||
|
||||
if (parserVerificar(parser, TOKEN_VAR)) {
|
||||
programa->esquerda = parserAnalisarSecaoVar(parser);
|
||||
}
|
||||
|
||||
programa->direita = parserAnalisarBloco(parser);
|
||||
parserEsperar(parser, TOKEN_PONTO);
|
||||
|
||||
if (!parserVerificar(parser, TOKEN_EOF)) {
|
||||
parserErro(parser);
|
||||
}
|
||||
|
||||
return programa;
|
||||
}
|
||||
Reference in new issue
Block a user