UNPKG

@designliquido/delegua

Version:

Linguagem de programação simples e moderna usando português estruturado.

173 lines 8.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AvaliadorSintaticoPortugolIpt = void 0; const construtos_1 = require("../../construtos"); const declaracoes_1 = require("../../declaracoes"); const avaliador_sintatico_base_1 = require("../avaliador-sintatico-base"); const portugol_ipt_1 = __importDefault(require("../../tipos-de-simbolos/portugol-ipt")); class AvaliadorSintaticoPortugolIpt extends avaliador_sintatico_base_1.AvaliadorSintaticoBase { async primario() { switch (this.simbolos[this.atual].tipo) { case portugol_ipt_1.default.IDENTIFICADOR: const simboloIdentificador = this.avancarEDevolverAnterior(); return new construtos_1.Variavel(this.hashArquivo, simboloIdentificador); case portugol_ipt_1.default.INTEIRO: case portugol_ipt_1.default.TEXTO: const simboloAnterior = this.avancarEDevolverAnterior(); return new construtos_1.Literal(this.hashArquivo, Number(simboloAnterior.linha), simboloAnterior.literal); case portugol_ipt_1.default.PARENTESE_ESQUERDO: this.avancarEDevolverAnterior(); const expressao = await this.expressao(); this.consumir(portugol_ipt_1.default.PARENTESE_DIREITO, "Esperado ')' após a expressão."); return new construtos_1.Agrupamento(this.hashArquivo, Number(this.simbolos[this.atual].linha), expressao); } } /** * Aparentemente, o Portugol IPT não suporta chamadas de função. * @returns O retorno da chamada de `primario()`. */ async chamar() { return await this.primario(); } async atribuir() { const expressao = await this.ou(); if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.SETA_ATRIBUICAO)) { const setaAtribuicao = this.simbolos[this.atual - 1]; const valor = await this.atribuir(); if (expressao instanceof construtos_1.Variavel) { return new construtos_1.Atribuir(this.hashArquivo, expressao, valor); } if (expressao instanceof construtos_1.AcessoIndiceVariavel) { return new construtos_1.AtribuicaoPorIndice(this.hashArquivo, expressao.linha, expressao.entidadeChamada, expressao.indice, valor); } throw this.erro(setaAtribuicao, 'Tarefa de atribuição inválida'); } return expressao; } /** * A declaração escreva (ou escrever) do Portugol IPT é sempre na mesma linha. */ async declaracaoEscreva() { const simboloAtual = this.avancarEDevolverAnterior(); // const argumentos = this.logicaComumEscreva(); const argumentos = []; do { const valor = await this.expressao(); argumentos.push(new construtos_1.FormatacaoEscrita(this.hashArquivo, Number(simboloAtual.linha), valor)); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return new declaracoes_1.EscrevaMesmaLinha(Number(simboloAtual.linha), this.hashArquivo, argumentos); } blocoEscopo() { throw new Error('Método não implementado.'); } async declaracaoSe() { this.avancarEDevolverAnterior(); const condicao = await this.expressao(); this.consumir(portugol_ipt_1.default.ENTAO, "Esperado 'então' ou 'entao' após condição do se."); this.consumir(portugol_ipt_1.default.QUEBRA_LINHA, "Esperado quebra de linha após palavra reservada 'então' ou 'entao' em condição se."); const caminhoEntao = (await this.resolverDeclaracaoForaDeBloco()); while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.QUEBRA_LINHA)) ; let caminhoSenao = null; if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.SENAO)) { this.consumir(portugol_ipt_1.default.QUEBRA_LINHA, "Esperado quebra de linha após palavra reservada 'senão' ou 'senao' em instrução se."); caminhoSenao = await this.resolverDeclaracaoForaDeBloco(); } this.consumir(portugol_ipt_1.default.QUEBRA_LINHA, "Esperado quebra de linha após palavra reservada 'então' ou 'entao' em condição se."); this.consumir(portugol_ipt_1.default.FIMSE, "Esperado 'fimse' para finalização de uma instrução se."); return new declaracoes_1.Se(condicao, caminhoEntao, [], caminhoSenao); } declaracaoEnquanto() { throw new Error('Método não implementado.'); } declaracaoPara() { throw new Error('Método não implementado.'); } declaracaoEscolha() { throw new Error('Método não implementado.'); } declaracaoFazer() { throw new Error('Método não implementado.'); } async declaracaoInteiros() { const simboloInteiro = this.consumir(portugol_ipt_1.default.INTEIRO, ''); const inicializacoes = []; do { const identificador = this.consumir(portugol_ipt_1.default.IDENTIFICADOR, "Esperado identificador após palavra reservada 'inteiro'."); // Inicializações de variáveis podem ter valores definidos. let valorInicializacao = 0; if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.IGUAL)) { const literalInicializacao = this.consumir(portugol_ipt_1.default.INTEIRO, 'Esperado literal inteiro após símbolo de igual em declaração de variável.'); valorInicializacao = Number(literalInicializacao.literal); } inicializacoes.push(new declaracoes_1.Var(identificador, new construtos_1.Literal(this.hashArquivo, Number(simboloInteiro.linha), valorInicializacao, 'inteiro'))); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return Promise.resolve(inicializacoes); } /** * Análise de uma declaração `leia()`. No VisuAlg, `leia()` aceita 1..N argumentos. * @returns Uma declaração `Leia`. */ async expressaoLeia() { const simboloAtual = this.avancarEDevolverAnterior(); const argumentos = []; do { argumentos.push(await this.resolverDeclaracaoForaDeBloco()); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return new construtos_1.Leia(simboloAtual, argumentos); } corpoDaFuncao(tipo) { throw new Error('Método não implementado.'); } async resolverDeclaracaoForaDeBloco() { const simboloAtual = this.simbolos[this.atual]; switch (simboloAtual.tipo) { case portugol_ipt_1.default.ESCREVER: return await this.declaracaoEscreva(); case portugol_ipt_1.default.INTEIRO: return await this.declaracaoInteiros(); case portugol_ipt_1.default.LER: return new declaracoes_1.Expressao(await this.expressaoLeia()); case portugol_ipt_1.default.QUEBRA_LINHA: this.avancarEDevolverAnterior(); return null; case portugol_ipt_1.default.SE: return await this.declaracaoSe(); default: return new declaracoes_1.Expressao(await this.expressao()); } } validarSegmentoInicio() { this.consumir(portugol_ipt_1.default.INICIO, `Esperada expressão 'inicio' para marcar escopo do algoritmo.`); } async analisar(retornoLexador, hashArquivo) { this.erros = []; this.atual = 0; this.blocos = 0; this.hashArquivo = hashArquivo || 0; this.simbolos = (retornoLexador === null || retornoLexador === void 0 ? void 0 : retornoLexador.simbolos) || []; while (this.verificarTipoSimboloAtual(portugol_ipt_1.default.QUEBRA_LINHA)) { this.avancarEDevolverAnterior(); } let declaracoes = []; this.validarSegmentoInicio(); while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== portugol_ipt_1.default.FIM) { const resolucaoDeclaracao = await this.resolverDeclaracaoForaDeBloco(); if (Array.isArray(resolucaoDeclaracao)) { declaracoes = declaracoes.concat(resolucaoDeclaracao); } else { declaracoes.push(resolucaoDeclaracao); } } return { declaracoes: declaracoes.filter((d) => d), erros: this.erros, }; } } exports.AvaliadorSintaticoPortugolIpt = AvaliadorSintaticoPortugolIpt; //# sourceMappingURL=avaliador-sintatico-portugol-ipt.js.map