@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
214 lines • 10.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MicroAvaliadorSintatico = void 0;
const construtos_1 = require("../construtos");
const micro_avaliador_sintatico_base_1 = require("./micro-avaliador-sintatico-base");
const delegua_1 = __importDefault(require("../tipos-de-simbolos/microgramaticas/delegua"));
/**
* O MicroAvaliadorSintatico funciona apenas dentro de interpolações de texto.
*/
class MicroAvaliadorSintatico extends micro_avaliador_sintatico_base_1.MicroAvaliadorSintaticoBase {
primario() {
const simboloAtual = this.simbolos[this.atual];
let valores = [];
switch (simboloAtual.tipo) {
case delegua_1.default.CHAVE_ESQUERDA:
this.avancarEDevolverAnterior();
const chaves = [];
valores = [];
if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.CHAVE_DIREITA)) {
return new construtos_1.Dicionario(-1, Number(this.linha), [], []);
}
while (!this.verificarSeSimboloAtualEIgualA(delegua_1.default.CHAVE_DIREITA)) {
const chave = this.declaracao();
this.consumir(delegua_1.default.DOIS_PONTOS, "Esperado ':' entre chave e valor.");
const valor = this.declaracao();
chaves.push(chave);
valores.push(valor);
if (this.simbolos[this.atual].tipo !== delegua_1.default.CHAVE_DIREITA) {
this.consumir(delegua_1.default.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
}
}
return new construtos_1.Dicionario(-1, Number(this.linha), chaves, valores);
case delegua_1.default.COLCHETE_ESQUERDO:
this.avancarEDevolverAnterior();
valores = [];
if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.COLCHETE_DIREITO)) {
return new construtos_1.Vetor(-1, Number(this.linha), []);
}
while (!this.verificarSeSimboloAtualEIgualA(delegua_1.default.COLCHETE_DIREITO)) {
const valor = this.declaracao();
valores.push(valor);
if (this.simbolos[this.atual].tipo !== delegua_1.default.COLCHETE_DIREITO) {
this.consumir(delegua_1.default.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
}
}
return new construtos_1.Vetor(-1, Number(this.linha), valores);
case delegua_1.default.FALSO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), false);
case delegua_1.default.IDENTIFICADOR:
const simboloIdentificador = this.avancarEDevolverAnterior();
// Se o próximo símbolo é um incremento ou um decremento,
// aqui deve retornar um unário correspondente.
// Caso contrário, apenas retornar um construto de variável.
if (this.simbolos[this.atual] &&
[delegua_1.default.INCREMENTAR, delegua_1.default.DECREMENTAR].includes(this.simbolos[this.atual].tipo)) {
const simboloIncrementoDecremento = this.avancarEDevolverAnterior();
return new construtos_1.Unario(-1, simboloIncrementoDecremento, new construtos_1.Variavel(-1, simboloIdentificador), 'DEPOIS');
}
return new construtos_1.Variavel(-1, simboloIdentificador);
case delegua_1.default.NULO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), null);
case delegua_1.default.NUMERO:
case delegua_1.default.TEXTO:
const simboloNumeroTexto = this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), simboloNumeroTexto.literal);
case delegua_1.default.PARENTESE_ESQUERDO:
this.avancarEDevolverAnterior();
const expressao = this.ou();
this.consumir(delegua_1.default.PARENTESE_DIREITO, "Esperado ')' após a expressão.");
return new construtos_1.Agrupamento(-1, Number(this.linha), expressao);
case delegua_1.default.VERDADEIRO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), true);
}
throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
}
finalizarChamada(entidadeChamada) {
const argumentos = [];
if (!this.verificarTipoSimboloAtual(delegua_1.default.PARENTESE_DIREITO)) {
do {
if (argumentos.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 argumentos.');
}
argumentos.push(this.ou());
} while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.VIRGULA));
}
this.consumir(delegua_1.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos.");
return new construtos_1.Chamada(-1, entidadeChamada, argumentos);
}
chamar() {
let expressao = this.primario();
while (true) {
if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.PARENTESE_ESQUERDO)) {
expressao = this.finalizarChamada(expressao);
}
else if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.PONTO)) {
const nome = this.consumir(delegua_1.default.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new construtos_1.AcessoMetodoOuPropriedade(-1, expressao, nome);
}
else if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.COLCHETE_ESQUERDO)) {
const indice = this.ou();
const simboloFechamento = this.consumir(delegua_1.default.COLCHETE_DIREITO, "Esperado ']' após escrita do indice.");
expressao = new construtos_1.AcessoIndiceVariavel(-1, expressao, indice, simboloFechamento);
}
else {
break;
}
}
return expressao;
}
unario() {
if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.NEGACAO, delegua_1.default.SUBTRACAO, delegua_1.default.BIT_NOT, delegua_1.default.INCREMENTAR, delegua_1.default.DECREMENTAR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.unario();
return new construtos_1.Unario(-1, operador, direito, 'ANTES');
}
return this.chamar();
}
exponenciacao() {
let expressao = this.unario();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.EXPONENCIACAO)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.exponenciacao();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitShift() {
let expressao = this.adicaoOuSubtracao();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.MENOR_MENOR, delegua_1.default.MAIOR_MAIOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.adicaoOuSubtracao();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitE() {
let expressao = this.bitShift();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.BIT_AND)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitShift();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitOu() {
let expressao = this.bitE();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.BIT_OR, delegua_1.default.BIT_XOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitE();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
comparar() {
let expressao = this.bitOu();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.MAIOR, delegua_1.default.MAIOR_IGUAL, delegua_1.default.MENOR, delegua_1.default.MENOR_IGUAL)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitOu();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
em() {
let expressao = this.comparacaoIgualdade();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.EM)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.comparacaoIgualdade();
expressao = new construtos_1.Logico(-1, expressao, operador, direito);
}
return expressao;
}
e() {
let expressao = this.em();
while (this.verificarSeSimboloAtualEIgualA(delegua_1.default.E)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.em();
expressao = new construtos_1.Logico(-1, expressao, operador, direito);
}
return expressao;
}
elvis() {
let expressao = this.ou();
if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.ELVIS)) {
const direito = this.ou();
return new construtos_1.Elvis(-1, expressao, direito);
}
return expressao;
}
declaracao() {
return this.elvis();
}
analisar(retornoLexador, linha) {
this.erros = [];
this.atual = 0;
this.linha = linha;
this.simbolos = (retornoLexador === null || retornoLexador === void 0 ? void 0 : retornoLexador.simbolos) || [];
const declaracoes = [];
while (this.atual < this.simbolos.length) {
declaracoes.push(this.declaracao());
}
return {
declaracoes: declaracoes,
erros: this.erros,
};
}
}
exports.MicroAvaliadorSintatico = MicroAvaliadorSintatico;
//# sourceMappingURL=micro-avaliador-sintatico.js.map