Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tradutores, serializadores e aninhamentos. #92

Merged
merged 13 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions execucao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ const principal = () => {

analisadorArgumentos
.argument('[arquivos...]', 'Nomes dos arquivos (opcional)')
.option(
'-a, --aninhamento',
'Gera CSS com aninhamento. Não recomendado usar se o CSS executar em navegadores antigos.',
false
)
.action((arquivos) => {
if (arquivos.length > 0) {
nomeArquivo = arquivos[0];
Expand All @@ -21,12 +26,14 @@ const principal = () => {
return;
}

const foles = new FolEs();
const foles = new FolEs(opcoes.aninhamento);

if (nomeArquivo.endsWith("foles")) {
console.log(foles.converterParaCss(nomeArquivo));
return;
} else if (nomeArquivo.endsWith("css")) {
}

if (nomeArquivo.endsWith("css")) {
const retorno = foles.converterParaFolEs(nomeArquivo);
console.log(retorno);
return;
Expand Down
14 changes: 12 additions & 2 deletions exemplos/reverso/exemplo.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
html{font-size:12px;}
body{font-size:16px;max-width:20cm;}
html {
font-size:12px;
}

body {
font-size:16px;
max-width:20cm;

p {
color: #999;
}
}
102 changes: 70 additions & 32 deletions fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import tiposDeSimbolos from "../tipos-de-simbolos/css";
import { Seletor } from "../seletores";
import { AvaliadorSintaticoInterface, ImportadorInterface } from "../interfaces";
import { HexadecimalCor } from "../valores/metodos/hexadecimal-cor";

export class AvaliadorSintaticoReverso implements AvaliadorSintaticoInterface {
simbolos: Simbolo[];
Expand Down Expand Up @@ -121,59 +122,96 @@
return seletores;
}

resolverModificadores(): Modificador[] {
// const simboloSeletor = this.avancarEDevolverAnterior();
private resolverCor() {

Check warning on line 125 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
const codigoCor = this.avancarEDevolverAnterior();

Check warning on line 126 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
return new HexadecimalCor(codigoCor.lexema);

Check warning on line 127 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

private valorModificador() {
const valorModificador = this.avancarEDevolverAnterior();

switch (valorModificador.tipo) {
case tiposDeSimbolos.CERQUILHA:
return this.resolverCor();

Check warning on line 135 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 135 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
default:
return valorModificador;
}
}

private resolverModificador(): Modificador {
const modificador = this.consumir(
tiposDeSimbolos.IDENTIFICADOR,
"Esperado nome do atributo de identificação."
);

this.consumir(
tiposDeSimbolos.CHAVE_ESQUERDA,
"Esperado '{' após declaração de seletor."
tiposDeSimbolos.DOIS_PONTOS,
`Esperado ':' após declaração de modificador '${modificador.lexema}'.`
);

const modificadores: Modificador[] = [];
while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.CHAVE_DIREITA)) {
const modificador = this.consumir(
tiposDeSimbolos.IDENTIFICADOR,
"Esperado nome do atributo de identificação."
);
const valorModificador = this.valorModificador();
let quantificador;
if (valorModificador instanceof Simbolo && valorModificador.tipo === tiposDeSimbolos.NUMERO) {
quantificador = this.avancarEDevolverAnterior();
}

this.consumir(
tiposDeSimbolos.DOIS_PONTOS,
`Esperado ':' após declaração de modificador '${modificador.lexema}'.`
);
this.consumir(
tiposDeSimbolos.PONTO_E_VIRGULA,
`Esperado ';' após declaração de valor de modificador '${modificador.lexema}'.`
);

const valorModificador = this.avancarEDevolverAnterior();
const quantificador = this.avancarEDevolverAnterior();
const classeModificadora = new SeletorReversoModificador(
modificador.lexema,
valorModificador instanceof Simbolo ? valorModificador.lexema : valorModificador,

Check warning on line 165 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
quantificador && quantificador.hasOwnProperty('lexema') ?
quantificador.lexema :
quantificador

Check warning on line 168 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
);

return classeModificadora as Modificador;
}

this.consumir(
tiposDeSimbolos.PONTO_E_VIRGULA,
`Esperado ';' após declaração de valor de modificador '${modificador.lexema}'.`
);
resolverModificadorEDeclaracoesAninhadas(): { modificadores: Modificador[], declaracoesAninhadas: Declaracao[] } {
this.consumir(
tiposDeSimbolos.CHAVE_ESQUERDA,
"Esperado '{' após declaração de seletor."
);

const classeModificadora = new SeletorReversoModificador(
modificador.lexema,
valorModificador.lexema,
quantificador.lexema
);
modificadores.push(classeModificadora as Modificador);
const modificadores: Modificador[] = [];
const declaracoesAninhadas: Declaracao[] = [];
while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.CHAVE_DIREITA)) {
switch (this.simbolos[this.atual].tipo) {
case tiposDeSimbolos.IDENTIFICADOR:
const modificador = this.resolverModificador();
modificadores.push(modificador);
break;
default:
const declaracaoAninhada = this.declaracao();

Check warning on line 189 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
declaracoesAninhadas.push(declaracaoAninhada);

Check warning on line 190 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
break;

Check warning on line 191 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 191 in fontes/avaliador-sintatico/avaliador-sintatico-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
}
}

this.avancarEDevolverAnterior(); // chave direita
return modificadores;
return {
modificadores,
declaracoesAninhadas
};
}

declaracao(): any {
declaracao(): Declaracao | null {
if (this.estaNoFinal()) return null;
const seletores = this.resolverSeletores();
const modificadores = this.resolverModificadores();
const modificadorEDeclaracoesAninhadas = this.resolverModificadorEDeclaracoesAninhadas();

return new Declaracao(
seletores,
modificadores,
[]
modificadorEDeclaracoesAninhadas.modificadores,
modificadorEDeclaracoesAninhadas.declaracoesAninhadas
);
}

analisar(simbolos: Simbolo[]) {
analisar(simbolos: Simbolo[]): Declaracao[] {
this.simbolos = simbolos;
this.erros = [];
this.atual = 0;
Expand Down
18 changes: 9 additions & 9 deletions fontes/foles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { AvaliadorSintatico } from "./avaliador-sintatico";
import { AvaliadorSintaticoReverso } from './avaliador-sintatico/avaliador-sintatico-reverso';
import { Lexador } from "./lexador";
import { LexadorReverso } from './lexador/lexador-reverso';
import { Tradutor } from "./tradutor";
import { TradutorReverso } from './tradutor/tradutor-reverso';
import { Serializador } from "./serializadores";
import { SerializadorReverso } from './serializadores/serializador-reverso';
import { Importador } from './importador';
import { ResultadoLexadorInterface, SimboloInterface } from './interfaces';

Expand All @@ -17,19 +17,19 @@ export class FolEs {
avaliadorSintaticoReverso: AvaliadorSintaticoReverso;
importador: Importador;
importadorReverso: Importador;
tradutor: Tradutor;
tradutorReverso: TradutorReverso;
tradutor: Serializador;
tradutorReverso: SerializadorReverso;

constructor() {
constructor(traduzirComAninhamentos: boolean) {
this.lexador = new Lexador();
this.lexadorReverso = new LexadorReverso();
this.importador = new Importador(this.lexador);
this.importadorReverso = new Importador(this.lexadorReverso);
this.importadorReverso.extensaoPadrao = ".css";
this.avaliadorSintatico = new AvaliadorSintatico(this.importador);
this.avaliadorSintaticoReverso = new AvaliadorSintaticoReverso(this.importadorReverso);
this.tradutor = new Tradutor();
this.tradutorReverso = new TradutorReverso();
this.tradutor = new Serializador(traduzirComAninhamentos);
this.tradutorReverso = new SerializadorReverso(traduzirComAninhamentos);
}

/**
Expand All @@ -39,13 +39,13 @@ export class FolEs {
*/
private converterParaCssInterno(simbolos: SimboloInterface[]): string {
const resultadoAvaliadorSintatico = this.avaliadorSintatico.analisar(simbolos);
const traducao = this.tradutor.traduzir(resultadoAvaliadorSintatico);
const traducao = this.tradutor.serializar(resultadoAvaliadorSintatico);
return traducao;
}

private converterParaFolEsInterno(simbolos: SimboloInterface[]): string {
const resultadoAvaliadorSintaticoReverso = this.avaliadorSintaticoReverso.analisar(simbolos);
const traducaoReversa = this.tradutorReverso.traduzir(resultadoAvaliadorSintaticoReverso);
const traducaoReversa = this.tradutorReverso.serializar(resultadoAvaliadorSintaticoReverso);
return traducaoReversa;
}

Expand Down
4 changes: 4 additions & 0 deletions fontes/lexador/lexador-reverso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@
this.adicionarSimbolo(tiposDeSimbolos.PONTO_E_VIRGULA);
this.avancar();
break;
case '#':
this.adicionarSimbolo(tiposDeSimbolos.CERQUILHA);

Check warning on line 193 in fontes/lexador/lexador-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
this.avancar();

Check warning on line 194 in fontes/lexador/lexador-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
break;

Check warning on line 195 in fontes/lexador/lexador-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 195 in fontes/lexador/lexador-reverso.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
case ' ':
case '\0':
case '\r':
Expand Down
4 changes: 3 additions & 1 deletion fontes/lexador/palavras-reservadas/css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import tiposDeSimbolos from "../../tipos-de-simbolos/css";

export default {
'body': tiposDeSimbolos.TAG,
'head': tiposDeSimbolos.TAG,
'html': tiposDeSimbolos.TAG,
'body': tiposDeSimbolos.TAG
'p': tiposDeSimbolos.TAG
}
2 changes: 1 addition & 1 deletion fontes/modificadores/largura-borda-direita.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class LarguraBordaDireita extends Modificador {
}

constructor(valor: string, quantificador?: string, pragmas?: PragmasModificador) {
super("largura-borda-direita", "border-right-width");
super("largura-borda-direita", "border-right-width", pragmas);

validarValorNumerico('largura-borda-direita', valor, this.valoresAceitos);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Metodo } from "../../valores/metodos/metodo";
import { DicionarioReversoModificadores } from "../dicionario/dicionario-reverso-modificadores";
import { PragmasModificador } from "./pragmas-modificador";

export class SeletorReversoModificador {
constructor(nomeCss: string, valor: string, quantificador: string) {
constructor(nomeCss: string, valor: string | Metodo, quantificador: string, pragmas?: PragmasModificador) {
if (
DicionarioReversoModificadores[nomeCss] === undefined ||
DicionarioReversoModificadores[nomeCss] === null
Expand Down
4 changes: 2 additions & 2 deletions fontes/modificadores/validacoes/cor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Hex } from "../../valores/metodos/hex";
import { HexadecimalCor } from "../../valores/metodos/hexadecimal-cor";
import { Metodo } from "../../valores/metodos/metodo";
import { cores } from "../atributos/cores";
import { valoresGlobais } from "../atributos/globais";
Expand All @@ -9,7 +9,7 @@ export function validarValorCor(
valoresAceitos?: { [valorFoles: string]: string },
valoresExtra?: { [valorFoles: string]: string }) {
if (valor instanceof Metodo) {
if (valor instanceof Hex) {
if (valor instanceof HexadecimalCor) {
if (valor['codigo'].length !== 3 && valor['codigo'].length !== 6) {
throw new Error(`Propriedade '${nomePropriedade}' com hexadecimal inválido: '${valor['codigo']}'. Hexadecimais
devem ter 3 ou 6 caracteres após a cerquilha, sendo cada caracter de 0 até 9 ou de A até F.`);
Expand Down
3 changes: 1 addition & 2 deletions fontes/seletores/seletor-classe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
pragmas?: PragmasSeletor;

constructor(nomeClasse: string, pseudoclasse?: Pseudoclasse, pragmas?: PragmasSeletor) {
super(pseudoclasse);
super(pseudoclasse, pragmas);

Check warning on line 10 in fontes/seletores/seletor-classe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
this.nomeClasse = nomeClasse;
this.pragmas = pragmas;
}

paraTexto() {
Expand Down
4 changes: 1 addition & 3 deletions fontes/seletores/seletor-espaco-reservado.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
*/
export class SeletorEspacoReservado extends Seletor {
nome: string;
pragmas?: PragmasSeletor;

constructor(nome: string, pragmas?: PragmasSeletor) {
super(undefined);
super(undefined, pragmas);

Check warning on line 11 in fontes/seletores/seletor-espaco-reservado.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
this.nome = nome;
this.pragmas = pragmas;
}

paraTexto() {
Expand Down
7 changes: 6 additions & 1 deletion fontes/seletores/seletor-estrutura.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Estrutura } from "../estruturas/estrutura";
import { Pseudoclasse } from "../pseudoclasses/pseudoclasse";
import { PragmasSeletor } from "./pragmas-seletor";
import { Seletor } from "./seletor";

export class SeletorEstrutura extends Seletor {
estrutura: Estrutura;

constructor(estrutura: Estrutura, pseudoclasse?: Pseudoclasse) {
super(pseudoclasse);
super(pseudoclasse, {
linha: estrutura.pragmas.linha,
colunaInicial: estrutura.pragmas.colunaInicial,
colunaFinal: estrutura.pragmas.colunaFinal
});
this.estrutura = estrutura;
}

Expand Down
7 changes: 5 additions & 2 deletions fontes/seletores/seletor.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Pseudoclasse } from "../pseudoclasses/pseudoclasse";
import { PragmasSeletor } from "./pragmas-seletor";

export abstract class Seletor {
pseudoclasse?: Pseudoclasse;
pragmas?: PragmasSeletor;

constructor(pseudoclasse?: Pseudoclasse) {
constructor(pseudoclasse?: Pseudoclasse, pragmas?: PragmasSeletor) {
this.pseudoclasse = pseudoclasse;
this.pragmas = pragmas;
}

abstract paraTexto();
}
}
5 changes: 5 additions & 0 deletions fontes/serializadores/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Serializadores

Serializadores são classes que efetivamente escrevem os arquivos de saída.

Nas primeiras implementações de FolEs, os tradutores faziam este papel. Com a inclusão da funcionalidade de geração de mapas de código, os tradutores passaram a gerar uma estrutura de dados intermediária, muito semelhante ao que é gerado pela análise sintática. Essas estruturas possuem todos os pragmas (linha, coluna inicial e coluna final de cada símbolo) recalculados pela tradução.
2 changes: 2 additions & 0 deletions fontes/serializadores/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './serializador';
export * from './serializador-reverso';
Loading
Loading