Skip to content

Commit

Permalink
Resolve pequenos bugs no avaliador sintático de Portugol Studio (#598)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelrvg authored Jan 26, 2024
1 parent d8f8117 commit 82c26e5
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ import { ErroAvaliadorSintatico } from '../erro-avaliador-sintatico';
* Há dois grupos de estruturas de alto nível: Construtos e Declarações.
*/
export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
private declaracoes: Declaracao[] = []

declaracaoEscreva(): Escreva {
throw new Error('Método não implementado.');
}

private validarEscopoPrograma(declaracoes: Declaracao[]): void {
private validarEscopoPrograma(): void {
this.consumir(tiposDeSimbolos.PROGRAMA, "Esperada expressão 'programa' para inicializar programa.");

this.consumir(
Expand All @@ -55,14 +57,19 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
);

while (!this.estaNoFinal()) {
declaracoes.push(this.resolverDeclaracaoForaDeBloco());
const declaracaoOuVetor: any = this.resolverDeclaracaoForaDeBloco();
if (Array.isArray(declaracaoOuVetor)) {
this.declaracoes = this.declaracoes.concat(declaracaoOuVetor);
} else {
this.declaracoes.push(declaracaoOuVetor);
}
}

if (this.simbolos[this.atual - 1].tipo !== tiposDeSimbolos.CHAVE_DIREITA) {
throw this.erro(this.simbolos[this.atual - 1], 'Esperado chave direita final para término do programa.');
}

const encontrarDeclaracaoInicio = declaracoes.filter(
const encontrarDeclaracaoInicio = this.declaracoes.filter(
(d) => d instanceof FuncaoDeclaracao && d.simbolo.lexema === 'inicio'
);

Expand All @@ -72,7 +79,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {

// A última declaração do programa deve ser uma chamada a inicio()
const declaracaoInicio = encontrarDeclaracaoInicio[0];
declaracoes.push(
this.declaracoes.push(
new Expressao(new Chamada(declaracaoInicio.hashArquivo, (declaracaoInicio as any).funcao, null, []))
);
}
Expand Down Expand Up @@ -376,16 +383,16 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
);

// Inicializações de variáveis podem ter valores definidos.
let valorInicializacao = 0;
let valorInicializacao = '';
if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
const literalInicializacao = this.consumir(
tiposDeSimbolos.CADEIA,
'Esperado literal de cadeia de caracteres após símbolo de igual em declaração de variável.'
);
valorInicializacao = Number(literalInicializacao.literal);
valorInicializacao = literalInicializacao.literal;
}

inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloCadeia.linha), 0)));
inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloCadeia.linha), valorInicializacao)));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

return inicializacoes;
Expand All @@ -402,17 +409,17 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
);

// Inicializações de variáveis podem ter valores definidos.
let valorInicializacao = 0;
let valorInicializacao = '';
if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
const literalInicializacao = this.consumir(
tiposDeSimbolos.CARACTER,
'Esperado literal de caracter após símbolo de igual em declaração de variável.'
);
valorInicializacao = Number(literalInicializacao.literal);
valorInicializacao = literalInicializacao.literal;
}

inicializacoes.push(
new Var(identificador, new Literal(this.hashArquivo, Number(simboloCaracter.linha), 0))
new Var(identificador, new Literal(this.hashArquivo, Number(simboloCaracter.linha), valorInicializacao))
);
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

Expand Down Expand Up @@ -538,7 +545,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
);

// Inicializações de variáveis podem ter valores definidos.
let valorInicializacao: any = false;
let valorInicializacao = false;
if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
if (![tiposDeSimbolos.VERDADEIRO, tiposDeSimbolos.FALSO].includes(this.simbolos[this.atual].tipo)) {
throw this.erro(
Expand All @@ -547,7 +554,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
);
}
const literalInicializacao = this.avancarEDevolverAnterior();
valorInicializacao = Number(literalInicializacao.literal);
valorInicializacao = literalInicializacao.lexema.toLowerCase() === 'verdadeiro' ? true : false;
}

inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloLogico.linha), valorInicializacao)));
Expand Down Expand Up @@ -613,7 +620,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
valorInicializacao = Number(literalInicializacao.literal);
}

inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloReal.linha), 0)));
inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloReal.linha), valorInicializacao)));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

return inicializacoes;
Expand Down Expand Up @@ -642,6 +649,8 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
this.avancarEDevolverAnterior();
}

this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VAZIO);

const nomeFuncao: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, `Esperado nome ${tipo}.`);
return new FuncaoDeclaracao(nomeFuncao, this.corpoDaFuncao(tipo));
}
Expand Down Expand Up @@ -695,12 +704,12 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {

this.hashArquivo = hashArquivo || 0;
this.simbolos = retornoLexador?.simbolos || [];
this.declaracoes = []

const declaracoes: Declaracao[] = [];
this.validarEscopoPrograma(declaracoes);
this.validarEscopoPrograma();

return {
declaracoes: declaracoes.filter((d) => d),
declaracoes: this.declaracoes.filter((d) => d),
erros: this.erros,
} as RetornoAvaliadorSintatico<Declaracao>;
}
Expand Down
53 changes: 53 additions & 0 deletions testes/portugol-studio/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,59 @@ describe('Interpretador (Portugol Studio)', () => {

expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Funcao Vazio', async () => {
const retornoLexador = lexador.mapear([
'programa',
'{',
' ',
' funcao inicio()',
' {',
' imprime_linha()',
' }',
'',
' funcao vazio imprime_linha()',
' {',
' escreva("\n---------------------")',
' }',
'}',
], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);

expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Estruturas de dados', async () => {
const retornoLexador = lexador.mapear([
'programa',
'{ ',
//variável global do tipo inteiro
'inteiro variavel',

'funcao inicio()',
'{ ',
'inteiro outra_variavel',

'real altura = 1.79',

'cadeia frase = "Isso é uma variável do tipo cadeia"',

'caracter inicial = \'P\'',

'logico exemplo = verdadeiro',

'escreva(altura)',
'}',
'}',
], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);

expect(retornoInterpretador.erros).toHaveLength(0);
});
});
});
});

0 comments on commit 82c26e5

Please sign in to comment.