diff --git a/.vscode/launch.json b/.vscode/launch.json index 40666a51..3b9cc29f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,19 +4,6 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "name": "Portugol-studio > Testes Interpretador", - "type": "node", - "request": "launch", - "runtimeArgs": [ - "--inspect-brk", - "${workspaceRoot}/node_modules/jest/bin/jest.js", - "portugol-studio/interpretador.test.ts", - "--runInBand" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, { "name": "Potigol > Testes Interpretador", "type": "node", @@ -30,19 +17,6 @@ "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" }, - { - "name": "Visualg > Testes Interpretador", - "type": "node", - "request": "launch", - "runtimeArgs": [ - "--inspect-brk", - "${workspaceRoot}/node_modules/jest/bin/jest.js", - "visualg/interpretador.test.ts", - "--runInBand" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, { "name": "BIRL > Testes Interpretador", "type": "node", @@ -818,23 +792,6 @@ "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" }, - { - "name": "Testes unitários - Portugol Studio", - "type": "node", - "request": "launch", - "runtimeArgs": [ - "--inspect-brk", - "${workspaceRoot}/node_modules/jest/bin/jest.js", - "portugol-studio/avaliador-sintatico", - "--runInBand" - ], - "skipFiles": [ - "/**", - "node_modules/**" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, { "name": "Testes unitários - Tradutor Delégua para Javascript", "type": "node", @@ -1486,29 +1443,6 @@ "ts-node/register/transpile-only" ] }, - { - "type": "node", - "request": "launch", - "name": "Portugol Studio > Olá Mundo", - "skipFiles": [ - "/**", - "node_modules/**" - ], - "cwd": "${workspaceRoot}", - "console": "integratedTerminal", - "args": [ - "${workspaceFolder}${pathSeparator}execucao.ts", - "--dialeto", - "portugol-studio", - "./exemplos/dialetos/portugol-studio/ola-mundo.por" - ], - "runtimeExecutable": "node", - "runtimeArgs": [ - "--nolazy", - "-r", - "ts-node/register/transpile-only" - ] - }, { "name": "Tradutor > Delégua para AssemblyScript", "type": "node", diff --git a/exemplos/dialetos/portugol-studio/ola-mundo.por b/exemplos/dialetos/portugol-studio/ola-mundo.por deleted file mode 100644 index 4ac0f119..00000000 --- a/exemplos/dialetos/portugol-studio/ola-mundo.por +++ /dev/null @@ -1,7 +0,0 @@ -programa -{ - funcao inicio () - { - escreva("Olá Mundo!") - } -} diff --git a/exemplos/dialetos/visualg/divisao-inteira.alg b/exemplos/dialetos/visualg/divisao-inteira.alg deleted file mode 100644 index 421fbc4f..00000000 --- a/exemplos/dialetos/visualg/divisao-inteira.alg +++ /dev/null @@ -1,10 +0,0 @@ -algoritmo "divisao-inteira" -var x: real - y: inteiro -inicio - x <- 10 - y <- 3 - - escreva ((x / y):3:1) - escreval (x \ y) -fimalgoritmo \ No newline at end of file diff --git a/exemplos/dialetos/visualg/exemplos-escreva.alg b/exemplos/dialetos/visualg/exemplos-escreva.alg deleted file mode 100644 index 3baf6243..00000000 --- a/exemplos/dialetos/visualg/exemplos-escreva.alg +++ /dev/null @@ -1,16 +0,0 @@ -algoritmo "exemplo" -var x: real - y: inteiro - a: caractere - l: logico -inicio - x <- 2.5 - y <- 6 - a <- "teste" - l <- VERDADEIRO - escreval ("x", x:4:1, y+3:4) // Escreve: x 2.5 9 - escreval (a, "ok") // Escreve: testeok (e depois pula linha) - escreval (a, " ok") // Escreve: teste ok (e depois pula linha) - escreval (a + " ok") // Escreve: teste ok (e depois pula linha) - escreva (l) // Escreve: VERDADEIRO -fimalgoritmo \ No newline at end of file diff --git a/exemplos/dialetos/visualg/exercicio1.alg b/exemplos/dialetos/visualg/exercicio1.alg deleted file mode 100644 index 4a9d2161..00000000 --- a/exemplos/dialetos/visualg/exercicio1.alg +++ /dev/null @@ -1,25 +0,0 @@ -algoritmo "semnome" -// Função : -// Autor : -// Data : 29/11/2013 -// Seção de Declarações -var -n1,n2,n3:real -inicio -// Seção de Comandos -escreval ("Digite dois valores para a soma,subtração,multiplicação e divisão: ") -leia (n1,n2) -n3<-n1+n2 -escreval () -escreval ("A soma de ",n1," mais ",n2," é igual a: ", n3) -n3<-n1-n2 -escreval () -escreval ("A subtração de ",n1," menos ",n2," é igual a: ", n3) -n3<-n1*n2 -escreval () -escreval ("A multiplicação de ",n1," multiplicação ",n2," é igual a: ", n3) -n3<-n1/n2 -escreval () -escreval ("A divisão de ",n1," e ",n2," é igual a: ", n3) -escreval () -fimalgoritmo diff --git a/exemplos/dialetos/visualg/exercicio2.alg b/exemplos/dialetos/visualg/exercicio2.alg deleted file mode 100644 index c9f9f9a1..00000000 --- a/exemplos/dialetos/visualg/exercicio2.alg +++ /dev/null @@ -1,15 +0,0 @@ -algoritmo "semnome" -// Função : -// Autor : -// Data : 29/11/2013 -// Seção de Declarações -var n1,n2,n3:real -inicio -// Seção de Comandos -escreva ("Digite a distancia em km veiculo do : ") -leia (n1) -escreva ("Combustivel gasto: ") -leia (n2) -n3<-(n1/n2) -Escreval ("A média do veiculo é: ",n3," em km") -fimalgoritmo diff --git a/exemplos/dialetos/visualg/multiplicar.alg b/exemplos/dialetos/visualg/multiplicar.alg deleted file mode 100644 index 306d6831..00000000 --- a/exemplos/dialetos/visualg/multiplicar.alg +++ /dev/null @@ -1,21 +0,0 @@ -algoritmo "semnome" -// Função : -// Autor : -// Data : 28/11/2013 -// Seção de Declarações -var tab: inteiro - opt: inteiro - num:inteiro -inicio -// Seção de Comandos -escreval ("Digite o valor para multiplicar: ") -leia (tab) -num<-1 -opt<-0 - repita - opt<-opt+1 - num<-tab*opt - escreval(num) - ate opt>=10 - -fimalgoritmo diff --git a/exemplos/dialetos/visualg/ola-mundo.alg b/exemplos/dialetos/visualg/ola-mundo.alg deleted file mode 100644 index d53b88ca..00000000 --- a/exemplos/dialetos/visualg/ola-mundo.alg +++ /dev/null @@ -1,4 +0,0 @@ -algoritmo "ola-mundo" -inicio -escreva("Ola mundo") -fimalgoritmo diff --git a/exemplos/dialetos/visualg/times.alg b/exemplos/dialetos/visualg/times.alg deleted file mode 100644 index 29f7df16..00000000 --- a/exemplos/dialetos/visualg/times.alg +++ /dev/null @@ -1,14 +0,0 @@ -algoritmo "Times" -var time: caractere -inicio -escreva ("Entre com o nome de um time de futebol: ") -leia (time) -escolha time - caso "Flamengo", "Fluminense", "Vasco", "Botafogo" - escreval ("É um time carioca.") - caso "São Paulo", "Palmeiras", "Santos", "Corínthians" - escreval ("É um time paulista.") - outrocaso - escreval ("É de outro estado.") -fimescolha -fimalgoritmo diff --git a/exemplos/dialetos/visualg/um-a-10.alg b/exemplos/dialetos/visualg/um-a-10.alg deleted file mode 100644 index da7d0fb3..00000000 --- a/exemplos/dialetos/visualg/um-a-10.alg +++ /dev/null @@ -1,7 +0,0 @@ -algoritmo "Numeros de 1 a 10" -var j: inteiro -inicio -para j de 1 ate 10 faca - escreva (j) -fimpara -fimalgoritmo diff --git a/exemplos/dialetos/visualg/um-a-dez-interrompa.alg b/exemplos/dialetos/visualg/um-a-dez-interrompa.alg deleted file mode 100644 index aaba927e..00000000 --- a/exemplos/dialetos/visualg/um-a-dez-interrompa.alg +++ /dev/null @@ -1,12 +0,0 @@ -algoritmo "Números de 1 a 10 (com interrompa)" -var x: inteiro -inicio -x <- 0 -repita - x <- x + 1 - escreva (x) - se x = 10 entao - interrompa - fimse -ate verdadeiro -fimalgoritmo \ No newline at end of file diff --git a/exemplos/dialetos/visualg/variaveis.alg b/exemplos/dialetos/visualg/variaveis.alg deleted file mode 100644 index 3324d0ef..00000000 --- a/exemplos/dialetos/visualg/variaveis.alg +++ /dev/null @@ -1,16 +0,0 @@ -Algoritmo "exemplo-variaveis" -var a: inteiro - Valor1, Valor2: real - vet: vetor [1..10] de real - matriz: vetor [0..4,8..10] de inteiro - nome_do_aluno: caractere - sinalizador: logico -Inicio - a <- 3 - Valor1 <- 1.5 - Valor2 <- Valor1 + a - vet[1] <- vet[1] + (a * 3) - matriz[3,9] <- Int(a/4) - 5 - nome_do_aluno <- "José da Silva" - sinalizador <- FALSO -Fimalgoritmo \ No newline at end of file diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts deleted file mode 100644 index 73c0bf62..00000000 --- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts +++ /dev/null @@ -1,853 +0,0 @@ -import { - AcessoIndiceVariavel, - Agrupamento, - AtribuicaoPorIndice, - Atribuir, - Binario, - Chamada, - Construto, - FuncaoConstruto, - Literal, - Unario, - Variavel, - Vetor, -} from '../../construtos'; -import { - Escreva, - Declaracao, - Se, - Enquanto, - Para, - Escolha, - Fazer, - FuncaoDeclaracao, - Expressao, - Leia, - Var, - Bloco, - EscrevaMesmaLinha, - Retorna, - Const, -} from '../../declaracoes'; -import { RetornoLexador, RetornoAvaliadorSintatico } from '../../interfaces/retornos'; -import { AvaliadorSintaticoBase } from '../avaliador-sintatico-base'; - -import { ParametroInterface, SimboloInterface } from '../../interfaces'; - -import tiposDeSimbolos from '../../tipos-de-simbolos/portugol-studio'; -import { RetornoDeclaracao } from '../retornos'; -import { ErroAvaliadorSintatico } from '../erro-avaliador-sintatico'; -import { TipoDadosElementar } from '../../tipo-dados-elementar'; - -/** - * O avaliador sintático (_Parser_) é responsável por transformar os símbolos do Lexador em estruturas de alto nível. - * Essas estruturas de alto nível são as partes que executam lógica de programação de fato. - * 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(): void { - this.consumir(tiposDeSimbolos.PROGRAMA, "Esperada expressão 'programa' para inicializar programa."); - - this.consumir( - tiposDeSimbolos.CHAVE_ESQUERDA, - "Esperada chave esquerda após expressão 'programa' para inicializar programa." - ); - - while (!this.estaNoFinal()) { - 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 = this.declaracoes.filter( - (d) => d instanceof FuncaoDeclaracao && d.simbolo.lexema === 'inicio' - ); - - if (encontrarDeclaracaoInicio.length <= 0) { - throw this.erro(this.simbolos[0], "Função 'inicio()' para iniciar o programa não foi definida."); - } - - // A última declaração do programa deve ser uma chamada a inicio() - const declaracaoInicio = encontrarDeclaracaoInicio[0]; - this.declaracoes.push( - new Expressao(new Chamada(declaracaoInicio.hashArquivo, (declaracaoInicio as any).funcao, null, [])) - ); - } - - comparacaoIgualdade(): Construto { - let expressao = this.comparar(); - - while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.DIFERENTE, tiposDeSimbolos.IGUAL_IGUAL)) { - const simboloAnterior = this.simbolos[this.atual - 1]; - const direito = this.comparar(); - expressao = new Binario(this.hashArquivo, expressao, simboloAnterior, direito); - } - - return expressao; - } - - primario(): Construto { - const simboloAtual = this.simbolos[this.atual]; - switch (simboloAtual.tipo) { - case tiposDeSimbolos.IDENTIFICADOR: - const simboloIdentificador: SimboloInterface = 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] && - [tiposDeSimbolos.INCREMENTAR, tiposDeSimbolos.DECREMENTAR].includes(this.simbolos[this.atual].tipo) - ) { - const simboloIncrementoDecremento: SimboloInterface = this.avancarEDevolverAnterior(); - return new Unario( - this.hashArquivo, - simboloIncrementoDecremento, - new Variavel(this.hashArquivo, simboloIdentificador), - 'DEPOIS' - ); - } - - return new Variavel(this.hashArquivo, simboloIdentificador); - - case tiposDeSimbolos.PARENTESE_ESQUERDO: - this.avancarEDevolverAnterior(); - const expressao = this.expressao(); - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após a expressão."); - - return new Agrupamento(this.hashArquivo, Number(simboloAtual.linha), expressao); - - case tiposDeSimbolos.CADEIA: - case tiposDeSimbolos.CARACTER: - case tiposDeSimbolos.INTEIRO: - case tiposDeSimbolos.REAL: - const simboloVariavel: SimboloInterface = this.avancarEDevolverAnterior(); - return new Literal(this.hashArquivo, Number(simboloVariavel.linha), simboloVariavel.literal); - } - } - - chamar(): Construto { - let expressao = this.primario(); - - while (true) { - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)) { - expressao = this.finalizarChamada(expressao); - } else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) { - const indices = []; - do { - indices.push(this.expressao()); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - const indice = indices[0]; - const simboloFechamento = this.consumir( - tiposDeSimbolos.COLCHETE_DIREITO, - "Esperado ']' após escrita do indice." - ); - expressao = new AcessoIndiceVariavel(this.hashArquivo, expressao, indice, simboloFechamento); - } else { - break; - } - } - - return expressao; - } - - atribuir(): Construto { - const expressao = this.ou(); - - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - const setaAtribuicao = this.simbolos[this.atual - 1]; - const valor = this.atribuir(); - - if (expressao instanceof Variavel) { - const simbolo = expressao.simbolo; - return new Atribuir(this.hashArquivo, simbolo, valor); - } else if (expressao instanceof AcessoIndiceVariavel) { - return new AtribuicaoPorIndice( - this.hashArquivo, - expressao.linha, - expressao.entidadeChamada, - expressao.indice, - valor - ); - } - - this.erro(setaAtribuicao, 'Tarefa de atribuição inválida'); - } - - return expressao; - } - - declaracaoEscrevaMesmaLinha(): EscrevaMesmaLinha { - const simboloAtual = this.avancarEDevolverAnterior(); - - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' antes dos valores em escreva."); - - const argumentos: Construto[] = []; - - do { - argumentos.push(this.expressao()); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após os valores em escreva."); - - return new EscrevaMesmaLinha(Number(simboloAtual.linha), simboloAtual.hashArquivo, argumentos); - } - - blocoEscopo(): Declaracao[] { - this.consumir(tiposDeSimbolos.CHAVE_ESQUERDA, "Esperado '}' antes do bloco."); - - let declaracoes: Array = []; - - while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.CHAVE_DIREITA) && !this.estaNoFinal()) { - const declaracaoOuVetor: any = this.resolverDeclaracaoForaDeBloco(); - if (Array.isArray(declaracaoOuVetor)) { - declaracoes = declaracoes.concat(declaracaoOuVetor); - } else { - declaracoes.push(declaracaoOuVetor); - } - } - - this.consumir(tiposDeSimbolos.CHAVE_DIREITA, "Esperado '}' após o bloco."); - return declaracoes; - } - - declaracaoSe(): Se { - this.avancarEDevolverAnterior(); - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'se'."); - const condicao = this.expressao(); - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após condição do se."); - - const caminhoEntao = this.resolverDeclaracaoForaDeBloco(); - - let caminhoSenao = null; - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.SENAO)) { - caminhoSenao = this.resolverDeclaracaoForaDeBloco(); - } - - return new Se(condicao, caminhoEntao, [], caminhoSenao); - } - - declaracaoEnquanto(): Enquanto { - try { - this.avancarEDevolverAnterior(); - this.blocos += 1; - - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'enquanto'."); - const condicao = this.expressao(); - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após condição."); - const corpo = this.resolverDeclaracaoForaDeBloco(); - - return new Enquanto(condicao, corpo); - } finally { - this.blocos -= 1; - } - } - - declaracaoEscolha(): Escolha { - try { - this.avancarEDevolverAnterior(); - this.blocos += 1; - - const condicao = this.expressao(); - this.consumir(tiposDeSimbolos.CHAVE_ESQUERDA, "Esperado '{' antes do escopo do 'escolha'."); - - const caminhos = []; - let caminhoPadrao = null; - while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_DIREITA) && !this.estaNoFinal()) { - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CASO)) { - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CONTRARIO)) { - if (caminhoPadrao !== null) { - const excecao = new ErroAvaliadorSintatico( - this.simbolos[this.atual], - "Você só pode ter um 'contrario' em cada declaração de 'escolha'." - ); - this.erros.push(excecao); - throw excecao; - } - - this.consumir(tiposDeSimbolos.DOIS_PONTOS, "Esperado ':' após declaração do 'contrario'."); - - const declaracoes = []; - do { - declaracoes.push(this.resolverDeclaracaoForaDeBloco()); - - this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARE); - } while ( - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CASO) && - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CONTRARIO) && - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CHAVE_DIREITA) - ); - - caminhoPadrao = { - declaracoes, - }; - break; - } - - const caminhoCondicoes = [this.expressao()]; - this.consumir(tiposDeSimbolos.DOIS_PONTOS, "Esperado ':' após o 'caso'."); - - while (this.verificarTipoSimboloAtual(tiposDeSimbolos.CASO)) { - this.consumir(tiposDeSimbolos.CASO, null); - caminhoCondicoes.push(this.expressao()); - this.consumir(tiposDeSimbolos.DOIS_PONTOS, "Esperado ':' após declaração do 'caso'."); - } - - let declaracoes = []; - do { - const retornoDeclaracao = this.resolverDeclaracaoForaDeBloco(); - if (Array.isArray(retornoDeclaracao)) { - declaracoes = declaracoes.concat(retornoDeclaracao); - } else { - declaracoes.push(retornoDeclaracao as Declaracao); - } - this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARE); - } while ( - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CASO) && - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CONTRARIO) && - !this.verificarTipoSimboloAtual(tiposDeSimbolos.CHAVE_DIREITA) - ); - - caminhos.push({ - condicoes: caminhoCondicoes, - declaracoes, - }); - } - } - - return new Escolha(condicao, caminhos, caminhoPadrao); - } finally { - this.blocos -= 1; - } - } - - /** - * No Portugol Studio, a palavra reservada é `faca`, sem acento. - */ - declaracaoFazer(): Fazer { - const simboloFaca: SimboloInterface = this.avancarEDevolverAnterior(); - try { - this.blocos += 1; - - const caminhoFazer = this.resolverDeclaracaoForaDeBloco(); - - this.consumir(tiposDeSimbolos.ENQUANTO, "Esperado declaração do 'enquanto' após o escopo do 'fazer'."); - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após declaração 'enquanto'."); - - const condicaoEnquanto = this.expressao(); - - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após declaração do 'enquanto'."); - - return new Fazer(simboloFaca.hashArquivo, Number(simboloFaca.linha), caminhoFazer, condicaoEnquanto); - } finally { - this.blocos -= 1; - } - } - - protected logicaComumParametros(): ParametroInterface[] { - const parametros: ParametroInterface[] = []; - - do { - if (parametros.length >= 255) { - this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 parâmetros'); - } - - const parametro: Partial = { - abrangencia: 'padrao', - }; - - if ( - !this.verificarSeSimboloAtualEIgualA( - tiposDeSimbolos.CADEIA, - tiposDeSimbolos.REAL, - tiposDeSimbolos.INTEIRO - ) - ) { - throw this.erro( - this.simbolos[this.atual], - 'Esperado tipo de parâmetro válido para declaração de função.' - ); - } - - parametro.nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome do parâmetro.'); - - // Em Portugol Studio, um parâmetro múltiplo é terminado por abre e fecha colchetes. - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) { - this.consumir( - tiposDeSimbolos.COLCHETE_DIREITO, - 'Esperado colchete direito após colchete esquerdo ao definir parâmetro múltiplo em função.' - ); - parametro.abrangencia = 'multiplo'; - } - - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - parametro.valorPadrao = this.primario(); - } - - parametros.push(parametro as ParametroInterface); - - if (parametro.abrangencia === 'multiplo') break; - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - return parametros; - } - - corpoDaFuncao(tipo: string): FuncaoConstruto { - // O parêntese esquerdo é considerado o símbolo inicial para - // fins de pragma. - const parenteseEsquerdo = this.consumir( - tiposDeSimbolos.PARENTESE_ESQUERDO, - `Esperado '(' após o nome ${tipo}.` - ); - - let parametros = []; - if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) { - parametros = this.logicaComumParametros(); - } - - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após parâmetros."); - - const corpo = this.blocoEscopo(); - - return new FuncaoConstruto(this.hashArquivo, Number(parenteseEsquerdo.linha), parametros, corpo); - } - - /** - * Declaração de apenas uma variável. - * Neste caso, o símbolo que determina o tipo da variável já foi consumido, - * e o retorno conta com apenas uma variável retornada. - */ - declaracaoDeVariavel(): Var { - switch (this.simboloAnterior().tipo) { - case tiposDeSimbolos.INTEIRO: - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'inteiro'." - ); - this.consumir(tiposDeSimbolos.IGUAL, 'Esperado símbolo igual para inicialização de variável.'); - const literalInicializacao = this.consumir( - tiposDeSimbolos.INTEIRO, - 'Esperado literal inteiro após símbolo de igual em declaração de variável.' - ); - const valorInicializacao = Number(literalInicializacao.literal); - return new Var( - identificador, - new Literal(this.hashArquivo, Number(literalInicializacao.linha), valorInicializacao) - ); - } - } - - declaracaoCadeiasCaracteres(): Var[] { - const simboloCadeia = this.consumir(tiposDeSimbolos.CADEIA, ''); - - const inicializacoes = []; - do { - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'cadeia'." - ); - - // Inicializações de variáveis podem ter valores definidos. - 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 = literalInicializacao.literal; - } - - inicializacoes.push( - new Var(identificador, new Literal(this.hashArquivo, Number(simboloCadeia.linha), valorInicializacao)) - ); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - return inicializacoes; - } - - declaracaoCaracteres(): Var[] { - const simboloCaracter = this.consumir(tiposDeSimbolos.CARACTER, ''); - - const inicializacoes = []; - do { - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'caracter'." - ); - - // Inicializações de variáveis podem ter valores definidos. - 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 = literalInicializacao.literal; - } - - inicializacoes.push( - new Var(identificador, new Literal(this.hashArquivo, Number(simboloCaracter.linha), valorInicializacao)) - ); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - return inicializacoes; - } - - declaracaoExpressao(simboloAnterior?: SimboloInterface): Expressao { - const expressao = this.expressao(); - // Ponto-e-vírgula é opcional aqui. - this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_E_VIRGULA); - if (!expressao) { - throw new ErroAvaliadorSintatico(simboloAnterior, 'Esperado expressão.'); - } - - return new Expressao(expressao); - } - - protected declaracaoVetorInteiros( - simboloInteiro: SimboloInterface, - identificador: SimboloInterface, - posicoes: number - ) { - let valorInicializacao: Vetor = new Vetor(this.hashArquivo, Number(simboloInteiro.linha), []); - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - this.consumir( - tiposDeSimbolos.CHAVE_ESQUERDA, - 'Esperado chave esquerda após sinal de igual em lado direito da atribuição de vetor.' - ); - - const valores = []; - do { - valores.push(this.primario()); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - this.consumir( - tiposDeSimbolos.CHAVE_DIREITA, - 'Esperado chave direita após valores de vetor em lado direito da atribuição de vetor.' - ); - - if (posicoes !== valores.length) { - throw this.erro( - simboloInteiro, - `Esperado ${posicoes} números, mas foram fornecidos ${valores.length} valores do lado direito da atribuição.` - ); - } - - valorInicializacao.valores = valores; - } - - return new Var(identificador, valorInicializacao); - } - - protected declaracaoTrivialInteiro(simboloInteiro: SimboloInterface, identificador: SimboloInterface) { - // Inicializações de variáveis podem ter valores definidos. - let valorInicializacao: Construto = new Literal(this.hashArquivo, Number(simboloInteiro.linha), 0); - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - valorInicializacao = this.expressao(); - } - - return new Var(identificador, valorInicializacao); - } - - declaracaoInteiros(): Var[] { - const simboloInteiro = this.consumir(tiposDeSimbolos.INTEIRO, ''); - - const inicializacoes = []; - do { - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'inteiro'." - ); - - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) { - // TODO - const numeroPosicoes = this.consumir( - tiposDeSimbolos.INTEIRO, - 'Esperado número inteiro para definir quantas posições terá o vetor.' - ); - - this.consumir( - tiposDeSimbolos.COLCHETE_DIREITO, - 'Esperado fechamento de identificação de número de posições de uma declaração de vetor.' - ); - - inicializacoes.push( - this.declaracaoVetorInteiros(simboloInteiro, identificador, Number(numeroPosicoes.literal)) - ); - } else { - inicializacoes.push(this.declaracaoTrivialInteiro(simboloInteiro, identificador)); - } - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - return inicializacoes; - } - - /** - * Análise de uma declaração `leia()`. No VisuAlg, `leia()` aceita 1..N argumentos. - * @returns Uma declaração `Leia`. - */ - declaracaoLeia(): Leia { - const simboloLeia = this.avancarEDevolverAnterior(); - - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' antes do argumento em instrução `leia`."); - - const argumentos = []; - do { - argumentos.push(this.resolverDeclaracaoForaDeBloco()); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após o argumento em instrução `leia`."); - - return new Leia(simboloLeia, argumentos); - } - - declaracaoLogicos(): Var[] { - const simboloLogico = this.consumir(tiposDeSimbolos.LOGICO, ''); - - const inicializacoes = []; - do { - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'logico'." - ); - - // Inicializações de variáveis podem ter valores definidos. - let valorInicializacao = false; - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - if (![tiposDeSimbolos.VERDADEIRO, tiposDeSimbolos.FALSO].includes(this.simbolos[this.atual].tipo)) { - throw this.erro( - this.simbolos[this.atual], - 'Esperado literal verdadeiro ou falso após símbolo de igual em declaração de variável.' - ); - } - const literalInicializacao = this.avancarEDevolverAnterior(); - valorInicializacao = literalInicializacao.lexema.toLowerCase() === 'verdadeiro' ? true : false; - } - - inicializacoes.push( - new Var(identificador, new Literal(this.hashArquivo, Number(simboloLogico.linha), valorInicializacao)) - ); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - return inicializacoes; - } - - declaracaoRetorne(): Retorna { - this.avancarEDevolverAnterior(); - const simboloChave = this.simbolos[this.atual]; - let valor = null; - - if ( - [ - tiposDeSimbolos.CADEIA, - tiposDeSimbolos.CARACTER, - tiposDeSimbolos.FALSO, - tiposDeSimbolos.IDENTIFICADOR, - tiposDeSimbolos.INTEIRO, - tiposDeSimbolos.NEGACAO, - tiposDeSimbolos.REAL, - tiposDeSimbolos.VERDADEIRO, - ].includes(this.simbolos[this.atual].tipo) - ) { - valor = this.expressao(); - } - - return new Retorna(simboloChave, valor); - } - - declaracaoPara(): Para { - try { - const simboloPara: SimboloInterface = this.avancarEDevolverAnterior(); - this.blocos += 1; - - this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'para'."); - - let inicializador: Var | Expressao; - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_E_VIRGULA)) { - inicializador = null; - } else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INTEIRO)) { - inicializador = this.declaracaoDeVariavel(); - } else { - inicializador = this.declaracaoExpressao(); - } - - let condicao = null; - if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PONTO_E_VIRGULA)) { - condicao = this.expressao(); - } - - let incrementar = null; - if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) { - incrementar = this.expressao(); - this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INCREMENTAR, tiposDeSimbolos.DECREMENTAR); - } - - this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após cláusulas"); - - const corpo = this.resolverDeclaracaoForaDeBloco(); - - return new Para(this.hashArquivo, Number(simboloPara.linha), inicializador, condicao, incrementar, corpo); - } finally { - this.blocos -= 1; - } - } - - declaracaoReais(): Var[] { - const simboloReal = this.consumir(tiposDeSimbolos.REAL, ''); - - const inicializacoes = []; - do { - const identificador = this.consumir( - tiposDeSimbolos.IDENTIFICADOR, - "Esperado identificador após palavra reservada 'real'." - ); - - // Inicializações de variáveis podem ter valores definidos. - let valorInicializacao = 0; - if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) { - const literalInicializacao = this.consumir( - tiposDeSimbolos.REAL, - 'Esperado literal real após símbolo de igual em declaração de variável.' - ); - valorInicializacao = Number(literalInicializacao.literal); - } - - inicializacoes.push( - new Var(identificador, new Literal(this.hashArquivo, Number(simboloReal.linha), valorInicializacao)) - ); - } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)); - - return inicializacoes; - } - - expressao(): Construto { - // if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.LEIA)) return this.declaracaoLeia(); - return this.atribuir(); - } - - funcao(tipo: string): FuncaoDeclaracao { - const simboloFuncao: SimboloInterface = this.avancarEDevolverAnterior(); - - // No Portugol Studio, se temos um símbolo de tipo após `função`, - // teremos um retorno no corpo da função. - if ( - [ - tiposDeSimbolos.REAL, - tiposDeSimbolos.INTEIRO, - tiposDeSimbolos.CADEIA, - tiposDeSimbolos.CARACTER, - tiposDeSimbolos.LOGICO, - ].includes(this.simbolos[this.atual].tipo) - ) { - // Por enquanto apenas consumimos o símbolo sem ações adicionais. - this.avancarEDevolverAnterior(); - } - - this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VAZIO); - - const nomeFuncao: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, `Esperado nome ${tipo}.`); - return new FuncaoDeclaracao(nomeFuncao, this.corpoDaFuncao(tipo)); - } - - declaracaoDeConstantes(): any { - let identificador: SimboloInterface; - let tipo: SimboloInterface; - if ( - [ - tiposDeSimbolos.REAL, - tiposDeSimbolos.INTEIRO, - tiposDeSimbolos.CADEIA, - tiposDeSimbolos.CARACTER, - tiposDeSimbolos.LOGICO, - ].includes(this.simbolos[this.atual].tipo) - ) { - tipo = this.avancarEDevolverAnterior(); - } - - identificador = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome da constante.'); - - this.consumir(tiposDeSimbolos.IGUAL, "Esperado '=' após identificador em instrução 'constante'."); - - const inicializador = this.expressao(); - - return new Const(identificador, inicializador, tipo.lexema as TipoDadosElementar); - } - - resolverDeclaracaoForaDeBloco(): Declaracao | Declaracao[] | Construto | Construto[] | any { - const simboloAtual = this.simbolos[this.atual]; - switch (simboloAtual.tipo) { - case tiposDeSimbolos.CADEIA: - return this.declaracaoCadeiasCaracteres(); - case tiposDeSimbolos.CARACTER: - return this.declaracaoCaracteres(); - case tiposDeSimbolos.CHAVE_ESQUERDA: - const simboloInicioBloco: SimboloInterface = this.simbolos[this.atual]; - return new Bloco(simboloInicioBloco.hashArquivo, Number(simboloInicioBloco.linha), this.blocoEscopo()); - case tiposDeSimbolos.CONSTANTE: - this.avancarEDevolverAnterior(); - return this.declaracaoDeConstantes(); - case tiposDeSimbolos.ENQUANTO: - return this.declaracaoEnquanto(); - case tiposDeSimbolos.ESCOLHA: - return this.declaracaoEscolha(); - case tiposDeSimbolos.ESCREVA: - return this.declaracaoEscrevaMesmaLinha(); - case tiposDeSimbolos.FACA: - return this.declaracaoFazer(); - case tiposDeSimbolos.FUNCAO: - return this.funcao('funcao'); - case tiposDeSimbolos.INTEIRO: - return this.declaracaoInteiros(); - case tiposDeSimbolos.LEIA: - return this.declaracaoLeia(); - case tiposDeSimbolos.LOGICO: - return this.declaracaoLogicos(); - case tiposDeSimbolos.PARA: - return this.declaracaoPara(); - case tiposDeSimbolos.PROGRAMA: - case tiposDeSimbolos.CHAVE_DIREITA: - this.avancarEDevolverAnterior(); - return null; - case tiposDeSimbolos.REAL: - return this.declaracaoReais(); - case tiposDeSimbolos.RETORNE: - return this.declaracaoRetorne(); - case tiposDeSimbolos.SE: - return this.declaracaoSe(); - default: - return this.declaracaoExpressao(simboloAtual); - } - } - - analisar( - retornoLexador: RetornoLexador, - hashArquivo: number - ): RetornoAvaliadorSintatico { - this.erros = []; - this.atual = 0; - this.blocos = 0; - - this.hashArquivo = hashArquivo || 0; - this.simbolos = retornoLexador?.simbolos || []; - this.declaracoes = []; - - this.validarEscopoPrograma(); - - return { - declaracoes: this.declaracoes.filter((d) => d), - erros: this.erros, - } as RetornoAvaliadorSintatico; - } -} diff --git a/fontes/avaliador-sintatico/dialetos/index.ts b/fontes/avaliador-sintatico/dialetos/index.ts index ec92e194..6c6e47e6 100644 --- a/fontes/avaliador-sintatico/dialetos/index.ts +++ b/fontes/avaliador-sintatico/dialetos/index.ts @@ -3,6 +3,5 @@ export * from './avaliador-sintatico-egua-classico'; export * from './avaliador-sintatico-pitugues'; export * from './avaliador-sintatico-mapler'; export * from './avaliador-sintatico-portugol-ipt'; -export * from './avaliador-sintatico-portugol-studio'; export * from './potigol'; diff --git a/fontes/formatadores/formatador-portugol-studio.ts b/fontes/formatadores/formatador-portugol-studio.ts deleted file mode 100644 index 042acfd6..00000000 --- a/fontes/formatadores/formatador-portugol-studio.ts +++ /dev/null @@ -1,412 +0,0 @@ -import { - AcessoIndiceVariavel, - AcessoMetodoOuPropriedade, - Agrupamento, - AtribuicaoPorIndice, - Atribuir, - Binario, - Chamada, - Construto, - DefinirValor, - Dicionario, - ExpressaoRegular, - FimPara, - FormatacaoEscrita, - FuncaoConstruto, - Isto, - Literal, - Logico, - Super, - TipoDe, - Tupla, - Unario, - Variavel, - Vetor, -} from '../construtos'; -import { - Classe, - Const, - ConstMultiplo, - Expressao, - FuncaoDeclaracao, - Enquanto, - Escolha, - Escreva, - Fazer, - Importar, - Para, - ParaCada, - Se, - Tente, - Var, - VarMultiplo, - Bloco, - Continua, - EscrevaMesmaLinha, - Leia, - LeiaMultiplo, - Retorna, - Sustar, - Declaracao, - Falhar, - Aleatorio, - CabecalhoPrograma, - TendoComo, -} from '../declaracoes'; -import { InicioAlgoritmo } from '../declaracoes/inicio-algoritmo'; -import { VisitanteComumInterface } from '../interfaces'; -import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from '../quebras'; - -export class FormatadorPortugolStudio implements VisitanteComumInterface { - indentacaoAtual: number; - quebraLinha: string; - tamanhoIndentacao: number; - codigoFormatado: string; - devePularLinha: boolean; - deveIndentar: boolean; - - constructor(quebraLinha: string, tamanhoIndentacao: number = 4) { - this.quebraLinha = quebraLinha; - this.tamanhoIndentacao = tamanhoIndentacao; - - this.indentacaoAtual = 0; - this.codigoFormatado = ''; - this.devePularLinha = true; - this.deveIndentar = true; - } - - visitarDeclaracaoTendoComo(declaracao: TendoComo): void | Promise { - throw new Error('Método não implementado.'); - } - - visitarDeclaracaoInicioAlgoritmo(declaracao: InicioAlgoritmo): Promise { - throw new Error('Método não implementado.'); - } - - visitarDeclaracaoCabecalhoPrograma(declaracao: CabecalhoPrograma): Promise { - throw new Error('Método não implementado.'); - } - - visitarExpressaoTupla(expressao: Tupla): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoClasse(declaracao: Classe) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoConst(declaracao: Const): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoConstMultiplo(declaracao: ConstMultiplo): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoDeAtribuicao(expressao: Atribuir) { - throw new Error('Método não implementado'); - } - - visitarDeclaracaoDeExpressao(declaracao: Expressao) { - // throw new Error("Método não implementado"); - } - - visitarDeclaracaoAleatorio(declaracao: Aleatorio): Promise { - throw new Error('Método não implementado.'); - } - - visitarDeclaracaoDefinicaoFuncao(declaracao: FuncaoDeclaracao) { - this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}funcao ${declaracao.simbolo.lexema}()${ - this.quebraLinha - }`; - - this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}{${this.quebraLinha}`; - this.visitarExpressaoFuncaoConstruto(declaracao.funcao); - this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`; - } - - visitarDeclaracaoEnquanto(declaracao: Enquanto) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoEscolha(declaracao: Escolha) { - throw new Error('Método não implementado'); - } - - visitarDeclaracaoEscreva(declaracao: Escreva) { - this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}escreva(`; - for (let argumento of declaracao.argumentos) { - this.formatarDeclaracaoOuConstruto(argumento); - } - - this.codigoFormatado += `)${this.quebraLinha}`; - } - - visitarDeclaracaoFazer(declaracao: Fazer) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoImportar(declaracao: Importar) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoPara(declaracao: Para): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoParaCada(declaracao: ParaCada): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoSe(declaracao: Se) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoTente(declaracao: Tente) { - throw new Error('Método não implementado'); - } - visitarDeclaracaoVar(declaracao: Var): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoVarMultiplo(declaracao: VarMultiplo): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoAcessoIndiceVariavel(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoAcessoElementoMatriz(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoAcessoMetodo(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoAgrupamento(expressao: any): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoAtribuicaoPorIndice(expressao: any): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoAtribuicaoPorIndicesMatriz(expressao: any): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoBinaria(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoBloco(declaracao: Bloco): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoContinua(declaracao?: Continua): ContinuarQuebra { - throw new Error('Método não implementado'); - } - visitarExpressaoDeChamada(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoDefinirValor(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoDeleguaFuncao(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoDeVariavel(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoDicionario(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { - throw new Error('Método não implementado'); - } - visitarDeclaracaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha) { - throw new Error('Método não implementado'); - } - visitarExpressaoFalhar(expressao: any): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoFimPara(declaracao: FimPara) { - throw new Error('Método não implementado'); - } - visitarExpressaoFormatacaoEscrita(declaracao: FormatacaoEscrita) { - throw new Error('Método não implementado'); - } - visitarExpressaoFuncaoConstruto(expressao: FuncaoConstruto) { - this.indentacaoAtual += this.tamanhoIndentacao; - - for (let declaracaoCorpo of expressao.corpo) { - this.formatarDeclaracaoOuConstruto(declaracaoCorpo); - } - - this.indentacaoAtual -= this.tamanhoIndentacao; - } - visitarExpressaoIsto(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoLeia(expressao: Leia): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoLeiaMultiplo(expressao: LeiaMultiplo): Promise { - throw new Error('Método não implementado'); - } - - visitarExpressaoLiteral(expressao: Literal): any { - if (typeof expressao.valor === 'string') { - this.codigoFormatado += `"${expressao.valor}"`; - return; - } - - this.codigoFormatado += `${expressao.valor}`; - } - - visitarExpressaoLogica(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoRetornar(declaracao: Retorna): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoSuper(expressao: Super) { - throw new Error('Método não implementado'); - } - visitarExpressaoSustar(declaracao?: Sustar): SustarQuebra { - throw new Error('Método não implementado'); - } - visitarExpressaoTipoDe(expressao: TipoDe): Promise { - throw new Error('Método não implementado'); - } - visitarExpressaoUnaria(expressao: any) { - throw new Error('Método não implementado'); - } - visitarExpressaoVetor(expressao: any) { - throw new Error('Método não implementado'); - } - - formatarDeclaracaoOuConstruto(declaracaoOuConstruto: Declaracao | Construto): void { - switch (declaracaoOuConstruto.constructor.name) { - case 'AcessoIndiceVariavel': - this.visitarExpressaoAcessoIndiceVariavel(declaracaoOuConstruto as AcessoIndiceVariavel); - break; - case 'AcessoMetodoOuPropriedade': - this.visitarExpressaoAcessoMetodo(declaracaoOuConstruto as AcessoMetodoOuPropriedade); - break; - case 'Agrupamento': - this.visitarExpressaoAgrupamento(declaracaoOuConstruto as Agrupamento); - break; - case 'AtribuicaoPorIndice': - this.visitarExpressaoAtribuicaoPorIndice(declaracaoOuConstruto as AtribuicaoPorIndice); - break; - case 'Atribuir': - this.visitarExpressaoDeAtribuicao(declaracaoOuConstruto as Atribuir); - break; - case 'Binario': - this.visitarExpressaoBinaria(declaracaoOuConstruto as Binario); - break; - case 'Bloco': - this.visitarExpressaoBloco(declaracaoOuConstruto as Bloco); - break; - case 'Chamada': - this.visitarExpressaoDeChamada(declaracaoOuConstruto as Chamada); - break; - case 'Classe': - this.visitarDeclaracaoClasse(declaracaoOuConstruto as Classe); - break; - case 'Continua': - this.visitarExpressaoContinua(declaracaoOuConstruto as Continua); - break; - case 'DefinirValor': - this.visitarExpressaoDefinirValor(declaracaoOuConstruto as DefinirValor); - break; - case 'Dicionario': - this.visitarExpressaoDicionario(declaracaoOuConstruto as Dicionario); - break; - case 'Escolha': - this.visitarDeclaracaoEscolha(declaracaoOuConstruto as Escolha); - break; - case 'Enquanto': - this.visitarDeclaracaoEnquanto(declaracaoOuConstruto as Enquanto); - break; - case 'Escreva': - this.visitarDeclaracaoEscreva(declaracaoOuConstruto as Escreva); - break; - case 'Expressao': - this.visitarDeclaracaoDeExpressao(declaracaoOuConstruto as Expressao); - break; - case 'ExpressaoRegular': - this.visitarExpressaoExpressaoRegular(declaracaoOuConstruto as ExpressaoRegular); - break; - case 'Falhar': - this.visitarExpressaoFalhar(declaracaoOuConstruto as Falhar); - break; - case 'Fazer': - this.visitarDeclaracaoFazer(declaracaoOuConstruto as Fazer); - break; - case 'FuncaoConstruto': - this.visitarExpressaoFuncaoConstruto(declaracaoOuConstruto as FuncaoConstruto); - break; - case 'FuncaoDeclaracao': - this.visitarDeclaracaoDefinicaoFuncao(declaracaoOuConstruto as FuncaoDeclaracao); - break; - case 'Importar': - this.visitarDeclaracaoImportar(declaracaoOuConstruto as Importar); - break; - case 'Isto': - this.visitarExpressaoIsto(declaracaoOuConstruto as Isto); - break; - case 'Leia': - this.visitarExpressaoLeia(declaracaoOuConstruto as Leia); - break; - case 'Literal': - this.visitarExpressaoLiteral(declaracaoOuConstruto as Literal); - break; - case 'Logico': - this.visitarExpressaoLogica(declaracaoOuConstruto as Logico); - break; - case 'Para': - this.visitarDeclaracaoPara(declaracaoOuConstruto as Para); - break; - case 'ParaCada': - this.visitarDeclaracaoParaCada(declaracaoOuConstruto as ParaCada); - break; - case 'Retorna': - this.visitarExpressaoRetornar(declaracaoOuConstruto as Retorna); - break; - case 'Se': - this.visitarDeclaracaoSe(declaracaoOuConstruto as Se); - break; - case 'Super': - this.visitarExpressaoSuper(declaracaoOuConstruto as Super); - break; - case 'Sustar': - this.visitarExpressaoSustar(declaracaoOuConstruto as Sustar); - break; - case 'Tente': - this.visitarDeclaracaoTente(declaracaoOuConstruto as Tente); - break; - case 'TipoDe': - this.visitarExpressaoTipoDe(declaracaoOuConstruto as TipoDe); - break; - case 'Unario': - this.visitarExpressaoUnaria(declaracaoOuConstruto as Unario); - break; - case 'Const': - this.visitarDeclaracaoConst(declaracaoOuConstruto as Const); - break; - case 'Var': - this.visitarDeclaracaoVar(declaracaoOuConstruto as Var); - break; - case 'Variavel': - this.visitarExpressaoDeVariavel(declaracaoOuConstruto as Variavel); - break; - case 'Vetor': - this.visitarExpressaoVetor(declaracaoOuConstruto as Vetor); - break; - default: - console.log(declaracaoOuConstruto.constructor.name); - break; - } - } - - formatar(declaracoes: Declaracao[]): string { - this.indentacaoAtual = 0; - this.codigoFormatado = `programa${this.quebraLinha}{${this.quebraLinha}`; - this.devePularLinha = true; - this.deveIndentar = true; - this.indentacaoAtual += this.tamanhoIndentacao; - - for (let declaracao of declaracoes) { - this.formatarDeclaracaoOuConstruto(declaracao); - } - - this.indentacaoAtual -= this.tamanhoIndentacao; - this.codigoFormatado += `}${this.quebraLinha}`; - - return this.codigoFormatado; - } -} diff --git a/fontes/formatadores/index.ts b/fontes/formatadores/index.ts index 4cf4b686..420ad551 100644 --- a/fontes/formatadores/index.ts +++ b/fontes/formatadores/index.ts @@ -1,3 +1,2 @@ export * from './formatador-delegua'; -export * from './formatador-portugol-studio'; export * from './formatador-potigol'; diff --git a/fontes/interpretador/dialetos/index.ts b/fontes/interpretador/dialetos/index.ts index 26ebdedd..d6034ceb 100644 --- a/fontes/interpretador/dialetos/index.ts +++ b/fontes/interpretador/dialetos/index.ts @@ -2,5 +2,4 @@ export * from './birl'; export * from './egua-classico'; export * from './mapler'; export * from './portugol-ipt'; -export * from './portugol-studio'; export * from './potigol'; diff --git a/fontes/interpretador/dialetos/portugol-studio/comum.ts b/fontes/interpretador/dialetos/portugol-studio/comum.ts deleted file mode 100644 index 3e52f6a4..00000000 --- a/fontes/interpretador/dialetos/portugol-studio/comum.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Variavel } from '../../../construtos'; -import { Expressao, Leia } from '../../../declaracoes'; -import { PilhaEscoposExecucaoInterface } from '../../../interfaces/pilha-escopos-execucao-interface'; - -/** - * Execução da leitura de valores da entrada configurada no - * início da aplicação. - * @param expressao Expressão do tipo Leia - * @returns Promise com o resultado da leitura. - */ -export async function visitarExpressaoLeiaComum( - interfaceEntradaSaida: any, - pilhaEscoposExecucao: PilhaEscoposExecucaoInterface, - expressao: Leia -): Promise { - const mensagem = '> '; - for (let argumento of expressao.argumentos) { - const promessaLeitura: Function = () => - new Promise((resolucao) => - interfaceEntradaSaida.question(mensagem, (resposta: any) => { - resolucao(resposta); - }) - ); - - const valorLido = await promessaLeitura(); - const simbolo = - argumento instanceof Expressao - ? ((argumento).expressao).simbolo - : (argumento).simbolo; - pilhaEscoposExecucao.definirVariavel(simbolo.lexema, valorLido); - } -} diff --git a/fontes/interpretador/dialetos/portugol-studio/index.ts b/fontes/interpretador/dialetos/portugol-studio/index.ts deleted file mode 100644 index d5214e34..00000000 --- a/fontes/interpretador/dialetos/portugol-studio/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './interpretador-portugol-studio'; -export * from './interpretador-portugol-studio-com-depuracao'; diff --git a/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio-com-depuracao.ts b/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio-com-depuracao.ts deleted file mode 100644 index 85c2a0df..00000000 --- a/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio-com-depuracao.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Leia } from '../../../declaracoes'; -import { visitarExpressaoLeiaComum } from './comum'; -import { InterpretadorComDepuracao } from '../../interpretador-com-depuracao'; - -export class InterpretadorPortugolStudioComDepuracao extends InterpretadorComDepuracao { - mensagemPrompt: string; - - constructor(diretorioBase: string, funcaoDeRetorno: Function = null, funcaoDeRetornoMesmaLinha: Function = null) { - super(diretorioBase, funcaoDeRetorno, funcaoDeRetornoMesmaLinha); - this.mensagemPrompt = '> '; - } - - /** - * Execução da leitura de valores da entrada configurada no - * início da aplicação. - * @param expressao Expressão do tipo Leia - * @returns Promise com o resultado da leitura. - */ - async visitarExpressaoLeia(expressao: Leia): Promise { - return visitarExpressaoLeiaComum(this.interfaceEntradaSaida, this.pilhaEscoposExecucao, expressao); - } - - /** - * No Portugol Studio, como o bloco de execução da função `inicio` é criado - * pelo avaliador sintático, precisamos ter uma forma aqui de avançar o - * primeiro bloco pós execução de comando, seja ele qual for. - */ - private avancarPrimeiroEscopoAposInstrucao(): void { - const escopoUm = this.pilhaEscoposExecucao.naPosicao(1); - if (!escopoUm) return; - escopoUm.declaracaoAtual = escopoUm.declaracoes.length; - } - - async instrucaoContinuarInterpretacao(escopo?: number): Promise { - const retornoExecucao = await super.instrucaoContinuarInterpretacao(escopo); - this.avancarPrimeiroEscopoAposInstrucao(); - return retornoExecucao; - } - - async instrucaoPasso(escopo?: number): Promise { - const retornoExecucaoPasso = await super.instrucaoPasso(escopo); - this.avancarPrimeiroEscopoAposInstrucao(); - return retornoExecucaoPasso; - } -} diff --git a/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio.ts b/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio.ts deleted file mode 100644 index 4b8ba30a..00000000 --- a/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Leia } from '../../../declaracoes'; -import { InterpretadorBase } from '../../interpretador-base'; -import { visitarExpressaoLeiaComum } from './comum'; - -export class InterpretadorPortugolStudio extends InterpretadorBase { - constructor(diretorioBase: string, performance = false, funcaoDeRetorno: Function = null) { - super(diretorioBase, performance, funcaoDeRetorno); - } - - /** - * Execução da leitura de valores da entrada configurada no - * início da aplicação. - * @param expressao Expressão do tipo Leia - * @returns Promise com o resultado da leitura. - */ - async visitarExpressaoLeia(expressao: Leia): Promise { - return visitarExpressaoLeiaComum(this.interfaceEntradaSaida, this.pilhaEscoposExecucao, expressao); - } -} diff --git a/fontes/lexador/dialetos/index.ts b/fontes/lexador/dialetos/index.ts index 105d7efe..0a4a9f07 100644 --- a/fontes/lexador/dialetos/index.ts +++ b/fontes/lexador/dialetos/index.ts @@ -5,4 +5,3 @@ export * from './lexador-guarani'; export * from './lexador-mapler'; export * from './lexador-potigol'; export * from './lexador-portugol-ipt'; -export * from './lexador-portugol-studio'; diff --git a/fontes/lexador/dialetos/lexador-portugol-studio.ts b/fontes/lexador/dialetos/lexador-portugol-studio.ts deleted file mode 100644 index 5fd36f5a..00000000 --- a/fontes/lexador/dialetos/lexador-portugol-studio.ts +++ /dev/null @@ -1,307 +0,0 @@ -import { RetornoLexador } from '../../interfaces/retornos'; -import { ErroLexador } from '../erro-lexador'; -import { LexadorBase } from '../lexador-base'; - -import { palavrasReservadas } from './palavras-reservadas/portugol-studio'; -import tiposDeSimbolos from '../../tipos-de-simbolos/portugol-studio'; -import { SimboloInterface } from '../../interfaces'; - -/** - * O Lexador é responsável por transformar o código em uma coleção de tokens de linguagem. - * Cada token de linguagem é representado por um tipo, um lexema e informações da linha de código em que foi expresso. - * Também é responsável por mapear as palavras reservadas da linguagem, que não podem ser usadas por outras - * estruturas, tais como nomes de variáveis, funções, literais, classes e assim por diante. - * - * O Lexador de Portugol Studio possui algumas particularidades: - * - Aspas simples são para caracteres individuais, e aspas duplas para cadeias de caracteres. - * - Literais de vetores usam chaves, e não colchetes. - */ -export class LexadorPortugolStudio extends LexadorBase { - protected logicaComumCaracteres(delimitador: string) { - while (this.simboloAtual() !== delimitador && !this.eFinalDoCodigo()) { - this.avancar(); - } - - if (this.eFinalDoCodigo()) { - this.erros.push({ - linha: this.linha + 1, - caractere: this.simboloAnterior(), - mensagem: 'Cadeia de caracteres não finalizada.', - } as ErroLexador); - return; - } - - const valor = this.codigo[this.linha].substring(this.inicioSimbolo + 1, this.atual); - return valor; - } - - analisarCaracter() { - const valor = this.logicaComumCaracteres("'"); - this.adicionarSimbolo(tiposDeSimbolos.CARACTER, valor); - } - - analisarTexto(): void { - const valor = this.logicaComumCaracteres('"'); - this.adicionarSimbolo(tiposDeSimbolos.CADEIA, valor); - } - - analisarNumero(): void { - let real = false; - while (this.eDigito(this.simboloAtual())) { - this.avancar(); - } - - if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) { - real = true; - this.avancar(); - - while (this.eDigito(this.simboloAtual())) { - this.avancar(); - } - } - - const numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual); - - this.adicionarSimbolo(real ? tiposDeSimbolos.REAL : tiposDeSimbolos.INTEIRO, parseFloat(numeroCompleto)); - } - - identificarPalavraChave(): void { - while (this.eAlfabetoOuDigito(this.simboloAtual())) { - this.avancar(); - } - - const codigo: string = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual); - - const tipo: string = codigo in palavrasReservadas ? palavrasReservadas[codigo] : tiposDeSimbolos.IDENTIFICADOR; - - this.adicionarSimbolo(tipo); - } - - analisarToken(): void { - const caractere = this.simboloAtual(); - - switch (caractere) { - case '[': - this.adicionarSimbolo(tiposDeSimbolos.COLCHETE_ESQUERDO); - this.avancar(); - break; - case ']': - this.adicionarSimbolo(tiposDeSimbolos.COLCHETE_DIREITO); - this.avancar(); - break; - case '(': - this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_ESQUERDO); - this.avancar(); - break; - case ')': - this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_DIREITO); - this.avancar(); - break; - case '{': - this.adicionarSimbolo(tiposDeSimbolos.CHAVE_ESQUERDA); - this.avancar(); - break; - case '}': - this.adicionarSimbolo(tiposDeSimbolos.CHAVE_DIREITA); - this.avancar(); - break; - case ',': - this.adicionarSimbolo(tiposDeSimbolos.VIRGULA); - this.avancar(); - break; - case '.': - this.adicionarSimbolo(tiposDeSimbolos.PONTO); - this.avancar(); - break; - case '-': - this.inicioSimbolo = this.atual; - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.MENOS_IGUAL); - this.avancar(); - } else if (this.simboloAtual() === '-') { - this.adicionarSimbolo(tiposDeSimbolos.DECREMENTAR); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.SUBTRACAO); - } - - break; - case '+': - this.inicioSimbolo = this.atual; - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.MAIS_IGUAL); - this.avancar(); - } else if (this.simboloAtual() === '+') { - this.adicionarSimbolo(tiposDeSimbolos.INCREMENTAR); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.ADICAO); - } - - break; - - case ':': - this.adicionarSimbolo(tiposDeSimbolos.DOIS_PONTOS); - this.avancar(); - break; - case '%': - this.adicionarSimbolo(tiposDeSimbolos.MODULO); - this.avancar(); - break; - case '*': - this.inicioSimbolo = this.atual; - this.avancar(); - switch (this.simboloAtual()) { - case '=': - this.avancar(); - this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO_IGUAL); - break; - default: - this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO); - break; - } - break; - case '!': - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.DIFERENTE); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.NEGACAO); - } - - break; - case '=': - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.IGUAL_IGUAL); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.IGUAL); - } - - break; - - /* case '&': - this.adicionarSimbolo(tiposDeSimbolos.BIT_AND); - this.avancar(); - break; - - case '~': - this.adicionarSimbolo(tiposDeSimbolos.BIT_NOT); - this.avancar(); - break; - - case '|': - this.adicionarSimbolo(tiposDeSimbolos.BIT_OR); - this.avancar(); - break; - - case '^': - this.adicionarSimbolo(tiposDeSimbolos.BIT_XOR); - this.avancar(); - break; */ - - case '<': - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.MENOR_IGUAL); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.MENOR); - } - break; - - case '>': - this.avancar(); - if (this.simboloAtual() === '=') { - this.adicionarSimbolo(tiposDeSimbolos.MAIOR_IGUAL); - this.avancar(); - } else { - this.adicionarSimbolo(tiposDeSimbolos.MAIOR); - } - break; - - case '/': - this.avancar(); - switch (this.simboloAtual()) { - case '/': - this.avancarParaProximaLinha(); - break; - case '*': - this.encontrarFimComentarioAsterisco(); - break; - case '=': - this.adicionarSimbolo(tiposDeSimbolos.DIVISAO_IGUAL); - this.avancar(); - break; - default: - this.adicionarSimbolo(tiposDeSimbolos.DIVISAO); - break; - } - - break; - - // Esta sessão ignora espaços em branco na tokenização. - // Ponto-e-vírgula é opcional em Delégua, então pode apenas ser ignorado. - case ' ': - case '\0': - case '\r': - case '\t': - case ';': - this.avancar(); - break; - - case '"': - this.avancar(); - this.analisarTexto(); - this.avancar(); - break; - - case "'": - this.avancar(); - this.analisarCaracter(); - 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.', - } as ErroLexador); - this.avancar(); - } - } - } - - mapear(codigo: string[], hashArquivo: number): RetornoLexador { - this.erros = []; - this.simbolos = []; - this.inicioSimbolo = 0; - this.atual = 0; - this.linha = 0; - - this.codigo = codigo || ['']; - this.hashArquivo = hashArquivo; - - for (let iterador = 0; iterador < this.codigo.length; iterador++) { - this.codigo[iterador] += '\0'; - } - - while (!this.eFinalDoCodigo()) { - this.inicioSimbolo = this.atual; - this.analisarToken(); - } - - return { - simbolos: this.simbolos, - erros: this.erros, - } as RetornoLexador; - } -} diff --git a/fontes/lexador/dialetos/palavras-reservadas/index.ts b/fontes/lexador/dialetos/palavras-reservadas/index.ts index ef3523a4..bcc81053 100644 --- a/fontes/lexador/dialetos/palavras-reservadas/index.ts +++ b/fontes/lexador/dialetos/palavras-reservadas/index.ts @@ -1,3 +1,2 @@ export { palavrasReservadas as palavrasReservadasBirl } from './birl'; -export { palavrasReservadas as palavrasReservadasPortugolStudio } from './portugol-studio'; diff --git a/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.ts b/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.ts deleted file mode 100644 index 3a8ce3bb..00000000 --- a/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.ts +++ /dev/null @@ -1,30 +0,0 @@ -import tiposDeSimbolos from '../../../tipos-de-simbolos/portugol-studio'; - -export const palavrasReservadas = { - cadeia: tiposDeSimbolos.CADEIA, - caracter: tiposDeSimbolos.CARACTER, - caso: tiposDeSimbolos.CASO, - const: tiposDeSimbolos.CONSTANTE, - contrario: tiposDeSimbolos.CONTRARIO, - enquanto: tiposDeSimbolos.ENQUANTO, - escolha: tiposDeSimbolos.ESCOLHA, - escreva: tiposDeSimbolos.ESCREVA, - e: tiposDeSimbolos.E, - faca: tiposDeSimbolos.FACA, - falso: tiposDeSimbolos.FALSO, - funcao: tiposDeSimbolos.FUNCAO, - inteiro: tiposDeSimbolos.INTEIRO, - leia: tiposDeSimbolos.LEIA, - logico: tiposDeSimbolos.LOGICO, - nao: tiposDeSimbolos.NEGACAO, - ou: tiposDeSimbolos.OU, - para: tiposDeSimbolos.PARA, - pare: tiposDeSimbolos.PARE, - programa: tiposDeSimbolos.PROGRAMA, - real: tiposDeSimbolos.REAL, - retorne: tiposDeSimbolos.RETORNE, - se: tiposDeSimbolos.SE, - senao: tiposDeSimbolos.SENAO, - vazio: tiposDeSimbolos.VAZIO, - verdadeiro: tiposDeSimbolos.VERDADEIRO, -}; diff --git a/fontes/tipos-de-simbolos/portugol-studio.ts b/fontes/tipos-de-simbolos/portugol-studio.ts deleted file mode 100644 index f2a3fd78..00000000 --- a/fontes/tipos-de-simbolos/portugol-studio.ts +++ /dev/null @@ -1,58 +0,0 @@ -export default { - ADICAO: 'ADICAO', - CADEIA: 'CADEIA', - CARACTER: 'CARACTER', - CASO: 'CASO', - CHAVE_ESQUERDA: 'CHAVE_ESQUERDA', - CHAVE_DIREITA: 'CHAVE_DIREITA', - COLCHETE_ESQUERDO: 'COLCHETE_ESQUERDO', - COLCHETE_DIREITO: 'COLCHETE_DIREITO', - CONSTANTE: 'CONSTANTE', - CONTRARIO: 'CONTRARIO', - DECREMENTAR: 'DECREMENTAR', - DIFERENTE: 'DIFERENTE', - DIVISAO: 'DIVISAO', - DIVISAO_IGUAL: 'DIVISAO_IGUAL', - DIVISAO_INTEIRA: 'DIVISAO_INTEIRA', - DOIS_PONTOS: 'DOIS_PONTOS', - E: 'E', - ENQUANTO: 'ENQUANTO', - ESCOLHA: 'ESCOLHA', - ESCREVA: 'ESCREVA', - FACA: 'FACA', - FALSO: 'FALSO', - FUNCAO: 'FUNCAO', - IDENTIFICADOR: 'IDENTIFICADOR', - IGUAL: 'IGUAL', - IGUAL_IGUAL: 'IGUAL_IGUAL', - INCREMENTAR: 'INCREMENTAR', - INTEIRO: 'INTEIRO', - LEIA: 'LEIA', - LOGICO: 'LOGICO', - MAIOR: 'MAIOR', - MAIOR_IGUAL: 'MAIOR_IGUAL', - MAIS_IGUAL: 'MAIS_IGUAL', - MENOR: 'MENOR', - MENOR_IGUAL: 'MENOR_IGUAL', - MENOS_IGUAL: 'MENOS_IGUAL', - MODULO: 'MODULO', - MULTIPLICACAO: 'MULTIPLICACAO', - MULTIPLICACAO_IGUAL: 'MULTIPLICACAO_IGUAL', - NEGACAO: 'NEGACAO', - OU: 'OU', - PARA: 'PARA', - PARE: 'PARE', - PARENTESE_ESQUERDO: 'PARENTESE_ESQUERDO', - PARENTESE_DIREITO: 'PARENTESE_DIREITO', - PONTO: 'PONTO', - PONTO_E_VIRGULA: 'PONTO_E_VIRGULA', - PROGRAMA: 'PROGRAMA', - RETORNE: 'RETORNE', - REAL: 'REAL', - SUBTRACAO: 'SUBTRACAO', - VIRGULA: 'VIRGULA', - SE: 'SE', - SENAO: 'SENAO', - VAZIO: 'VAZIO', - VERDADEIRO: 'VERDADEIRO', -}; diff --git a/testes/portugol-studio/avaliador-sintatico.test.ts b/testes/portugol-studio/avaliador-sintatico.test.ts deleted file mode 100644 index 218d10cc..00000000 --- a/testes/portugol-studio/avaliador-sintatico.test.ts +++ /dev/null @@ -1,380 +0,0 @@ -import { AvaliadorSintaticoPortugolStudio } from '../../fontes/avaliador-sintatico/dialetos'; -import { ErroAvaliadorSintatico } from '../../fontes/avaliador-sintatico/erro-avaliador-sintatico'; -import { LexadorPortugolStudio } from '../../fontes/lexador/dialetos'; - -describe('Avaliador sintático (Portugol Studio)', () => { - describe('analisar()', () => { - let lexador: LexadorPortugolStudio; - let avaliadorSintatico: AvaliadorSintaticoPortugolStudio; - - beforeEach(() => { - lexador = new LexadorPortugolStudio(); - avaliadorSintatico = new AvaliadorSintaticoPortugolStudio(); - }); - - describe('Casos de Sucesso', () => { - it('Sucesso - Olá Mundo', () => { - const retornoLexador = lexador.mapear( - [ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' escreva("Olá Mundo")', - ' }', - '}' - ], - -1 - ); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2); - }); - - it('Sucesso - Estruturas de dados', () => { - const retornoLexador = lexador.mapear( - [ - 'programa', - '{', - ' 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); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Sucesso - Agrupamento', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro base', - ' inteiro altura', - ' inteiro area', - ' escreva("Insira a base: ")', - ' leia(base)', - ' escreva("Insira a altura: ")', - ' leia(altura)', - ' area = (base * altura) / 2', - ' escreva("\nA area do triangulo é: ", area)', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Sucesso - Leia', () => { - const retornoLexador = lexador.mapear( - [ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro numero1, numero2, numero3, numero4, numero5', - ' leia(numero1, numero2, numero3, numero4, numero5)', - ' escreva(numero1 + numero2 + numero3 + numero4 + numero5)', - ' }', - '}', - ], - -1 - ); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Sucesso - Funções', () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' mensagem("Bem Vindo")', - ' escreva("O resultado do primeiro cálculo é: ", calcula (3.0, 4.0))', - ' escreva("\nO resultado do segundo cálculo é: ", calcula (7.0, 2.0), "\n")', - ' mensagem("Tchau")', - ' }', - '', - ' funcao mensagem (cadeia texto)', - ' {', - ' inteiro i', - ' ', - ' para (i = 0; i < 50; i++)', - ' {', - ' escreva ("-")', - ' }', - ' ', - ' escreva ("\n", texto, "\n")', - ' ', - ' para (i = 0; i < 50; i++)', - ' {', - ' escreva ("-")', - ' }', - ' ', - ' escreva("\n")', - ' }', - '', - ' funcao real calcula (real a, real b)', - ' {', - ' real resultado', - ' resultado = a * a + b * b', - ' retorne resultado', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.erros).toHaveLength(0); - }); - - it('Estrutura condicional - se e senao.', () => { - const resultado = lexador.mapear( - [ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' real numeroUm, numeroDois, soma', - ' numeroUm = 12.0', - ' numeroDois = 20.0', - ' soma = numeroUm + numeroDois', - ' se (soma > 20)', - ' {', - ' escreva("Numero maior que 20")', - ' }', - ' senao', - ' {', - ' escreva("Numero menor que 20")', - ' }', - ' }', - '}', - ], - -1 - ); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Estruturas de repetição - Enquanto', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro numero, atual = 1, fatorial = 1', - ' ', - ' escreva("Digite um numero: ")', - ' leia(numero)', - ' ', - ' enquanto (atual <= numero)', - ' {', - ' fatorial = fatorial * atual', - ' atual = atual + 1', - ' }', - ' ', - ' escreva("O fatorial de ", numero, " é: ", fatorial, "\n")', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Estruturas de repetição - Faca ... Enquanto', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro idade', - ' ', - ' faca', - ' {', - ' escreva ("Informe sua idade (valores aceitos de 5 a 150): ")', - ' leia (idade)', - ' }', - ' enquanto (idade < 5 ou idade > 120)', - ' ', - ' escreva ("\nCorreto!\n")', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Estruturas de repetição - Para', () => { - const resultado = lexador.mapear([ - 'programa {', - ' funcao inicio() {', - ' para (inteiro i = 1; i <= 10; i++) {', - ' escreva(i)', - ' }', - ' }', - ' }' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Atribuição de Variáveis', () => { - const resultado = lexador.mapear([ - 'programa {', - ' funcao inicio() {', - ' inteiro a = 2', - ' inteiro b = a', - ' escreva("variáveis a:",a," b:",b)', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - - it('Atribuição de Vetores', () => { - const resultado = lexador.mapear([ - 'programa {', - ' funcao inicio() {', - ' inteiro numeros[5] = {23,42,10,24,66}', - ' escreva("zero:", numeros[5])', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(resultado, -1); - - expect(retornoAvaliadorSintatico).toBeTruthy(); - expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0); - }); - }); - - describe('Casos de Falha', () => { - it('Falha - Função `inicio()` não definida', () => { - const retornoLexador = lexador.mapear( - [ - 'programa', - '{', - ' funcao teste()', - ' {', - ' escreva("Olá Mundo")', - ' }', - '}' - ], - -1 - ); - - const t = () => { - avaliadorSintatico.analisar(retornoLexador, -1); - }; - - expect(t).toThrow(ErroAvaliadorSintatico); - expect(t).toThrow( - expect.objectContaining({ - name: 'Error', - message: expect.stringContaining("Função 'inicio()' para iniciar o programa não foi definida.") - }) - ) - }); - - it('Falha - Programa vazio', () => { - const retornoLexador = lexador.mapear([''], -1); - - const t = () => { - avaliadorSintatico.analisar(retornoLexador, -1); - } - - expect(t).toThrow(ErroAvaliadorSintatico); - expect(t).toThrow( - expect.objectContaining({ - name: 'Error', - message: expect.stringContaining("Esperada expressão 'programa' para inicializar programa.") - }) - ) - }) - - it('Falha - Programa escreva com string não finalizada', () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' escreva("Olá Mundo)', - ' }', - '}' - ], -1) - - const t = () => { - avaliadorSintatico.analisar(retornoLexador, -1); - } - - expect(t).toThrow(ErroAvaliadorSintatico); - // @FixMe - Mensagem de erro não está sendo exibida corretamente. - expect(t).toThrow( - expect.objectContaining({ - name: 'Error', - message: expect.stringContaining("Esperado ')' após os valores em escreva.") - }) - ) - }) - - it('Falha - Leia sem variável', () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' leia()', - ' }', - '}' - ], -1); - - const t = () => { - avaliadorSintatico.analisar(retornoLexador, -1); - } - - expect(t).toThrow(ErroAvaliadorSintatico); - }) - - - }); - }); -}); diff --git a/testes/portugol-studio/formatador.test.ts b/testes/portugol-studio/formatador.test.ts deleted file mode 100644 index f0553552..00000000 --- a/testes/portugol-studio/formatador.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as sistemaOperacional from 'os'; - -import { FormatadorPortugolStudio } from '../../fontes/formatadores'; -import { LexadorPortugolStudio } from '../../fontes/lexador/dialetos'; -import { AvaliadorSintaticoPortugolStudio } from '../../fontes/avaliador-sintatico/dialetos'; - -describe('Formatadores > Portugol Studio', () => { - const formatador = new FormatadorPortugolStudio(sistemaOperacional.EOL); - const avaliadorSintatico = new AvaliadorSintaticoPortugolStudio(); - const lexador = new LexadorPortugolStudio(); - - it('Olá mundo', () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' escreva("Olá Mundo")', - ' }', - '}' - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - const resultado = formatador.formatar(retornoAvaliadorSintatico.declaracoes); - const linhasResultado = resultado.split(sistemaOperacional.EOL); - - // console.log(resultado); - expect(linhasResultado).toHaveLength(7); - }); - -}); diff --git a/testes/portugol-studio/interpretador.test.ts b/testes/portugol-studio/interpretador.test.ts deleted file mode 100644 index b4ba8c20..00000000 --- a/testes/portugol-studio/interpretador.test.ts +++ /dev/null @@ -1,364 +0,0 @@ -import { AvaliadorSintaticoPortugolStudio } from '../../fontes/avaliador-sintatico/dialetos'; -import { InterpretadorPortugolStudio } from '../../fontes/interpretador/dialetos'; -import { LexadorPortugolStudio } from '../../fontes/lexador/dialetos'; - -describe('Interpretador (Portugol Studio)', () => { - describe('interpretar()', () => { - let lexador: LexadorPortugolStudio; - let avaliadorSintatico: AvaliadorSintaticoPortugolStudio; - let interpretador: InterpretadorPortugolStudio; - - beforeEach(() => { - lexador = new LexadorPortugolStudio(); - avaliadorSintatico = new AvaliadorSintaticoPortugolStudio(); - interpretador = new InterpretadorPortugolStudio(process.cwd()); - }); - - describe('Cenários de sucesso', () => { - it('Trivial', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' escreva("Olá Mundo")', - ' }', - '}' - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - interpretador.funcaoDeRetorno = (saida: string) => { - expect(saida).toEqual("Olá Mundo") - } - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Sucesso - Leia', async () => { - // Aqui vamos simular a resposta para cinco variáveis de `leia()`. - const respostas = [1, 2, 3, 4, 5]; - interpretador.interfaceEntradaSaida = { - question: (mensagem: string, callback: Function) => { - callback(respostas.pop()); - } - }; - - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro numero1, numero2, numero3, numero4, numero5', - ' leia(numero1, numero2, numero3, numero4, numero5)', - ' escreva(numero1 + numero2 + numero3 + numero4 + numero5)', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - interpretador.funcaoDeRetorno = (saida: string) => { - expect(saida).toEqual("15") - } - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Sucesso - Leia com condicional se', async () => { - const respostas = [1]; - interpretador.interfaceEntradaSaida = { - question: (mensagem: string, callback: Function) => { - callback(respostas.pop()); - } - }; - - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro n', - ' leia(n)', - ' se(n == 1) {', - ' escreva("É igual a 1")', - ' }', - ' senao {', - ' escreva("Não é igual a 1")', - ' }', - ' }', - '}' - ], -1); - - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - interpretador.funcaoDeRetorno = (saida: any) => { - expect(saida).toEqual("É igual a 1") - } - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Atribuição variaveis com soma', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' inteiro a = 2', - ' inteiro b = 3', - ' a = a + b', - ' escreva("O resultado é: ", a)', - ' }', - '}' - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - interpretador.funcaoDeRetorno = (saida: string) => { - expect(saida).toEqual("O resultado é: 5") - } - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Trivial', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' inteiro a = 2', - ' inteiro b = a', - ' escreva("variáveis a:",a," b:",b)', - ' }', - '}' - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Faca', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' inteiro valor = 2', - ' logico eNegativo', - ' faca', - ' {', - ' escreva("Ok\t", valor,"\n")', - ' valor--', - ' eNegativo = valor < 0', - ' }', - ' enquanto(nao eNegativo)', - ' }', - '}' - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - 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); - }); - - it('Retorne', async () => { - const respostas = [1]; - interpretador.interfaceEntradaSaida = { - question: (mensagem: string, callback: Function) => { - callback(respostas.pop()); - } - }; - - const retornoLexador = lexador.mapear([ - 'programa', - '{ ', - 'funcao inicio()', - '{ ', - 'inteiro numero', - 'escreva("Quantos elementos da sequência de Fibonacci deseja calcular? ")', - 'leia(numero)', - 'para (inteiro i = 1; i <= numero ; i++)', - '{', - ' escreva(fibonacci(i), " ")', - '}', - 'escreva("\n")', - '}', - 'funcao inteiro fibonacci(inteiro posicao)', - '{ ', - 'se (posicao == 1)', - '{', - 'retorne 0', - '}', - 'senao se (posicao == 2)', - '{', - 'retorne 1', - '}', - 'retorne fibonacci(posicao - 1) + fibonacci(posicao - 2)', - '}', - '}', - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Constante', async () => { - const respostas = ["Abigail", 4, 5, 10]; - interpretador.interfaceEntradaSaida = { - question: (mensagem: string, callback: Function) => { - callback(respostas.pop()); - } - }; - - const retornoLexador = lexador.mapear([ - 'programa', - '{', - 'funcao inicio ()', - '{ ', - - 'const real PRECO_PARAFUSO = 1.50', - 'const real PRECO_ARRUELA = 2.00', - 'const real PRECO_PORCA = 2.50', - - 'cadeia nome', - 'inteiro quantidade_parafusos, quantidade_arruelas, quantidade_porcas', - 'real total_parafusos, total_arruelas, total_porcas, total_pagar', - - 'escreva("Digite seu nome: ")', - 'leia(nome)', - - 'escreva("\nDigite a quantidade de parafusos que deseja comprar: ")', - 'leia(quantidade_parafusos)', - - 'escreva("Digite a quantidade de arruelas que deseja comprar: ")', - 'leia(quantidade_arruelas)', - - 'escreva("Digite a quantidade de porcas que deseja comprar: ")', - 'leia(quantidade_porcas)', - - 'total_parafusos = PRECO_PARAFUSO * quantidade_parafusos', - 'total_arruelas = PRECO_ARRUELA * quantidade_arruelas', - 'total_porcas = PRECO_PORCA * quantidade_porcas', - - 'total_pagar = total_parafusos + total_porcas + total_arruelas', - - 'escreva("Cliente: ", nome, "\n")', - 'escreva("===============================\n")', - 'escreva("Parafusos: ", quantidade_parafusos, "\n")', - 'escreva("Arruelas: " , quantidade_arruelas, "\n")', - 'escreva("Porcas: ", quantidade_porcas, "\n")', - 'escreva("===============================\n")', - 'escreva("Total a pagar: R$ ", total_pagar, "\n")', - '}', - '}', - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - - it('Escolha', async () => { - const retornoLexador = lexador.mapear([ - 'programa', - '{', - 'funcao inicio()', - '{', - 'escolha (77)', - '{', - 'caso 1:', - 'escreva ("Voce é lindo(a)!")', - 'pare', // Impede que as instruções do caso 2 sejam executadas - 'caso 2:', - 'escreva ("Voce é um monstro!")', - 'pare', // Impede que as instruções do caso 2 sejam executadas - 'caso 3:', - 'escreva ("Tchau!")', - 'pare', - 'caso contrario:', // Será executado para qualquer opção diferente de 1, 2 ou 3 - 'escreva ("Opção Inválida !")', - '}', - 'escreva("\n")', - '}', - '}', - ], -1); - const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); - - const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); - - expect(retornoInterpretador.erros).toHaveLength(0); - }); - }); - }); -}); diff --git a/testes/portugol-studio/lexador.test.ts b/testes/portugol-studio/lexador.test.ts deleted file mode 100644 index 0f964594..00000000 --- a/testes/portugol-studio/lexador.test.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { LexadorPortugolStudio } from "../../fontes/lexador/dialetos"; - -describe('Lexador (Portugol Studio)', () => { - describe('mapear()', () => { - let lexador: LexadorPortugolStudio; - - beforeEach(() => { - lexador = new LexadorPortugolStudio(); - }); - - describe('Cenário de sucesso', () => { - it('Arquivo vazio.', () => { - const resultado = lexador.mapear([''], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(0); - }); - - it('Programa vazio.', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - '', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(9); - }); - - it('Operação matematica - adição', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' esreva(1 + 1)', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(15); - }); - - it('Operação matematica - subtração', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' esreva(1 - 1)', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(15); - }); - - it('Operação matematica - multiplicação', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' esreva(1 * 1)', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(15); - }); - - it('Operação matematica - divisão', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' esreva(1 / 1)', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(15); - }); - - it('Estrutura condicional - se e senão', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' ', - ' funcao inicio()', - ' {', - ' real numeroUm, numeroDois, soma', - ' numeroUm = 12.0', - ' numeroDois = 20.0', - ' soma = numeroUm + numeroDois', - ' se (soma > 20)', - ' {', - ' escreva("Numero maior que 20")', - ' }', - ' senao', - ' {', - ' escreva("Numero menor que 20")', - ' }', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(45); - }); - - it('Enquanto', () => { - const resultado = lexador.mapear([ - 'programa', - '{', - ' funcao inicio()', - ' {', - ' inteiro numero, atual = 1, fatorial = 1', - ' ', - ' escreva("Digite um numero: ")', - ' leia(numero)', - ' ', - ' enquanto (atual <= numero)', - ' {', - ' fatorial = fatorial * atual', - ' atual = atual + 1', - ' }', - ' ', - ' escreva("O fatorial de ", numero, " é: ", fatorial, "\n")', - ' }', - '}' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(57); - }); - - it('Para', () => { - const resultado = lexador.mapear([ - 'programa {', - ' funcao inicio() {', - ' para (inteiro i = 1; i <= 10; i++) {', - ' escreva(i)', - ' }', - ' }', - ' }' - ], -1); - - expect(resultado).toBeTruthy(); - expect(resultado.simbolos).toHaveLength(27); - }); - }); - }); -});