Skip to content

Commit

Permalink
Intuindo tipo em construto binário.
Browse files Browse the repository at this point in the history
  • Loading branch information
leonelsanchesdasilva committed Dec 16, 2024
1 parent 08c5d1f commit 4b287b3
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 20 deletions.
16 changes: 8 additions & 8 deletions fontes/avaliador-sintatico/avaliador-sintatico.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ export class AvaliadorSintatico
) {
const operador = this.simbolos[this.atual - 1];
const direito = this.exponenciacao();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -439,7 +439,7 @@ export class AvaliadorSintatico
) {
const operador = this.simbolos[this.atual - 1];
const direito = this.multiplicar();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -451,7 +451,7 @@ export class AvaliadorSintatico
while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.MENOR_MENOR, tiposDeSimbolos.MAIOR_MAIOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.adicaoOuSubtracao();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -463,7 +463,7 @@ export class AvaliadorSintatico
while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.BIT_AND)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitShift();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -475,7 +475,7 @@ export class AvaliadorSintatico
while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.BIT_OR, tiposDeSimbolos.BIT_XOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitE();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -493,8 +493,8 @@ export class AvaliadorSintatico
)
) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitOu(); // Única diferença entre esta implementação e base.
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
const direito = this.bitOu();
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand All @@ -506,7 +506,7 @@ export class AvaliadorSintatico
while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.DIFERENTE, tiposDeSimbolos.IGUAL_IGUAL)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.comparar();
expressao = new Binario(this.hashArquivo, expressao, operador, direito);
expressao = new Binario<TipoDeSimboloDelegua>(this.hashArquivo, expressao, operador, direito);
}

return expressao;
Expand Down
22 changes: 21 additions & 1 deletion fontes/construtos/binario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,34 @@ export class Binario<TTipoSimbolo extends string = string> implements Construto
esquerda: Construto;
operador: SimboloInterface<TTipoSimbolo>;
direita: Construto;
tipo: string = 'qualquer';

constructor(hashArquivo: number, esquerda: any, operador: SimboloInterface<TTipoSimbolo>, direita: any) {
constructor(hashArquivo: number, esquerda: Construto, operador: SimboloInterface<TTipoSimbolo>, direita: Construto) {
this.linha = esquerda.linha;
this.hashArquivo = hashArquivo;

this.esquerda = esquerda;
this.operador = operador;
this.direita = direita;
this.tipo = this.deduzirTipo();
}

protected deduzirTipo(): string {
if (['logico', 'lógico'].includes(this.esquerda.tipo) || ['logico', 'lógico'].includes(this.direita.tipo)) {
return 'lógico';
}

if (this.esquerda.tipo === 'texto' || this.direita.tipo === 'texto') {
return 'texto';
}

if (this.esquerda.tipo === 'inteiro' && this.direita.tipo === 'inteiro') {
return 'inteiro';
}

if (['numero', 'número'].includes(this.esquerda.tipo) || ['numero', 'número'].includes(this.direita.tipo)) {
return 'número';
}
}

async aceitar(visitante: VisitanteComumInterface): Promise<any> {
Expand Down
1 change: 1 addition & 0 deletions fontes/construtos/construto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export interface Construto {
linha: number;
hashArquivo: number;
valor?: any;
tipo?: string;
aceitar(visitante: VisitanteComumInterface): Promise<any>;
}
94 changes: 83 additions & 11 deletions testes/avaliador-sintatico.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Lexador } from '../fontes/lexador';
import { AvaliadorSintatico } from '../fontes/avaliador-sintatico';
import { Bloco, Classe, Expressao, FuncaoDeclaracao, Retorna, TendoComo } from '../fontes/declaracoes';
import { Bloco, Classe, Escreva, Expressao, FuncaoDeclaracao, Leia, Retorna, TendoComo, Var } from '../fontes/declaracoes';
import { Binario, Chamada, FuncaoConstruto, Literal, Variavel } from '../fontes/construtos';

describe('Avaliador sintático', () => {
Expand Down Expand Up @@ -48,20 +48,89 @@ describe('Avaliador sintático', () => {
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
});

it('Leia sem parâmetro', () => {
const retornoLexador = lexador.mapear(['var nome = leia()'], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
describe('Declarações com construto binário', () => {
it('Números literais, soma', () => {
const retornoLexador = lexador.mapear(['2 + 3'], -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
const declaracao = retornoAvaliadorSintatico.declaracoes[0];
expect(declaracao.constructor.name).toBe('Expressao');
const declaracaoTipada = declaracao as Expressao;
expect(declaracaoTipada.expressao.constructor.name).toBe('Binario');
const binario = declaracaoTipada.expressao as Binario;
expect(binario.tipo).toBe('número');
expect(binario.esquerda.constructor.name).toBe('Literal');
expect(binario.direita.constructor.name).toBe('Literal');
const literalEsquerdo = binario.esquerda as Literal;
const literalDireito = binario.direita as Literal;
expect(literalEsquerdo.tipo).toBe('número');
expect(literalEsquerdo.valor).toBe(2);
expect(literalDireito.tipo).toBe('número');
expect(literalDireito.valor).toBe(3);
});

it('Literal + variável, multiplicacao', () => {
const retornoLexador = lexador.mapear(
[
'var a: número = 50',
'escreva(a * 3)'
], -1);

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
const declaracao = retornoAvaliadorSintatico.declaracoes[1];
expect(declaracao.constructor.name).toBe('Escreva');
const declaracaoTipada = declaracao as Escreva;
expect(declaracaoTipada.argumentos).toHaveLength(1);
const argumento = declaracaoTipada.argumentos[0];
expect(argumento.constructor.name).toBe('Binario');
const binario = argumento as Binario;
expect(binario.tipo).toBe('número');
expect(binario.esquerda.constructor.name).toBe('Variavel');
expect(binario.direita.constructor.name).toBe('Literal');
const literalEsquerdo = binario.esquerda as Variavel;
const literalDireito = binario.direita as Literal;
expect(literalEsquerdo.tipo).toBe('número');
expect(literalDireito.tipo).toBe('número');
expect(literalDireito.valor).toBe(3);
});
});

it('Leia com parâmetro', () => {
const retornoLexador = lexador.mapear(["var nome = leia('Digite seu nome:')"], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
describe('Leia', () => {
it('Leia sem parâmetro', () => {
const retornoLexador = lexador.mapear(['var nome = leia()'], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
const declaracao = retornoAvaliadorSintatico.declaracoes[0];
expect(declaracao.constructor.name).toBe('Var');
const declaracaoTipada = declaracao as Var;
expect(declaracaoTipada.inicializador.constructor.name).toBe('Leia');
const declaracaoLeia = declaracaoTipada.inicializador as Leia;
expect(declaracaoLeia.argumentos).toHaveLength(0);
});

it('Leia com parâmetro', () => {
const retornoLexador = lexador.mapear(["var nome = leia('Digite seu nome:')"], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
const declaracao = retornoAvaliadorSintatico.declaracoes[0];
expect(declaracao.constructor.name).toBe('Var');
const declaracaoTipada = declaracao as Var;
expect(declaracaoTipada.inicializador.constructor.name).toBe('Leia');
const declaracaoLeia = declaracaoTipada.inicializador as Leia;
expect(declaracaoLeia.argumentos.length).toBeGreaterThan(0);
});
});

describe('Para cada', () => {
Expand Down Expand Up @@ -91,6 +160,9 @@ describe('Avaliador sintático', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
const declaracao = retornoAvaliadorSintatico.declaracoes[0];
expect(declaracao.constructor.name).toBe('ParaCada');
});
});

Expand Down

0 comments on commit 4b287b3

Please sign in to comment.