UNPKG

@designliquido/delegua

Version:

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

314 lines 11.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LexadorCalango = void 0; const simbolo_1 = require("../simbolo"); const calango_1 = __importDefault(require("./palavras-reservadas/calango")); const calango_2 = __importDefault(require("../../tipos-de-simbolos/calango")); class LexadorCalango { eDigito(caractere) { return caractere >= '0' && caractere <= '9'; } eAlfabeto(caractere) { const acentuacoes = [ 'á', 'Á', 'ã', 'Ã', 'â', 'Â', 'à', 'À', 'é', 'É', 'ê', 'Ê', 'í', 'Í', 'ó', 'Ó', 'õ', 'Õ', 'ô', 'Ô', 'ú', 'Ú', 'ç', 'Ç', '_', ]; return ((caractere >= 'a' && caractere <= 'z') || (caractere >= 'A' && caractere <= 'Z') || acentuacoes.includes(caractere)); } eAlfabetoOuDigito(caractere) { return this.eDigito(caractere) || this.eAlfabeto(caractere); } eFinalDoCodigo() { if (this.linha > this.codigo.length - 1) return true; return (this.linha == this.codigo.length - 1 && this.codigo[this.codigo.length - 1].length <= this.atual); } eUltimaLinha() { return this.linha >= this.codigo.length - 1; } eFinalDaLinha() { return this.atual >= this.codigo[this.linha].length; } avancar() { this.atual += 1; if (this.eFinalDaLinha() && !this.eUltimaLinha()) { this.linha++; this.atual = 0; // this.logicaEmLinhaIniciada = false; } } adicionarSimbolo(tipo, literal) { const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual); const comprimento = Math.max(texto.length, 1); const colunaInicio = this.inicioSimbolo + 1; const colunaFim = this.inicioSimbolo + comprimento; this.simbolos.push(new simbolo_1.Simbolo(tipo, texto, literal, this.linha, -1, colunaInicio, colunaFim)); } simboloAtual() { if (this.eFinalDaLinha()) return '\0'; if (this.linha > this.codigo.length - 1) return '\0'; return this.codigo[this.linha].charAt(this.atual); } proximoSimbolo() { if (this.atual + 1 >= this.codigo[this.linha].length) return '\0'; return this.codigo[this.linha].charAt(this.atual + 1); } simboloAnterior() { return this.codigo[this.linha].charAt(this.atual - 1); } analisarTexto(delimitador) { const linhaPrimeiroCaracter = this.linha; while (this.simboloAtual() !== delimitador && !this.eFinalDoCodigo()) { this.avancar(); } if (this.eFinalDoCodigo()) { this.erros.push({ linha: this.linha + 1, caractere: this.simboloAnterior(), mensagem: 'Texto não finalizado.', }); return; } const textoCompleto = this.codigo[this.linha].substring(this.inicioSimbolo + 1, this.atual); this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.TEXTO, textoCompleto, textoCompleto, linhaPrimeiroCaracter + 1, this.hashArquivo)); } analisarCaracter() { const linhaPrimeiroCaracter = this.linha; // Restringe leitura à linha atual (como analisarNumero), evitando // que avancar() mude this.linha e corrompa o cálculo do substring. while (this.simboloAtual() !== "'" && this.linha === linhaPrimeiroCaracter && !this.eFinalDoCodigo()) { this.avancar(); } if (this.linha !== linhaPrimeiroCaracter || this.eFinalDoCodigo()) { this.erros.push({ linha: linhaPrimeiroCaracter + 1, caractere: this.simboloAnterior(), mensagem: 'Caractere não finalizado.', }); return; } const valorCaracter = this.codigo[linhaPrimeiroCaracter].substring(this.inicioSimbolo + 1, this.atual); this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.LITERAL_CARACTER, valorCaracter, valorCaracter, linhaPrimeiroCaracter + 1, this.hashArquivo)); } analisarNumero() { const linhaPrimeiroDigito = this.linha; while (this.eDigito(this.simboloAtual()) && this.linha === linhaPrimeiroDigito) { this.avancar(); } if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) { this.avancar(); while (this.eDigito(this.simboloAtual())) { this.avancar(); } } let numeroCompleto; if (linhaPrimeiroDigito < this.linha) { const linhaNumero = this.codigo[linhaPrimeiroDigito]; numeroCompleto = linhaNumero.substring(this.inicioSimbolo, linhaNumero.length); } else { numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual); } this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.NUMERO, numeroCompleto, parseFloat(numeroCompleto), linhaPrimeiroDigito + 1, this.hashArquivo)); } identificarPalavraChave() { const linhaPrimeiroCaracter = this.linha; while (this.eAlfabetoOuDigito(this.simboloAtual()) && this.linha === linhaPrimeiroCaracter) { this.avancar(); } let textoPalavraChave; if (linhaPrimeiroCaracter < this.linha) { const linhaPalavraChave = this.codigo[linhaPrimeiroCaracter]; textoPalavraChave = linhaPalavraChave.substring(this.inicioSimbolo, linhaPalavraChave.length); } else { textoPalavraChave = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual); } const tipo = textoPalavraChave in calango_1.default ? calango_1.default[textoPalavraChave] : calango_2.default.IDENTIFICADOR; this.simbolos.push(new simbolo_1.Simbolo(tipo, textoPalavraChave, null, linhaPrimeiroCaracter + 1, this.hashArquivo)); } analisarToken() { const caractere = this.simboloAtual(); switch (caractere) { case ' ': case '\t': case '\0': this.avancar(); break; case '\r': case '\n': this.adicionarSimbolo(calango_2.default.QUEBRA_LINHA); // Quebra de linha adicionada para identificar o início do código this.avancar(); break; case ';': // Calango exige o ponto e vírgula para indicar final do código this.adicionarSimbolo(calango_2.default.PONTO_E_VIRGULA); this.avancar(); break; case '"': this.avancar(); this.analisarTexto('"'); this.avancar(); break; case "'": this.avancar(); this.analisarCaracter(); this.avancar(); break; case ':': this.adicionarSimbolo(calango_2.default.DOIS_PONTOS); this.avancar(); break; case '[': this.adicionarSimbolo(calango_2.default.COLCHETE_ESQUERDO); this.avancar(); break; case ']': this.adicionarSimbolo(calango_2.default.COLCHETE_DIREITO); this.avancar(); break; case '(': this.adicionarSimbolo(calango_2.default.PARENTESE_ESQUERDO); this.avancar(); break; case ')': this.adicionarSimbolo(calango_2.default.PARENTESE_DIREITO); this.avancar(); break; case ',': this.adicionarSimbolo(calango_2.default.VIRGULA); this.avancar(); break; case '+': this.adicionarSimbolo(calango_2.default.ADICAO); this.avancar(); break; case '-': this.adicionarSimbolo(calango_2.default.SUBTRACAO); this.avancar(); break; case '*': this.adicionarSimbolo(calango_2.default.MULTIPLICACAO); this.avancar(); break; case '/': if (this.proximoSimbolo() === '/') { // Comentário de linha: consumir até ao fim da linha sem emitir símbolo. // Guardamos o número da linha para parar quando avancar() mudar para a próxima. const linhaComentario = this.linha; while (this.linha === linhaComentario && !this.eFinalDoCodigo()) { this.avancar(); } } else { this.adicionarSimbolo(calango_2.default.DIVISAO); this.avancar(); } break; case '=': this.adicionarSimbolo(calango_2.default.IGUAL_ATRIBUICAO); this.avancar(); break; case '>': this.avancar(); if (this.simboloAtual() === '=') { this.adicionarSimbolo(calango_2.default.MAIOR_IGUAL, '>='); this.avancar(); } else { this.adicionarSimbolo(calango_2.default.MAIOR); } break; case '<': this.avancar(); if (this.simboloAtual() === '=') { this.adicionarSimbolo(calango_2.default.MENOR_IGUAL, '<='); this.avancar(); } else if (this.simboloAtual() === '>') { this.adicionarSimbolo(calango_2.default.DIFERENTE, '<>'); this.avancar(); } else { this.adicionarSimbolo(calango_2.default.MENOR); } break; case '%': this.adicionarSimbolo(calango_2.default.MODULO); this.avancar(); break; case '^': this.adicionarSimbolo(calango_2.default.EXPONENCIACAO); this.avancar(); break; default: if (this.eDigito(caractere)) this.analisarNumero(); else if (this.eAlfabeto(caractere)) this.identificarPalavraChave(); else { this.erros.push({ linha: this.linha + 1, caractere: caractere, mensagem: 'Caractere inesperado.', }); this.avancar(); } } } mapear(codigo, hashArquivo) { this.simbolos = []; this.erros = []; this.inicioSimbolo = 0; this.atual = 0; this.linha = 0; this.codigo = codigo || ['']; this.hashArquivo = hashArquivo; while (!this.eFinalDoCodigo()) { this.inicioSimbolo = this.atual; this.analisarToken(); } return { simbolos: this.simbolos, erros: this.erros, }; } } exports.LexadorCalango = LexadorCalango; //# sourceMappingURL=lexador-calango.js.map