UNPKG

@designliquido/foles

Version:

Linguagem de folhas de estilo para documentos em geral em português

963 lines 54.9 kB
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AvaliadorSintaticoReverso = void 0;
const declaracoes_1 = require("../declaracoes");
const lexador_1 = require("../lexador");
const erro_avaliador_sintatico_1 = require("./erro-avaliador-sintatico");
const seletor_reverso_modificador_1 = require("../modificadores/superclasse/seletor-reverso-modificador");
const seletor_estruturas_html_1 = require("../estruturas/seletor-estruturas-html");
const css_1 = __importDefault(require("../tipos-de-simbolos/css"));
const seletores_1 = require("../seletores");
const hexadecimal_cor_1 = require("../valores/metodos/foles/hexadecimal-cor");
const seletor_valor_reverso_1 = require("../valores/seletor-valor-reverso");
/**
 * O avaliador sintático reverso avalia símbolos de arquivos CSS,
 * transformando-os em estruturas de alto nível prontas para
 * serem traduzidas para FolEs.
 */
class AvaliadorSintaticoReverso {
    constructor(importador) {
        this.importador = importador;
        this.simbolos = [];
    }
    erro(simbolo, mensagemDeErro) {
        const excecao = new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(simbolo, mensagemDeErro);
        this.erros.push(excecao);
        return excecao;
    }
    estaNoFinal() {
        return this.atual === this.simbolos.length;
    }
    avancarEDevolverAnterior() {
        if (!this.estaNoFinal())
            this.atual += 1;
        return this.simbolos[this.atual - 1];
    }
    verificarTipoSimboloAtual(tipo) {
        if (this.estaNoFinal())
            return false;
        return this.simbolos[this.atual].tipo === tipo;
    }
    consumir(tipo, mensagemDeErro) {
        if (this.verificarTipoSimboloAtual(tipo))
            return this.avancarEDevolverAnterior();
        throw this.erro(this.simbolos[this.atual], mensagemDeErro);
    }
    declaracaoPorSeletor() {
        // TODO: Pensar lógica para seletor de classes.
        this.avancarEDevolverAnterior();
        return null;
    }
    resolverPseudoclasse() {
        let pseudoclasse;
        // TODO: Validar pseudoclasse.
        if (this.verificarTipoSimboloAtual(css_1.default.DOIS_PONTOS)) {
            this.avancarEDevolverAnterior();
            pseudoclasse = this.consumir(css_1.default.IDENTIFICADOR, "Esperado nome de pseudoclasse.");
        }
        return pseudoclasse;
    }
    seletorPorEstrutura() {
        const simboloSeletor = this.avancarEDevolverAnterior();
        const pseudoclasse = this.resolverPseudoclasse();
        return new seletores_1.SeletorEstrutura(new seletor_estruturas_html_1.SeletorEstruturasHtml(simboloSeletor.lexema, {
            linha: simboloSeletor.linha,
            colunaInicial: simboloSeletor.colunaInicial,
            colunaFinal: simboloSeletor.colunaFinal,
        }), pseudoclasse);
    }
    seletorPorId() {
        this.atual += 1;
        const simboloSeletor = this.avancarEDevolverAnterior();
        const pseudoclasse = this.resolverPseudoclasse();
        return new seletores_1.SeletorId(simboloSeletor.lexema, pseudoclasse, {
            linha: simboloSeletor.linha,
            colunaInicial: simboloSeletor.colunaInicial,
            colunaFinal: simboloSeletor.colunaFinal,
        });
    }
    seletorPorNomeDeClasse() {
        this.atual += 1;
        const simboloSeletor = this.avancarEDevolverAnterior();
        const pseudoclasse = this.resolverPseudoclasse();
        return new seletores_1.SeletorClasse(simboloSeletor.lexema, pseudoclasse, {
            linha: simboloSeletor.linha,
            colunaInicial: simboloSeletor.colunaInicial,
            colunaFinal: simboloSeletor.colunaFinal,
        });
    }
    /**
     * Resolve os seletores. Por enquanto resolve apenas um seletor por vez.
     * @param espacoReservado
     */
    resolverSeletores(espacoReservado = null) {
        const seletores = [];
        do {
            switch (this.simbolos[this.atual].tipo) {
                case css_1.default.TAG:
                    seletores.push(this.seletorPorEstrutura());
                    break;
                case css_1.default.IDENTIFICADOR:
                    throw new Error("Não deveria cair aqui.");
                case css_1.default.PONTO:
                    seletores.push(this.seletorPorNomeDeClasse());
                    break;
                case css_1.default.CERQUILHA:
                    seletores.push(this.seletorPorId());
                    break;
            }
        } while (this.simbolos[this.atual].tipo === css_1.default.VIRGULA);
        return seletores;
    }
    resolverCor() {
        const codigoCor = this.avancarEDevolverAnterior();
        return new hexadecimal_cor_1.HexadecimalCor(codigoCor.lexema);
    }
    // TODO: Implementar lógica para resolver método
    resolverMetodo(lexema) {
        switch (lexema) {
            case "annotation":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'annotation'.");
                const valorAnotacao = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método annotation.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorAnotacao]);
            case "blur":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'blur'.");
                const valorBorrar = this.avancarEDevolverAnterior();
                let quantificadorBorrar;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorBorrar = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorBorrar = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'blur'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorBorrar,
                    quantificadorBorrar,
                ]);
            case "brightness":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'brightness'.");
                const valorBrilho = this.avancarEDevolverAnterior();
                let quantificadorBrilho;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorBrilho = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorBrilho = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'brightness'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorBrilho,
                    quantificadorBrilho,
                ]);
            case "calc":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'calc'.");
                const valorCalc1 = this.avancarEDevolverAnterior();
                const quantificadorCalc1 = this.avancarEDevolverAnterior();
                const operadorCalc = this.avancarEDevolverAnterior();
                const valorCalc2 = this.avancarEDevolverAnterior();
                const quantificadorCalc2 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'calc'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorCalc1,
                    quantificadorCalc1,
                    operadorCalc,
                    valorCalc2,
                    quantificadorCalc2,
                ]);
            case "character-variant":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'character-variant'.");
                const valorVariarCaractere = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método character-variant.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorVariarCaractere]);
            case "clamp":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'clamp'.");
                const valorMin = this.avancarEDevolverAnterior();
                const quantificadorMin = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método 'clamp'.");
                const valorMed = this.avancarEDevolverAnterior();
                const quantificadorMed = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método 'clamp'.");
                const valorMax = this.avancarEDevolverAnterior();
                const quantificadorMax = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método clamp.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorMin,
                    quantificadorMin,
                    valorMed,
                    quantificadorMed,
                    valorMax,
                    quantificadorMax,
                ]);
            case "contrast":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'contrast'.");
                const valorContraste = this.avancarEDevolverAnterior();
                let quantificadorContraste;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorContraste = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorContraste = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'contrast'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorContraste,
                    quantificadorContraste,
                ]);
            case "counter":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'counter'.");
                const nomeCounter = this.avancarEDevolverAnterior();
                let estiloCounter = null;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperada vírgula após primeiro parâmetro do método 'counter'.");
                    estiloCounter = this.avancarEDevolverAnterior();
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'counter'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    nomeCounter,
                    estiloCounter,
                ]);
            case "cubic-bezier":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'cubic-bezier'.");
                const parametro1 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método cubic-bezier.");
                const parametro2 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método cubic-bezier.");
                const parametro3 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após terceiro argumento do método cubic-bezier.");
                const parametro4 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após quarto argumento do método curva-cúbica.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    parametro1,
                    parametro2,
                    parametro3,
                    parametro4,
                ]);
            case "drop-shadow":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'drop-shadow'.");
                let corSombra = null;
                if (this.simbolos[this.atual].tipo === "QUALITATIVO") {
                    corSombra = this.avancarEDevolverAnterior();
                }
                const valorSombra1 = this.avancarEDevolverAnterior();
                const quantificadorSombra1 = this.avancarEDevolverAnterior();
                const valorSombra2 = this.avancarEDevolverAnterior();
                const quantificadorSombra2 = this.avancarEDevolverAnterior();
                let valorSombra3;
                let quantificadorSombra3;
                if (this.simbolos[this.atual].tipo === "NUMERO") {
                    valorSombra3 = this.avancarEDevolverAnterior();
                    quantificadorSombra3 = this.avancarEDevolverAnterior();
                }
                else {
                    valorSombra3 = null;
                    quantificadorSombra3 = null;
                }
                if (this.simbolos[this.atual].tipo === "QUALITATIVO") {
                    corSombra = this.avancarEDevolverAnterior();
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'drop-shadow'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorSombra1,
                    quantificadorSombra1,
                    valorSombra2,
                    quantificadorSombra2,
                    valorSombra3,
                    quantificadorSombra3,
                    corSombra,
                ]);
            case "fit-content":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'fit-content'.");
                const valorFit = this.avancarEDevolverAnterior();
                const quantificadorFit = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método fit-content.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorFit["lexema"],
                    quantificadorFit["lexema"],
                ]);
            case "grayscale":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'grayscale'.");
                const valorEscala = this.avancarEDevolverAnterior();
                let quantificadorEscala;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorEscala = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorEscala = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'grayscale'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorEscala,
                    quantificadorEscala,
                ]);
            case "hsl":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'hsl'.");
                const HdeHSL = this.avancarEDevolverAnterior();
                const SdeHSL = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.QUANTIFICADOR, "Esperado símbolo percentual após argumento de saturação (S) no método 'hsl'.");
                const LdeHSL = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.QUANTIFICADOR, "Esperado símbolo percentual após argumento de luminosidade (L) no método 'hsl'.");
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'hsl'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    HdeHSL,
                    SdeHSL,
                    LdeHSL,
                ]);
            case "hsla":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'hsla'.");
                const HdeHSLA = this.avancarEDevolverAnterior();
                const SdeHSLA = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.QUANTIFICADOR, "Esperado símbolo percentual após argumento de saturação (S) no método 'hsla'.");
                const LdeHSLA = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.QUANTIFICADOR, "Esperado símbolo percentual após argumento de luminosidade (L) no método 'hsla'.");
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumentos de método 'hsla'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    HdeHSLA,
                    SdeHSLA,
                    LdeHSLA,
                ]);
            case "hue-rotate":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'hue-rotate'.");
                const valorRotacao = this.avancarEDevolverAnterior();
                let quantificadorRotacao;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacao = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacao = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'hue-rotate'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorRotacao,
                    quantificadorRotacao,
                ]);
            case "invert":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'invert'.");
                const valorInverter = this.avancarEDevolverAnterior();
                let quantificadorInverter;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorInverter = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorInverter = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'invert'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorInverter,
                    quantificadorInverter,
                ]);
            case "linear-gradient":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'linear-gradient'.");
                const valorAngulo = this.avancarEDevolverAnterior();
                let quantificadorAngulo;
                if (valorAngulo.tipo === "QUALITATIVO") {
                    switch (valorAngulo.lexema) {
                        case "superior":
                            valorAngulo.lexema = "0";
                            valorAngulo.tipo = "NUMERO";
                            quantificadorAngulo = {
                                tipo: "QUANTIFICADOR",
                                lexema: "deg",
                            };
                            break;
                        case "direita":
                            valorAngulo.lexema = "90";
                            valorAngulo.tipo = "NUMERO";
                            quantificadorAngulo = {
                                tipo: "QUANTIFICADOR",
                                lexema: "deg",
                            };
                            break;
                        case "inferior":
                            valorAngulo.lexema = "180";
                            valorAngulo.tipo = "NUMERO";
                            quantificadorAngulo = {
                                tipo: "QUANTIFICADOR",
                                lexema: "deg",
                            };
                            break;
                        case "esquerda":
                            valorAngulo.lexema = "270";
                            valorAngulo.tipo = "NUMERO";
                            quantificadorAngulo = {
                                tipo: "QUANTIFICADOR",
                                lexema: "deg",
                            };
                            break;
                        default:
                            break;
                    }
                }
                else {
                    quantificadorAngulo = this.avancarEDevolverAnterior();
                }
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método linear-gradient.");
                const cor1 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método linear-gradient.");
                const cor2 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'linear-gradient'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorAngulo,
                    quantificadorAngulo,
                    cor1,
                    cor2,
                ]);
            case "linear":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'linear'.");
                const valor1 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método linear.");
                const valor2 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método linear.");
                const valor3 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após terceiro argumento do método linear.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valor1,
                    valor2,
                    valor3,
                ]);
            case "minmax":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'minmax'.");
                const valor01 = this.avancarEDevolverAnterior();
                let parametro01 = null;
                if (Number(valor01["lexema"])) {
                    const quantificador01 = this.avancarEDevolverAnterior();
                    parametro01 = `${valor01["lexema"]}${quantificador01["lexema"]}`;
                }
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método minmax.");
                const valor02 = this.avancarEDevolverAnterior();
                let parametro02 = null;
                if (Number(valor02["lexema"])) {
                    const quantificador02 = this.avancarEDevolverAnterior();
                    parametro02 = `${valor02["lexema"]}${quantificador02["lexema"]}`;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método minmax.");
                if (parametro01 !== null) {
                    return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                        parametro01,
                        valor02["lexema"],
                    ]);
                }
                else if (parametro02 !== null) {
                    return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                        valor01["lexema"],
                        parametro02,
                    ]);
                }
            case "opacity":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'opacity'.");
                const valorOpaco = this.avancarEDevolverAnterior();
                let quantificadorOpaco;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorOpaco = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorOpaco = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'opacity'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorOpaco, quantificadorOpaco], true);
            case "ornaments":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'ornaments'.");
                const valorOrnaments = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método ornaments.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorOrnaments]);
            case "perspective":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'perspective'.");
                const valorPerspectivar = this.avancarEDevolverAnterior();
                let quantificadorPerspectivar;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorPerspectivar = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorPerspectivar = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'perspective'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorPerspectivar, quantificadorPerspectivar], true);
            case "ray":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'ray'.");
                let posicaoRaio;
                if (this.simbolos[this.atual].tipo === "QUALITATIVO") {
                    posicaoRaio = this.avancarEDevolverAnterior();
                }
                else {
                    posicaoRaio = null;
                }
                const numeroRaio = this.avancarEDevolverAnterior();
                const quantificadorRaio = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumentos de método 'ray'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    posicaoRaio,
                    numeroRaio,
                    quantificadorRaio,
                ]);
            case "rgb":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rgb'.");
                const vermelho = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após argumento de cor vermelha.");
                const verde = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após argumento de cor verde.");
                const azul = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumentos de método 'rgb'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [vermelho, verde, azul]);
            case "rgba":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rgba'.");
                const vermelhoRgba = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após argumento de cor vermelha.");
                const verdeRgba = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após argumento de cor verde.");
                const azulRgba = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumentos de método 'rgba'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    vermelhoRgba,
                    verdeRgba,
                    azulRgba,
                ]);
            case "rotate":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rotate'.");
                const valorRotacionar = this.avancarEDevolverAnterior();
                let quantificadorRotacionar;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacionar = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacionar = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'rotate'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorRotacionar, quantificadorRotacionar], true);
            case "rotate3d":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rotate3d'.");
                const valor1Rotacionar3d = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperada vírgula após primeiro parâmetro do método 'rotate3d'.");
                const valor2Rotacionar3d = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperada vírgula após segundo parâmetro do método 'rotate3d'.");
                const valor3Rotacionar3d = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperada vírgula após terceiro parâmetro do método 'rotate3d'.");
                const valor4Rotacionar3d = this.avancarEDevolverAnterior();
                let quantificadorRotacionar3d;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacionar3d = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacionar3d = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'rotate3d'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valor1Rotacionar3d,
                    valor2Rotacionar3d,
                    valor3Rotacionar3d,
                    valor4Rotacionar3d,
                    quantificadorRotacionar3d,
                ]);
            case "rotateZ":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rotateZ'.");
                const valorRotacionarZ = this.avancarEDevolverAnterior();
                let quantificadorRotacionarZ;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacionarZ = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacionarZ = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'rotateZ'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorRotacionarZ,
                    quantificadorRotacionarZ,
                ]);
            case "rotateX":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rotateX'.");
                const valorRotacionarX = this.avancarEDevolverAnterior();
                let quantificadorRotacionarX;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacionarX = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacionarX = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'rotateX'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorRotacionarX,
                    quantificadorRotacionarX,
                ]);
            case "rotateY":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'rotateY'.");
                const valorRotacionarY = this.avancarEDevolverAnterior();
                let quantificadorRotacionarY;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorRotacionarY = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorRotacionarY = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'rotateY'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorRotacionarY,
                    quantificadorRotacionarY,
                ]);
            case "saturate":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'saturate'.");
                const valorSaturar = this.avancarEDevolverAnterior();
                let quantificadorSaturar;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorSaturar = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorSaturar = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'saturate'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorSaturar,
                    quantificadorSaturar,
                ]);
            case "scale":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'scale'.");
                const valorScale1 = this.avancarEDevolverAnterior();
                let valorScale2;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método scale.");
                    valorScale2 = this.avancarEDevolverAnterior();
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método scale.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorScale1, valorScale2], true);
            case "scale3d":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'scale3d'.");
                const valorScale3d1 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método scale3d.");
                const valorScale3d2 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método scale3d.");
                const valorScale3d3 = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método scale3d.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorScale3d1,
                    valorScale3d2,
                    valorScale3d3,
                ]);
            case "scaleZ":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'scaleZ'.");
                const valorScaleZ = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método scaleZ.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorScaleZ]);
            case "scaleX":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'scaleX'.");
                const valorScaleX = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método scaleX.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorScaleX]);
            case "scaleY":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'scaleY'.");
                const valorScaleY = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método scaleY.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorScaleY]);
            case "sepia":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'sepia'.");
                const valorSepia = this.avancarEDevolverAnterior();
                let quantificadorSepia;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorSepia = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorSepia = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'sepia'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorSepia,
                    quantificadorSepia,
                ]);
            case "skew":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'skew'.");
                const valorInclinar1 = this.avancarEDevolverAnterior();
                let quantificadorInclinar1;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorInclinar1 = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorInclinar1 = null;
                }
                let valorInclinar2;
                let quantificadorInclinar2;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método 'skew'.");
                    valorInclinar2 = this.avancarEDevolverAnterior();
                    quantificadorInclinar2 = this.avancarEDevolverAnterior();
                }
                else {
                    valorInclinar2 = null;
                    quantificadorInclinar2 = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'skew'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorInclinar1,
                    quantificadorInclinar1,
                    valorInclinar2,
                    quantificadorInclinar2,
                ]);
            case "skewX":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'skewX'.");
                const valorInclinarX = this.avancarEDevolverAnterior();
                let quantificadorInclinarX;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorInclinarX = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorInclinarX = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'skewX'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorInclinarX,
                    quantificadorInclinarX,
                ]);
            case "skewY":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'skewY'.");
                const valorInclinarY = this.avancarEDevolverAnterior();
                let quantificadorInclinarY;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorInclinarY = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorInclinarY = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'skewY'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorInclinarY,
                    quantificadorInclinarY,
                ]);
            case "steps":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'steps'.");
                const valorNumerico = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método steps.");
                const termoSalto = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após segundo argumento do método steps.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorNumerico,
                    termoSalto,
                ]);
            case "styleset":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'styleset'.");
                const valor1ConjuntoEstilos = this.avancarEDevolverAnterior();
                let valor2ConjuntoEstilos;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método styleset.");
                    valor2ConjuntoEstilos = this.avancarEDevolverAnterior();
                }
                let valor3ConjuntoEstilos;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após segundo argumento do método styleset.");
                    valor3ConjuntoEstilos = this.avancarEDevolverAnterior();
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método styleset.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valor1ConjuntoEstilos, valor2ConjuntoEstilos, valor3ConjuntoEstilos]);
            case "stylistic":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'stylistic'.");
                const valorEstilistico = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método stylistic.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorEstilistico]);
            case "swash":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'swash'.");
                const valorEspirrar = this.avancarEDevolverAnterior();
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após argumento do método swash.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [valorEspirrar]);
            case "translate":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'translate'.");
                const valorTranslacao1 = this.avancarEDevolverAnterior();
                let quantificadorTranlacao1;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorTranlacao1 = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorTranlacao1 = null;
                }
                let valorTranslacao2;
                let quantificadorTranlacao2;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método 'translate'.");
                    valorTranslacao2 = this.avancarEDevolverAnterior();
                    quantificadorTranlacao2 = this.avancarEDevolverAnterior();
                }
                else {
                    valorTranslacao2 = null;
                    quantificadorTranlacao2 = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'translação'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorTranslacao1,
                    quantificadorTranlacao1,
                    valorTranslacao2,
                    quantificadorTranlacao2,
                ], true);
            case "translate3d":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'translate3d'.");
                const valorTranslacao3d1 = this.avancarEDevolverAnterior();
                let quantificadorTranlacao3d1;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorTranlacao3d1 = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorTranlacao3d1 = null;
                }
                let valorTranslacao3d2;
                let quantificadorTranlacao3d2;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método 'translate3d'.");
                    valorTranslacao3d2 = this.avancarEDevolverAnterior();
                    if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                        quantificadorTranlacao3d2 =
                            this.avancarEDevolverAnterior();
                    }
                    else {
                        quantificadorTranlacao3d2 = null;
                    }
                }
                else {
                    valorTranslacao3d2 = null;
                    quantificadorTranlacao3d2 = null;
                }
                let valorTranslacao3d3;
                let quantificadorTranlacao3d3;
                if (this.simbolos[this.atual].tipo === "VIRGULA") {
                    this.consumir(css_1.default.VIRGULA, "Esperado vírgula após primeiro argumento do método 'translate3d'.");
                    valorTranslacao3d3 = this.avancarEDevolverAnterior();
                    if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                        quantificadorTranlacao3d3 =
                            this.avancarEDevolverAnterior();
                    }
                    else {
                        quantificadorTranlacao3d3 = null;
                    }
                }
                else {
                    valorTranslacao3d3 = null;
                    quantificadorTranlacao3d3 = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'translate3d'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorTranslacao3d1,
                    quantificadorTranlacao3d1,
                    valorTranslacao3d2,
                    quantificadorTranlacao3d2,
                    valorTranslacao3d3,
                    quantificadorTranlacao3d3,
                ]);
            case "translateX":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'translateX'.");
                const valorTranslaçaoX = this.avancarEDevolverAnterior();
                let quantificadorTranslaçaoX;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorTranslaçaoX = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorTranslaçaoX = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'translateX'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorTranslaçaoX,
                    quantificadorTranslaçaoX,
                ]);
            case "translateY":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'translateY'.");
                const valorTranslaçaoY = this.avancarEDevolverAnterior();
                let quantificadorTranslaçaoY;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorTranslaçaoY = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorTranslaçaoY = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'translateY'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorTranslaçaoY,
                    quantificadorTranslaçaoY,
                ]);
            case "translateZ":
                this.consumir(css_1.default.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'translateZ'.");
                const valorTranslaçaoZ = this.avancarEDevolverAnterior();
                let quantificadorTranslaçaoZ;
                if (this.simbolos[this.atual].tipo === "QUANTIFICADOR") {
                    quantificadorTranslaçaoZ = this.avancarEDevolverAnterior();
                }
                else {
                    quantificadorTranslaçaoZ = null;
                }
                this.consumir(css_1.default.PARENTESE_DIREITO, "Esperado parêntese direito após método 'translateZ'.");
                return new seletor_valor_reverso_1.SeletorValorReverso(lexema, [
                    valorTranslaçaoZ,
                    quantificadorTranslaçaoZ,
                ]);
        }
    }
    valorModificador() {
        const valorModificador = this.avancarEDevolverAnterior();
        switch (valorModificador.tipo) {
            case css_1.default.CERQUILHA:
                return this.resolverCor();
            case css_1.default.METODO:
                return this.resolverMetodo(valorModificador.lexema);
            case css_1.default.IDENTIFICADOR:
                return this.resolverMetodo(valorModificador.lexema);
            default:
                return valorModificador;
        }
    }
    resolverModificador() {
        const modificador = this.consumir(css_1.default.IDENTIFICADOR, "Esperado nome do atributo de identificação.");
        this.consumir(css_1.default.DOIS_PONTOS, `Esperado ':' após declaração de modificador '${modificador.lexema}'.`);
        const valorModificador = this.valorModificador();
        let quantificador;
        if (valorModificador instanceof lexador_1.Simbolo &&
            valorModificador.tipo === css_1.default.NUMERO) {
            quantificador = this.avancarEDevolverAnterior();
        }
        this.consumir(css_1.default.PONTO_E_VIRGULA, `Esperado ';' após declaração de valor de modificador '${modificador.lexema}'.`);
        const classeModificadora = new seletor_reverso_modificador_1.SeletorReversoModificador(modificador.lexema, valorModificador instanceof lexador_1.Simbolo
            ? valorModificador.lexema
            : valorModificador, quantificador && quantificador.hasOwnProperty("lexema")
            ? quantificador.lexema
            : quantificador, {
            linha: modificador.linha,
            colunaInicial: modificador.colunaInicial,
            colunaFinal: modificador.colunaFinal,
        });
        return classeModificadora;
    }
    resolverModificadorEDeclaracoesAninhadas() {
        this.consumir(css_1.default.CHAVE_ESQUERDA, "Esperado '{' após declaração de seletor.");
        const modificadores = [];
        const declaracoesAninhadas = [];
        while (!this.verificarTipoSimboloAtual(css_1.default.CHAVE_DIREITA)) {
            switch (this.simbolos[this.atual].tipo) {
                case css_1.default.IDENTIFICADOR:
                    const modificador = this.resolverModificador();
                    modificadores.push(modificador);
                    break;
                default:
                    const declaracaoAninhada = this.declaracao();
                    declaracoesAninhadas.push(declaracaoAninhada);
                    break;
            }
        }
        this.avancarEDevolverAnterior(); // chave direita
        return {
            modificadores,
            declaracoesAninhadas,
        };
    }
    declaracao() {
        if (this.estaNoFinal())
            return null;
        const seletores = this.resolverSeletores();
        const modificadorEDeclaracoesAninhadas = this.resolverModificadorEDeclaracoesAninhadas();
        return new declaracoes_1.BlocoDeclaracao(seletores, modificadorEDeclaracoesAninhadas.modificadores, modificadorEDeclaracoesAninhadas.declaracoesAninhadas);
    }
    analisar(simbolos) {
        this.simbolos = simbolos;
        this.erros = [];
        this.atual = 0;
        const declaracoes = [];
        while (!this.estaNoFinal()) {
            declaracoes.push(this.declaracao());
        }
        return declaracoes;
    }
}
exports.AvaliadorSintaticoReverso = AvaliadorSintaticoReverso;
//# sourceMappingURL=avaliador-sintatico-reverso.js.map