From 0f8e371acc499df357ef81e253b8899779506736 Mon Sep 17 00:00:00 2001 From: Samuel Vaz Date: Sat, 28 Oct 2023 16:31:44 -0300 Subject: [PATCH] =?UTF-8?q?#376=20Implementa=C3=A7=C3=A3o=20regex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analisador-semantico.ts | 5 +++- .../dialetos/analisador-semantico-birl.ts | 5 +++- .../avaliador-sintatico.ts | 30 +++++++++++++++++++ fontes/construtos/expressao-regular.ts | 21 +++++++++++++ fontes/construtos/index.ts | 9 +++--- .../interfaces/visitante-comum-interface.ts | 3 +- .../interpretador-egua-classico.ts | 4 +++ .../egua-classico/resolvedor/resolvedor.ts | 6 +++- .../dialetos/mapler/interpretador-mapler.ts | 6 +++- .../interpretador-portugol-ipt.ts | 5 +++- fontes/interpretador/interpretador-base.ts | 4 +++ fontes/lexador/lexador.ts | 7 ++++- fontes/tipos-de-simbolos/delegua.ts | 1 + testes/interpretador.test.ts | 15 ++++++++++ 14 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 fontes/construtos/expressao-regular.ts diff --git a/fontes/analisador-semantico/analisador-semantico.ts b/fontes/analisador-semantico/analisador-semantico.ts index 3ed04d06..8aef8d4f 100644 --- a/fontes/analisador-semantico/analisador-semantico.ts +++ b/fontes/analisador-semantico/analisador-semantico.ts @@ -1,4 +1,4 @@ -import { Atribuir, Chamada, FimPara, FormatacaoEscrita, FuncaoConstruto, Literal, Super, TipoDe, Variavel, Vetor } from '../construtos'; +import { Atribuir, Chamada, ExpressaoRegular, FimPara, FormatacaoEscrita, FuncaoConstruto, Literal, Super, TipoDe, Variavel, Vetor } from '../construtos'; import { Bloco, Classe, @@ -58,6 +58,9 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface { this.atual = 0; this.erros = []; } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } erro(simbolo: SimboloInterface, mensagemDeErro: string): void { this.erros.push({ diff --git a/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts b/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts index d45dffd1..cd73513c 100644 --- a/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts +++ b/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts @@ -1,4 +1,4 @@ -import { Atribuir, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../construtos'; +import { Atribuir, ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../construtos'; import { Bloco, Classe, @@ -60,6 +60,9 @@ export class AnalisadorSemanticoBirl implements AnalisadorSemanticoInterface { this.atual = 0; this.erros = []; } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } visitarExpressaoTipoDe(expressao: TipoDe): Promise { throw new Error('Método não implementado.'); diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts index e3fd3fba..f4f7e77c 100644 --- a/fontes/avaliador-sintatico/avaliador-sintatico.ts +++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts @@ -26,6 +26,7 @@ import { Variavel, Vetor, Isto, + ExpressaoRegular, } from '../construtos'; import { ErroAvaliadorSintatico } from './erro-avaliador-sintatico'; @@ -271,11 +272,40 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface flagArr.indexOf(char) === pos) + .join('') + ) + : new RegExp(texto); + } + finalizarChamada(entidadeChamada: Construto): Construto { const argumentos: Array = []; diff --git a/fontes/construtos/expressao-regular.ts b/fontes/construtos/expressao-regular.ts new file mode 100644 index 00000000..919df1ed --- /dev/null +++ b/fontes/construtos/expressao-regular.ts @@ -0,0 +1,21 @@ +import { VisitanteComumInterface, SimboloInterface, VariavelInterface } from '../interfaces'; +import { Construto } from './construto'; + +export class ExpressaoRegular implements Construto { + linha: number; + hashArquivo: number; + valor: any; + + simbolo: SimboloInterface; + + constructor(hashArquivo: number, simbolo: SimboloInterface, valor: any) { + this.linha = Number(simbolo.linha); + this.hashArquivo = hashArquivo; + this.valor = valor; + this.simbolo = simbolo; + } + + async aceitar(visitante: VisitanteComumInterface): Promise { + return Promise.resolve(visitante.visitarExpressaoExpressaoRegular(this)); + } +} diff --git a/fontes/construtos/index.ts b/fontes/construtos/index.ts index 804b0689..e0914ff2 100644 --- a/fontes/construtos/index.ts +++ b/fontes/construtos/index.ts @@ -1,21 +1,22 @@ +export * from './acesso-indice-variavel'; +export * from './acesso-metodo'; +export * from './agrupamento'; export * from './atribuicao-por-indice'; export * from './atribuir'; export * from './binario'; export * from './chamada'; export * from './constante'; export * from './constante-ou-variavel'; +export * from './construto'; export * from './definir-valor'; export * from './dicionario'; -export * from './construto'; +export * from './expressao-regular'; export * from './fim-para'; export * from './formatacao-escrita'; export * from './funcao'; -export * from './acesso-metodo'; -export * from './agrupamento'; export * from './isto'; export * from './literal'; export * from './logico'; -export * from './acesso-indice-variavel'; export * from './super'; export * from './tipo-de'; export * from './unario'; diff --git a/fontes/interfaces/visitante-comum-interface.ts b/fontes/interfaces/visitante-comum-interface.ts index 44349559..d31137ff 100644 --- a/fontes/interfaces/visitante-comum-interface.ts +++ b/fontes/interfaces/visitante-comum-interface.ts @@ -1,4 +1,4 @@ -import { Atribuir, FimPara, Literal, Super, TipoDe } from '../construtos'; +import { Atribuir, ExpressaoRegular, FimPara, Literal, Super, TipoDe } from '../construtos'; import { Bloco, Classe, @@ -58,6 +58,7 @@ export interface VisitanteComumInterface { visitarExpressaoDeleguaFuncao(expressao: any): any; visitarExpressaoDeVariavel(expressao: any): any; visitarExpressaoDicionario(expressao: any): any; + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise; visitarExpressaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha): any; visitarExpressaoFalhar(expressao: any): Promise; visitarExpressaoFimPara(declaracao: FimPara): any; diff --git a/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts b/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts index 150c6a2f..a37cd048 100644 --- a/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts +++ b/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts @@ -11,6 +11,7 @@ import { AcessoIndiceVariavel, Atribuir, Construto, + ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, @@ -89,6 +90,9 @@ export class InterpretadorEguaClassico implements InterpretadorInterface { carregarBibliotecaGlobal(this, this.pilhaEscoposExecucao); } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } visitarExpressaoTipoDe(expressao: TipoDe): Promise { throw new Error('Método não implementado.'); diff --git a/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.ts b/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.ts index edc922fe..ae418711 100644 --- a/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.ts +++ b/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.ts @@ -1,4 +1,4 @@ -import { AcessoMetodo, Construto, FimPara, FormatacaoEscrita, Super, TipoDe, Variavel } from '../../../../construtos'; +import { AcessoMetodo, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, Super, TipoDe, Variavel } from '../../../../construtos'; import { Bloco, Const, @@ -75,6 +75,10 @@ export class ResolvedorEguaClassico implements ResolvedorInterface, Interpretado this.classeAtual = TipoClasse.NENHUM; this.cicloAtual = TipoClasse.NENHUM; } + + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } visitarExpressaoTipoDe(expressao: TipoDe): Promise { throw new Error('Método não implementado.'); diff --git a/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts b/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts index df9413c7..d64f7b75 100644 --- a/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts +++ b/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts @@ -1,4 +1,4 @@ -import { Binario, Construto, Logico, Variavel } from '../../../construtos'; +import { Binario, Construto, ExpressaoRegular, Logico, Variavel } from '../../../construtos'; import { Const, Escreva, EscrevaMesmaLinha, Fazer, Leia } from '../../../declaracoes'; import { InterpretadorBase } from '../..'; import { ContinuarQuebra, Quebra } from '../../../quebras'; @@ -18,6 +18,10 @@ export class InterpretadorMapler extends InterpretadorBase { this.mensagemPrompt = '> '; } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } + visitarDeclaracaoConst(declaracao: Const): Promise { throw new Error('Método não implementado.'); } diff --git a/fontes/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.ts b/fontes/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.ts index 826d5322..49a575c9 100644 --- a/fontes/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.ts +++ b/fontes/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.ts @@ -1,4 +1,4 @@ -import { Atribuir, Construto, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../../construtos'; +import { Atribuir, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../../construtos'; import { Bloco, Classe, @@ -73,6 +73,9 @@ export class InterpretadorPortugolIpt implements InterpretadorInterface { }; this.pilhaEscoposExecucao.empilhar(escopoExecucao); } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + throw new Error('Método não implementado.'); + } visitarExpressaoTipoDe(expressao: TipoDe): Promise { throw new Error('Método não implementado.'); diff --git a/fontes/interpretador/interpretador-base.ts b/fontes/interpretador/interpretador-base.ts index e7a338e8..771618e0 100644 --- a/fontes/interpretador/interpretador-base.ts +++ b/fontes/interpretador/interpretador-base.ts @@ -50,6 +50,7 @@ import { Binario, Chamada, Construto, + ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, @@ -135,6 +136,9 @@ export class InterpretadorBase implements InterpretadorInterface { carregarBibliotecasGlobais(this, this.pilhaEscoposExecucao); } + visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise { + return expressao.valor; + } async visitarExpressaoTipoDe(expressao: TipoDe): Promise { let tipoDe = expressao.valor; diff --git a/fontes/lexador/lexador.ts b/fontes/lexador/lexador.ts index 297c5896..0ebf7b9d 100644 --- a/fontes/lexador/lexador.ts +++ b/fontes/lexador/lexador.ts @@ -323,8 +323,13 @@ export class Lexador implements LexadorInterface { break; case '|': - this.adicionarSimbolo(tiposDeSimbolos.BIT_OR); this.avancar(); + if (this.simboloAtual() === '|') { + this.adicionarSimbolo(tiposDeSimbolos.EXPRESSAO_REGULAR, '||'); + this.avancar(); + } else { + this.adicionarSimbolo(tiposDeSimbolos.BIT_OR); + } break; case '^': diff --git a/fontes/tipos-de-simbolos/delegua.ts b/fontes/tipos-de-simbolos/delegua.ts index d8c3fc91..618d0db3 100644 --- a/fontes/tipos-de-simbolos/delegua.ts +++ b/fontes/tipos-de-simbolos/delegua.ts @@ -29,6 +29,7 @@ export default { ESCOLHA: 'ESCOLHA', ESCREVA: 'ESCREVA', EXPONENCIACAO: 'EXPONENCIACAO', + EXPRESSAO_REGULAR: 'EXPRESSAO_REGULAR', FALHAR: 'FALHAR', FALSO: 'FALSO', FAZER: 'FAZER', diff --git a/testes/interpretador.test.ts b/testes/interpretador.test.ts index eaaaff00..4acbb3a7 100644 --- a/testes/interpretador.test.ts +++ b/testes/interpretador.test.ts @@ -994,6 +994,21 @@ describe('Interpretador', () => { expect(retornoInterpretador.erros).toHaveLength(0); }); }) + + describe('Expressão Regular', () => { + it('Método substituir()', async () => { + const retornoLexador = lexador.mapear([ + "var str = \"olá mundo, olá universo\";", + "var novaStr = str.substituir(||/olá/g||, \"oi\");", + "escreva(novaStr);", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + + const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes); + + expect(retornoInterpretador.erros).toHaveLength(0); + }); + }) }); describe('Cenários de falha', () => {