Repository: DesignLiquido/delegua
Pull request #152 (2022-11-04 00:55:29)

Esboço do Dialeto VisuAlg
Funcionais:

- `testes\exemplos\dialetos\visualg\ola-mundo.alg`
- `testes\exemplos\dialetos\visualg\um-a-10.alg`


Patch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 3174a110..ba99bccc 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -157,7 +157,8 @@
             "runtimeArgs": [
                 "--inspect-brk",
                 "${workspaceRoot}/node_modules/jest/bin/jest.js",
-                "interpretador.test.ts",
+                // "interpretador.test.ts",
+                "visualg",
                 "--runInBand"
             ],
             "console": "integratedTerminal",
@@ -452,6 +453,54 @@
             ],
             "runtimeExecutable": "node",
             "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"]
+        },
+        {
+            "type": "node",
+            "request": "launch",
+            "name": "VisuAlg > Olá Mundo",
+            "skipFiles": ["<node_internals>/**", "node_modules/**"],
+            "cwd": "${workspaceRoot}",
+            "console": "integratedTerminal",
+            "args": [
+                "${workspaceFolder}${pathSeparator}index.ts",
+                "--dialeto",
+                "visualg",
+                "./testes/exemplos/dialetos/visualg/ola-mundo.alg"
+            ],
+            "runtimeExecutable": "node",
+            "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"]
+        },
+        {
+            "type": "node",
+            "request": "launch",
+            "name": "VisuAlg > Times",
+            "skipFiles": ["<node_internals>/**", "node_modules/**"],
+            "cwd": "${workspaceRoot}",
+            "console": "integratedTerminal",
+            "args": [
+                "${workspaceFolder}${pathSeparator}index.ts",
+                "--dialeto",
+                "visualg",
+                "./testes/exemplos/dialetos/visualg/times.alg"
+            ],
+            "runtimeExecutable": "node",
+            "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"]
+        },
+        {
+            "type": "node",
+            "request": "launch",
+            "name": "VisuAlg > 1 a 10",
+            "skipFiles": ["<node_internals>/**", "node_modules/**"],
+            "cwd": "${workspaceRoot}",
+            "console": "integratedTerminal",
+            "args": [
+                "${workspaceFolder}${pathSeparator}index.ts",
+                "--dialeto",
+                "visualg",
+                "./testes/exemplos/dialetos/visualg/um-a-10.alg"
+            ],
+            "runtimeExecutable": "node",
+            "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"]
         }
     ]
 }
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico-base.ts b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
new file mode 100644
index 00000000..047018c8
--- /dev/null
+++ b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
@@ -0,0 +1,330 @@
+import { Binario, Construto, Funcao, Logico, Unario } from '../construtos';
+import {
+    Escreva,
+    Expressao,
+    Se,
+    Enquanto,
+    Para,
+    Sustar,
+    Continua,
+    Retorna,
+    Escolha,
+    Importar,
+    Tente,
+    Fazer,
+    Var,
+    Funcao as FuncaoDeclaracao,
+    Classe,
+} from '../declaracoes';
+import { AvaliadorSintaticoInterface, SimboloInterface } from '../interfaces';
+import {
+    RetornoLexador,
+    RetornoAvaliadorSintatico,
+} from '../interfaces/retornos';
+import { ErroAvaliadorSintatico } from './erro-avaliador-sintatico';
+
+import tiposDeSimbolos from '../tipos-de-simbolos/comum';
+
+/**
+ * O Avaliador Sintático Base é uma tentativa de mapear métodos em comum
+ * entre todos os outros Avaliadores Sintáticos. Depende de um dicionário
+ * de tipos de símbolos comuns entre todos os dialetos.
+ */
+export abstract class AvaliadorSintaticoBase
+    implements AvaliadorSintaticoInterface
+{
+    simbolos: SimboloInterface[];
+    erros: ErroAvaliadorSintatico[];
+    atual: number;
+    ciclos: number;
+
+    consumir(tipo: any, mensagemDeErro: string) {
+        if (this.verificarTipoSimboloAtual(tipo))
+            return this.avancarEDevolverAnterior();
+        throw this.erro(this.simbolos[this.atual], mensagemDeErro);
+    }
+
+    erro(
+        simbolo: SimboloInterface,
+        mensagemDeErro: string
+    ): ErroAvaliadorSintatico {
+        const excecao = new ErroAvaliadorSintatico(simbolo, mensagemDeErro);
+        this.erros.push(excecao);
+        return excecao;
+    }
+
+    verificarTipoSimboloAtual(tipo: string): boolean {
+        if (this.estaNoFinal()) return false;
+        return this.simbolos[this.atual].tipo === tipo;
+    }
+
+    verificarTipoProximoSimbolo(tipo: string): boolean {
+        return this.simbolos[this.atual + 1].tipo === tipo;
+    }
+
+    estaNoFinal(): boolean {
+        return this.atual === this.simbolos.length;
+    }
+
+    avancarEDevolverAnterior(): SimboloInterface {
+        if (!this.estaNoFinal()) this.atual += 1;
+        return this.simbolos[this.atual - 1];
+    }
+
+    verificarSeSimboloAtualEIgualA(...argumentos: any[]): boolean {
+        for (let i = 0; i < argumentos.length; i++) {
+            const tipoAtual = argumentos[i];
+            if (this.verificarTipoSimboloAtual(tipoAtual)) {
+                this.avancarEDevolverAnterior();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    abstract primario(): Construto;
+
+    finalizarChamada(entidadeChamada: Construto): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract chamar(): Construto;
+
+    unario(): Construto {
+        if (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.NEGACAO,
+                tiposDeSimbolos.SUBTRACAO
+            )
+        ) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.unario();
+            return new Unario(-1, operador, direito);
+        }
+
+        return this.chamar();
+    }
+
+    exponenciacao(): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    multiplicar(): Construto {
+        let expressao = this.unario();
+
+        while (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.DIVISAO,
+                tiposDeSimbolos.MULTIPLICACAO,
+                tiposDeSimbolos.MODULO
+            )
+        ) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.unario();
+            expressao = new Binario(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    adicaoOuSubtracao(): Construto {
+        let expressao = this.multiplicar();
+
+        while (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.SUBTRACAO,
+                tiposDeSimbolos.ADICAO
+            )
+        ) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.multiplicar();
+            expressao = new Binario(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    bitFill(): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    bitE(): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    bitOu(): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    comparar(): Construto {
+        let expressao = this.adicaoOuSubtracao();
+
+        while (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.MAIOR,
+                tiposDeSimbolos.MAIOR_IGUAL,
+                tiposDeSimbolos.MENOR,
+                tiposDeSimbolos.MENOR_IGUAL
+            )
+        ) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.adicaoOuSubtracao();
+            expressao = new Binario(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    comparacaoIgualdade(): Construto {
+        let expressao = this.comparar();
+
+        while (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.DIFERENTE,
+                tiposDeSimbolos.IGUAL
+            )
+        ) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.comparar();
+            expressao = new Binario(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    em(): Construto {
+        throw new Error('Método não implementado.');
+    }
+
+    e(): Construto {
+        let expressao = this.comparacaoIgualdade();
+
+        while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.E)) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.comparacaoIgualdade();
+            expressao = new Logico(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    ou(): Construto {
+        let expressao = this.e();
+
+        while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.OU)) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.e();
+            expressao = new Logico(
+                -1,
+                expressao,
+                operador,
+                direito
+            );
+        }
+
+        return expressao;
+    }
+
+    /**
+     * `atribuir()` deve chamar `ou()` na implementação.
+     */
+    abstract atribuir(): Construto;
+
+    expressao(): Construto {
+        return this.atribuir();
+    }
+
+    abstract declaracaoEscreva(): Escreva;
+
+    declaracaoExpressao(): Expressao {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract blocoEscopo(): any[];
+
+    declaracaoSe(): Se {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract declaracaoEnquanto(): Enquanto;
+
+    abstract declaracaoPara(): Para;
+
+    declaracaoSustar(): Sustar {
+        throw new Error('Método não implementado.');
+    }
+
+    declaracaoContinua(): Continua {
+        throw new Error('Método não implementado.');
+    }
+
+    declaracaoRetorna(): Retorna {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract declaracaoEscolha(): Escolha;
+
+    declaracaoImportar(): Importar {
+        throw new Error('Método não implementado.');
+    }
+
+    declaracaoTente(): Tente {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract declaracaoFazer(): Fazer;
+
+    resolverDeclaracao() {
+        throw new Error('Método não implementado.');
+    }
+
+    declaracaoDeVariavel(): Var {
+        throw new Error('Método não implementado.');
+    }
+
+    funcao(tipo: any): FuncaoDeclaracao {
+        const simboloFuncao: SimboloInterface = this.avancarEDevolverAnterior();
+
+        const nomeFuncao: SimboloInterface = this.consumir(
+            tiposDeSimbolos.IDENTIFICADOR,
+            `Esperado nome ${tipo}.`
+        );
+        return new FuncaoDeclaracao(nomeFuncao, this.corpoDaFuncao(tipo));
+    }
+
+    abstract corpoDaFuncao(tipo: any): Funcao;
+
+    declaracaoDeClasse(): Classe {
+        throw new Error('Método não implementado.');
+    }
+
+    abstract declaracao(): any;
+
+    abstract analisar(retornoLexador: RetornoLexador, hashArquivo?: number): RetornoAvaliadorSintatico;
+}
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts
index 1e43ceb0..5f0b9599 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts
@@ -1,4 +1,4 @@
-import tiposDeSimbolos from '../tipos-de-simbolos';
+import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
 import hrtime from 'browser-process-hrtime';
 import {
     AvaliadorSintaticoInterface,
@@ -84,12 +84,12 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     consumir(tipo: string, mensagemDeErro: string): SimboloInterface {
         if (this.verificarTipoSimboloAtual(tipo))
             return this.avancarEDevolverAnterior();
-        throw this.erro(this.simboloAtual(), mensagemDeErro);
+        throw this.erro(this.simbolos[this.atual], mensagemDeErro);
     }
 
     verificarTipoSimboloAtual(tipo: string): boolean {
         if (this.estaNoFinal()) return false;
-        return this.simboloAtual().tipo === tipo;
+        return this.simbolos[this.atual].tipo === tipo;
     }
 
     verificarTipoProximoSimbolo(tipo: string): boolean {
@@ -110,7 +110,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
 
     avancarEDevolverAnterior(): SimboloInterface {
         if (!this.estaNoFinal()) this.atual += 1;
-        return this.simboloAnterior();
+        return this.simbolos[this.atual - 1];
     }
 
     verificarSeSimboloAtualEIgualA(...argumentos: any[]): boolean {
@@ -126,9 +126,9 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     }
 
     primario(): Construto {
-        const simboloAtual = this.simboloAtual();
+        const simboloAtual = this.simbolos[this.atual];
         if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.SUPER)) {
-            const simboloChave = this.simboloAnterior();
+            const simboloChave = this.simbolos[this.atual - 1];
             this.consumir(tiposDeSimbolos.PONTO, "Esperado '.' após 'super'.");
             const metodo = this.consumir(
                 tiposDeSimbolos.IDENTIFICADOR,
@@ -164,7 +164,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 const valor = this.atribuir();
                 valores.push(valor);
                 if (
-                    this.simboloAtual().tipo !==
+                    this.simbolos[this.atual].tipo !==
                     tiposDeSimbolos.COLCHETE_DIREITO
                 ) {
                     this.consumir(
@@ -216,7 +216,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 valores.push(valor);
 
                 if (
-                    this.simboloAtual().tipo !== tiposDeSimbolos.CHAVE_DIREITA
+                    this.simbolos[this.atual].tipo !== tiposDeSimbolos.CHAVE_DIREITA
                 ) {
                     this.consumir(
                         tiposDeSimbolos.VIRGULA,
@@ -239,7 +239,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.FUNCAO
             )
         )
-            return this.corpoDaFuncao(this.simboloAnterior().lexema);
+            return this.corpoDaFuncao(this.simbolos[this.atual - 1].lexema);
         if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.FALSO))
             return new Literal(
                 this.hashArquivo,
@@ -262,7 +262,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
             return new Isto(
                 this.hashArquivo,
                 Number(simboloAtual.linha),
-                this.simboloAnterior()
+                this.simbolos[this.atual - 1]
             );
 
         if (
@@ -271,7 +271,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.TEXTO
             )
         ) {
-            const simboloAnterior: SimboloInterface = this.simboloAnterior();
+            const simboloAnterior: SimboloInterface = this.simbolos[this.atual - 1];
             return new Literal(
                 this.hashArquivo,
                 Number(simboloAnterior.linha),
@@ -282,7 +282,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         if (
             this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IDENTIFICADOR)
         ) {
-            return new Variavel(this.hashArquivo, this.simboloAnterior());
+            return new Variavel(this.hashArquivo, this.simbolos[this.atual - 1]);
         }
 
         if (
@@ -306,7 +306,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IMPORTAR))
             return this.declaracaoImportar();
 
-        throw this.erro(this.simboloAtual(), 'Esperado expressão.');
+        throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
     }
 
     finalizarChamada(entidadeChamada: Construto): Construto {
@@ -318,7 +318,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
             do {
                 if (argumentos.length >= 255) {
                     throw this.erro(
-                        this.simboloAtual(),
+                        this.simbolos[this.atual],
                         'Não pode haver mais de 255 argumentos.'
                     );
                 }
@@ -391,7 +391,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.BIT_NOT
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.unario();
             return new Unario(this.hashArquivo, operador, direito);
         }
@@ -405,7 +405,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         while (
             this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.EXPONENCIACAO)
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.unario();
             expressao = new Binario(
                 this.hashArquivo,
@@ -431,7 +431,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.MODULO_IGUAL
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.exponenciacao();
             expressao = new Binario(
                 this.hashArquivo,
@@ -460,7 +460,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.MENOS_IGUAL
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.multiplicar();
             expressao = new Binario(
                 this.hashArquivo,
@@ -482,7 +482,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.MAIOR_MAIOR
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.adicaoOuSubtracao();
             expressao = new Binario(
                 this.hashArquivo,
@@ -499,7 +499,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         let expressao = this.bitFill();
 
         while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.BIT_AND)) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.bitFill();
             expressao = new Binario(
                 this.hashArquivo,
@@ -521,7 +521,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.BIT_XOR
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.bitE();
             expressao = new Binario(
                 this.hashArquivo,
@@ -545,7 +545,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.MENOR_IGUAL
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.bitOu();
             expressao = new Binario(
                 this.hashArquivo,
@@ -567,7 +567,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.IGUAL_IGUAL
             )
         ) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.comparar();
             expressao = new Binario(
                 this.hashArquivo,
@@ -584,7 +584,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         let expressao = this.comparacaoIgualdade();
 
         while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.EM)) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.comparacaoIgualdade();
             expressao = new Logico(
                 this.hashArquivo,
@@ -601,7 +601,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         let expressao = this.em();
 
         while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.E)) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.em();
             expressao = new Logico(
                 this.hashArquivo,
@@ -618,7 +618,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         let expressao = this.e();
 
         while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.OU)) {
-            const operador = this.simboloAnterior();
+            const operador = this.simbolos[this.atual - 1];
             const direito = this.e();
             expressao = new Logico(
                 this.hashArquivo,
@@ -654,7 +654,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 expressao
             );
         } else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
-            const igual = this.simboloAnterior();
+            const igual = this.simbolos[this.atual - 1];
             const valor = this.atribuir();
 
             if (expressao instanceof Variavel) {
@@ -689,7 +689,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     }
 
     declaracaoEscreva(): Escreva {
-        const simboloAtual = this.simboloAtual();
+        const simboloAtual = this.simbolos[this.atual];
 
         this.consumir(
             tiposDeSimbolos.PARENTESE_ESQUERDO,
@@ -810,7 +810,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
 
     declaracaoPara(): Para {
         try {
-            const simboloPara: SimboloInterface = this.simboloAnterior();
+            const simboloPara: SimboloInterface = this.simbolos[this.atual - 1];
             this.ciclos += 1;
 
             this.consumir(
@@ -872,27 +872,27 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     declaracaoSustar(): Sustar {
         if (this.ciclos < 1) {
             this.erro(
-                this.simboloAnterior(),
+                this.simbolos[this.atual - 1],
                 "'sustar' ou 'pausa' deve estar dentro de um laço de repetição."
             );
         }
 
-        return new Sustar(this.simboloAtual());
+        return new Sustar(this.simbolos[this.atual]);
     }
 
     declaracaoContinua(): Continua {
         if (this.ciclos < 1) {
             this.erro(
-                this.simboloAnterior(),
+                this.simbolos[this.atual - 1],
                 "'continua' precisa estar em um laço de repetição."
             );
         }
 
-        return new Continua(this.simboloAtual());
+        return new Continua(this.simbolos[this.atual]);
     }
 
     declaracaoRetorna(): Retorna {
-        const simboloChave = this.simboloAnterior();
+        const simboloChave = this.simbolos[this.atual - 1];
         let valor = null;
 
         if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PONTO_E_VIRGULA)) {
@@ -968,7 +968,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 ) {
                     if (caminhoPadrao !== null) {
                         const excecao = new ErroAvaliadorSintatico(
-                            this.simboloAtual(),
+                            this.simbolos[this.atual],
                             "Você só pode ter um 'padrao' em cada declaração de 'escolha'."
                         );
                         this.erros.push(excecao);
@@ -1022,7 +1022,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     }
 
     declaracaoTente(): Tente {
-        const simboloTente: SimboloInterface = this.simboloAnterior();
+        const simboloTente: SimboloInterface = this.simbolos[this.atual - 1];
         this.consumir(
             tiposDeSimbolos.CHAVE_ESQUERDA,
             "Esperado '{' após a declaração 'tente'."
@@ -1076,7 +1076,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
     }
 
     declaracaoFazer(): Fazer {
-        const simboloFazer: SimboloInterface = this.simboloAnterior();
+        const simboloFazer: SimboloInterface = this.simbolos[this.atual - 1];
         try {
             this.ciclos += 1;
 
@@ -1133,7 +1133,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         if (
             this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_ESQUERDA)
         ) {
-            const simboloInicioBloco: SimboloInterface = this.simboloAnterior();
+            const simboloInicioBloco: SimboloInterface = this.simbolos[this.atual - 1];
             return new Bloco(
                 simboloInicioBloco.hashArquivo,
                 Number(simboloInicioBloco.linha),
@@ -1141,20 +1141,20 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
             );
         }
 
-        const simboloAtual = this.simboloAtual();
+        const simboloAtual = this.simbolos[this.atual];
         if (simboloAtual.tipo === tiposDeSimbolos.IDENTIFICADOR) {
             // Pela gramática, a seguinte situação não pode ocorrer:
             // 1. O símbolo anterior ser um identificador; e
             // 2. O símbolo anterior estar na mesma linha do identificador atual.
 
-            const simboloAnterior = this.simboloAnterior();
+            const simboloAnterior = this.simbolos[this.atual - 1];
             if (
                 !!simboloAnterior &&
                 simboloAnterior.tipo === tiposDeSimbolos.IDENTIFICADOR &&
                 simboloAnterior.linha === simboloAtual.linha
             ) {
                 this.erro(
-                    this.simboloAtual(),
+                    this.simbolos[this.atual],
                     'Não é permitido ter dois identificadores seguidos na mesma linha.'
                 );
             }
@@ -1194,14 +1194,14 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         do {
             if (parametros.length >= 255) {
                 this.erro(
-                    this.simboloAtual(),
+                    this.simbolos[this.atual],
                     'Não pode haver mais de 255 parâmetros'
                 );
             }
 
             let parametro: Partial<ParametroInterface> = {};
 
-            if (this.simboloAtual().tipo === tiposDeSimbolos.MULTIPLICACAO) {
+            if (this.simbolos[this.atual].tipo === tiposDeSimbolos.MULTIPLICACAO) {
                 this.consumir(tiposDeSimbolos.MULTIPLICACAO, null);
                 parametro.tipo = 'estrela';
             } else {
@@ -1272,7 +1272,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
             );
             superClasse = new Variavel(
                 this.hashArquivo,
-                this.simboloAnterior()
+                this.simbolos[this.atual - 1]
             );
         }
 
@@ -1327,7 +1327,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         this.avancarEDevolverAnterior();
 
         while (!this.estaNoFinal()) {
-            const tipoSimboloAtual: string = this.simboloAnterior().tipo;
+            const tipoSimboloAtual: string = this.simbolos[this.atual - 1].tipo;
             if (tipoSimboloAtual === tiposDeSimbolos.PONTO_E_VIRGULA) return;
 
             switch (tipoSimboloAtual) {
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.ts
index 2c0e8810..85d3bd6e 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.ts
@@ -1,4 +1,4 @@
-import tiposDeSimbolos from '../../tipos-de-simbolos';
+import tiposDeSimbolos from '../../tipos-de-simbolos/delegua';
 
 import {
     AvaliadorSintaticoInterface,
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.ts
index b640946e..13096be8 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.ts
@@ -45,7 +45,7 @@ import {
     SimboloInterface,
 } from '../../interfaces';
 import { Pragma } from '../../lexador/dialetos/pragma';
-import tiposDeSimbolos from '../../lexador/dialetos/tipos-de-simbolos-eguap';
+import tiposDeSimbolos from '../../tipos-de-simbolos/eguap';
 import { RetornoLexador } from '../../interfaces/retornos/retorno-lexador';
 import { ErroAvaliadorSintatico } from '../erro-avaliador-sintatico';
 import { RetornoAvaliadorSintatico } from '../../interfaces/retornos/retorno-avaliador-sintatico';
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
new file mode 100644
index 00000000..fde0fc9c
--- /dev/null
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
@@ -0,0 +1,493 @@
+import { RetornoLexador, RetornoAvaliadorSintatico } from '../../interfaces/retornos';
+import { AvaliadorSintaticoBase } from '../avaliador-sintatico-base';
+import { Bloco, Enquanto, Escolha, Escreva, Fazer, Leia, Para, Var } from '../../declaracoes';
+import { Atribuir, Binario, Construto, Funcao, Literal, Variavel } from '../../construtos';
+import { SimboloInterface } from '../../interfaces';
+import { Simbolo } from '../../lexador';
+
+import tiposDeSimbolos from '../../tipos-de-simbolos/visualg' 
+
+export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
+    validarSegmentoAlgoritmo(): void {
+        this.consumir(tiposDeSimbolos.ALGORITMO, 
+            "Esperada expressão 'algoritmo' para inicializar programa.");
+
+        this.consumir(tiposDeSimbolos.CARACTERE, 
+            "Esperad cadeia de caracteres após palavra-chave 'algoritmo'.");
+
+        this.consumir(tiposDeSimbolos.QUEBRA_LINHA, 
+            "Esperado quebra de linha após definição do segmento 'algoritmo'.");
+    }
+
+    /**
+     * Validação do segmento de declaração de variáveis (opcional).
+     * @returns Vetor de Construtos para inicialização de variáveis.
+     */
+    validarSegmentoVar(): Construto[] {
+        if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.VAR)) {
+            return [];
+        }
+
+        const inicializacoes = [];
+        this.avancarEDevolverAnterior(); // Var
+
+        this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.QUEBRA_LINHA);
+
+        while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.INICIO)) {
+            const identificador = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 
+                "Esperado nome de variável.");
+            this.consumir(tiposDeSimbolos.DOIS_PONTOS, 
+                "Esperado dois-pontos após nome de variável.");
+
+            if (!this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.INTEIRO, tiposDeSimbolos.CARACTERE
+            )) {
+                throw this.erro(this.simbolos[this.atual], 'Tipo de variável não conhecido.');
+            }
+
+            const tipoVariavel = this.simbolos[this.atual - 1].tipo;
+
+            this.consumir(tiposDeSimbolos.QUEBRA_LINHA, 
+                "Esperado quebra de linha após declaração de variável.");
+
+            // Se chegou até aqui, variável é válida.
+            switch (tipoVariavel) {
+                case tiposDeSimbolos.INTEIRO:
+                    inicializacoes.push(new Var(identificador, new Literal(-1, -1, 0)));
+                    break;
+                case tiposDeSimbolos.CARACTERE:
+                    inicializacoes.push(new Var(identificador, new Literal(-1, -1, "")));
+                    break;
+            }
+        }
+
+        return inicializacoes;
+    }
+
+    validarSegmentoInicio(algoritmoOuFuncao: string): void {
+        this.consumir(tiposDeSimbolos.INICIO, 
+            `Esperada expressão 'inicio' para marcar escopo de ${algoritmoOuFuncao}.`);
+    }
+
+    estaNoFinal(): boolean {
+        return this.atual === this.simbolos.length;
+    }
+
+    primario(): Construto {
+        if (
+            this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IDENTIFICADOR)
+        ) {
+            return new Variavel(-1, this.simbolos[this.atual - 1]);
+        }
+
+        if (
+            this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.NUMERO,
+                tiposDeSimbolos.CARACTERE
+            )
+        ) {
+            const simboloAnterior: SimboloInterface = this.simbolos[this.atual - 1];
+            return new Literal(
+                -1,
+                Number(simboloAnterior.linha),
+                simboloAnterior.literal
+            );
+        }
+    }
+
+    /**
+     * Método que resolve atribuições.
+     * @returns Um construto do tipo `Atribuir`, `Conjunto` ou `AtribuicaoSobrescrita`.
+     */
+    atribuir(): Construto {
+        const expressao = this.ou();
+
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.SETA_ATRIBUICAO)) {
+            const igual = this.simbolos[this.atual - 1];
+            const valor = this.atribuir();
+
+            if (expressao instanceof Variavel) {
+                const simbolo = expressao.simbolo;
+                return new Atribuir(-1, simbolo, valor);
+            } 
+
+            this.erro(igual, 'Tarefa de atribuição inválida');
+        }
+
+        return expressao;
+    }
+
+    blocoEscopo(): any[] {
+        const declaracoes = [];
+
+        while (
+            !this.verificarTipoSimboloAtual(tiposDeSimbolos.FIM_FUNCAO) &&
+            !this.estaNoFinal()
+        ) {
+            declaracoes.push(this.declaracao());
+        }
+
+        this.consumir(
+            tiposDeSimbolos.FIM_FUNCAO,
+            "Esperado palavra-chave 'fimfuncao' após o bloco."
+        );
+        return declaracoes;
+    }
+
+    chamar(): Construto {
+        return this.primario();
+    }
+
+    corpoDaFuncao(tipo: any): Funcao {
+        this.consumir(tiposDeSimbolos.DOIS_PONTOS, 
+            "Esperado dois-pontos após nome de função.");
+
+        // Tipo retornado pela função. 
+        if (!this.verificarSeSimboloAtualEIgualA(
+            tiposDeSimbolos.INTEIRO,
+            tiposDeSimbolos.CARACTERE
+        )) {
+            throw this.erro(
+                this.simbolos[this.atual], 
+                "Esperado um tipo válido para retorno de função");
+        }
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após tipo retornado por 'funcao'."
+        );
+
+        this.validarSegmentoVar();
+        this.validarSegmentoInicio('função');
+
+        const corpo = this.blocoEscopo();
+
+        return new Funcao(-1, -1, null, corpo);
+    }
+
+    declaracaoEnquanto(): Enquanto {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        const condicao = this.expressao();
+
+        this.consumir(
+            tiposDeSimbolos.FACA,
+            "Esperado paravra reservada 'faca' após condição de continuidade em declaracão 'enquanto'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após palavra reservada 'faca' em declaracão 'enquanto'."
+        );
+
+        const declaracoes = [];
+        do {
+            declaracoes.push(this.declaracao());
+        } while (
+            ![tiposDeSimbolos.FIM_ENQUANTO].includes(this.simbolos[this.atual].tipo)
+        );
+
+        this.consumir(
+            tiposDeSimbolos.FIM_ENQUANTO,
+            "Esperado palavra-chave 'fimenquanto' para fechamento de declaração 'enquanto'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após palavra-chave 'fimenquanto'."
+        );
+
+        return new Enquanto(condicao, declaracoes);
+    }
+
+    logicaCasosEscolha(): any {
+        let literais = [];
+        let simboloAtualCaso: SimboloInterface = this.avancarEDevolverAnterior();
+        while (simboloAtualCaso.tipo !== tiposDeSimbolos.QUEBRA_LINHA) {
+            literais.push(this.primario());
+            this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA);
+            simboloAtualCaso = this.simbolos[this.atual];
+        }
+
+        return literais;
+    }
+
+    declaracaoEscolha(): Escolha {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        const identificador = this.primario();
+
+        // Blocos de caso
+        const caminhos = [];
+        let simboloAtualBlocoCaso: SimboloInterface = this.avancarEDevolverAnterior();
+        while (![tiposDeSimbolos.OUTRO_CASO, tiposDeSimbolos.FIM_ESCOLHA].includes(simboloAtualBlocoCaso.tipo)) {
+            let caminhoCondicoes = this.logicaCasosEscolha();
+            this.consumir(
+                tiposDeSimbolos.QUEBRA_LINHA,
+                "Esperado quebra de linha após último valor de declaração 'caso'."
+            );
+
+            const declaracoes = [];
+            do {
+                declaracoes.push(this.declaracao());
+            } while (
+                ![tiposDeSimbolos.CASO, tiposDeSimbolos.OUTRO_CASO, tiposDeSimbolos.FIM_ESCOLHA].includes(this.simbolos[this.atual].tipo)
+            );
+
+            caminhos.push({
+                condicoes: caminhoCondicoes,
+                declaracoes,
+            });
+
+            simboloAtualBlocoCaso = this.avancarEDevolverAnterior();
+        }
+
+        let caminhoPadrao = null;
+        if (simboloAtualBlocoCaso.tipo === tiposDeSimbolos.OUTRO_CASO) {
+            const declaracoes = [];
+            do {
+                declaracoes.push(this.declaracao());
+            } while (
+                !this.verificarTipoSimboloAtual(tiposDeSimbolos.FIM_ESCOLHA)
+            );
+
+            caminhoPadrao = {
+                declaracoes,
+            };
+        }
+
+        this.consumir(
+            tiposDeSimbolos.FIM_ESCOLHA,
+            "Esperado palavra-chave 'fimescolha' para fechamento de declaração 'escolha'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após palavra-chave 'fimescolha'."
+        );
+
+        return new Escolha(
+            identificador,
+            caminhos, 
+            caminhoPadrao);
+    }
+
+    declaracaoEscreva(): Escreva {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        this.consumir(
+            tiposDeSimbolos.PARENTESE_ESQUERDO,
+            "Esperado '(' antes dos valores em escreva."
+        );
+
+        const valor = this.declaracao();
+
+        this.consumir(
+            tiposDeSimbolos.PARENTESE_DIREITO,
+            "Esperado ')' após os valores em escreva."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após fechamento de parênteses pós instrução 'escreva'."
+        );
+
+        return new Escreva(
+            Number(simboloAtual.linha),
+            -1,
+            [valor]
+        );
+    }
+
+    /**
+     * Execução de declaração "repita".
+     * @returns Um construto do tipo Fazer
+     */
+    declaracaoFazer(): Fazer {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após instrução 'repita'."
+        );
+
+        const declaracoes = [];
+        do {
+            declaracoes.push(this.declaracao());
+        } while (
+            ![tiposDeSimbolos.ATE].includes(this.simbolos[this.atual].tipo)
+        );
+
+        this.consumir(
+            tiposDeSimbolos.ATE,
+            "Esperado palavra-chave 'ate' após declaração de bloco em instrução 'repita'."
+        );
+
+        const condicao = this.expressao();
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após condição de continuidade em instrução 'repita'."
+        );
+
+        return new Fazer(-1, -1, declaracoes, condicao);
+    }  
+
+    declaracaoLeia(): Leia {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        this.consumir(
+            tiposDeSimbolos.PARENTESE_ESQUERDO,
+            "Esperado '(' antes dos valores em leia."
+        );
+
+        const valor = this.declaracao();
+
+        this.consumir(
+            tiposDeSimbolos.PARENTESE_DIREITO,
+            "Esperado ')' após os valores em leia."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após fechamento de parênteses pós instrução 'leia'."
+        );
+
+        return null;
+    }
+
+    declaracaoPara(): Para {
+        const simboloPara: SimboloInterface = this.avancarEDevolverAnterior();
+
+        const variavelIteracao = this.consumir(
+            tiposDeSimbolos.IDENTIFICADOR,
+            "Esperado identificador de variável após 'para'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.DE,
+            "Esperado palavra reservada 'de' após variáve de controle de 'para'."
+        );
+
+        const numeroInicio = this.consumir(
+            tiposDeSimbolos.NUMERO,
+            "Esperado literal ou variável após 'de' em declaração 'para'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.ATE,
+            "Esperado palavra reservada 'ate' após valor inicial do laço de repetição 'para'."
+        );
+
+        const numeroFim = this.consumir(
+            tiposDeSimbolos.NUMERO,
+            "Esperado literal ou variável após 'de' em declaração 'para'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.FACA,
+            "Esperado palavra reservada 'faca' após valor final do laço de repetição 'para'."
+        );
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após palavra reservada 'faca' do laço de repetição 'para'."
+        );
+
+        let declaracoesBlocoPara = []
+        let simboloAtualBlocoPara: SimboloInterface = this.simbolos[this.atual];
+        while (simboloAtualBlocoPara.tipo !== tiposDeSimbolos.FIM_PARA) {
+            declaracoesBlocoPara.push(this.declaracao());
+            simboloAtualBlocoPara = this.avancarEDevolverAnterior();
+        }
+
+        this.consumir(
+            tiposDeSimbolos.QUEBRA_LINHA,
+            "Esperado quebra de linha após palavra reservada 'fimpara'."
+        );
+        
+        const corpo = new Bloco(-1, Number(simboloPara.linha) + 1, declaracoesBlocoPara.filter(d => d));
+
+        return new Para(-1, 
+            Number(simboloPara.linha), 
+            new Atribuir(-1, variavelIteracao, new Literal(-1, -1, numeroInicio.literal)), 
+            new Binario(-1, 
+                new Variavel(-1, variavelIteracao), 
+                new Simbolo(tiposDeSimbolos.MENOR, "", "", Number(simboloPara.linha), -1), 
+                new Literal(-1, -1, numeroFim.literal)
+            ), 
+            new Atribuir(-1, 
+                variavelIteracao, 
+                new Binario(-1, 
+                    new Variavel(-1, variavelIteracao), 
+                    new Simbolo(tiposDeSimbolos.ADICAO, '', null, -1, -1), 
+                    new Literal(-1, -1, 1)
+                )
+            ), 
+            corpo
+        );
+    }
+
+    declaracao(): any {
+        const simboloAtual = this.simbolos[this.atual];
+        switch (simboloAtual.tipo) {
+            case tiposDeSimbolos.ENQUANTO:
+                return this.declaracaoEnquanto();
+            case tiposDeSimbolos.ESCOLHA:
+                return this.declaracaoEscolha();
+            case tiposDeSimbolos.ESCREVA:
+            case tiposDeSimbolos.ESCREVA_LINHA:
+                return this.declaracaoEscreva();
+            case tiposDeSimbolos.FUNCAO:
+                return this.funcao('funcao');
+            case tiposDeSimbolos.LEIA:
+                return this.declaracaoLeia();
+            case tiposDeSimbolos.PARA:
+                return this.declaracaoPara();
+            case tiposDeSimbolos.PARENTESE_ESQUERDO:
+            case tiposDeSimbolos.PARENTESE_DIREITO:
+                throw new Error('Não deveria estar caindo aqui.')
+            case tiposDeSimbolos.QUEBRA_LINHA:
+                this.avancarEDevolverAnterior();
+                return null;
+            case tiposDeSimbolos.REPITA:
+                return this.declaracaoFazer();
+            default:
+                return this.atribuir();
+        }
+    }
+
+    /**
+     * No VisuAlg, há uma determinada cadência de validação de símbolos. 
+     * - O primeiro símbolo é `algoritmo`, seguido por um identificador e
+     * uma quebra de linha.
+     * - O segundo símbolo é `var`, que pode ser seguido por uma série de 
+     * declarações de variáveis e finalizado por uma quebra de linha.
+     * - O terceiro símbolo é `inicio`, seguido por uma quebra de linha. 
+     * - O último símbolo deve ser `fimalgoritmo`, que também é usado para 
+     * definir quando não existem mais construtos a serem adicionados.
+     * @param retornoLexador Os símbolos entendidos pelo Lexador.
+     * @param hashArquivo Obrigatório por interface mas não usado aqui.
+     */
+    analisar(retornoLexador: RetornoLexador, hashArquivo?: number): RetornoAvaliadorSintatico {
+        this.erros = [];
+        this.atual = 0;
+        this.ciclos = 0;
+
+        this.simbolos = retornoLexador?.simbolos || [];
+
+        let declaracoes = [];
+        this.validarSegmentoAlgoritmo();
+        declaracoes = declaracoes.concat(this.validarSegmentoVar());
+        this.validarSegmentoInicio('algoritmo');
+
+        while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== tiposDeSimbolos.FIM_ALGORITMO) {
+            declaracoes.push(this.declaracao());
+        }
+
+        return { 
+            declaracoes: declaracoes.filter(d => d),
+            erros: this.erros
+        } as RetornoAvaliadorSintatico;
+    }
+}
diff --git a/fontes/declaracoes/bloco.ts b/fontes/declaracoes/bloco.ts
index 9cd4023b..fff4ce47 100644
--- a/fontes/declaracoes/bloco.ts
+++ b/fontes/declaracoes/bloco.ts
@@ -3,9 +3,9 @@ import { Declaracao } from "./declaracao";
 
 
 export class Bloco extends Declaracao {
-    declaracoes: any;
+    declaracoes: any[];
 
-    constructor(hashArquivo: number, linha: number, declaracoes: any) {
+    constructor(hashArquivo: number, linha: number, declaracoes: any[]) {
         super(linha, hashArquivo);
         this.declaracoes = declaracoes;
     }
diff --git a/fontes/declaracoes/escolha.ts b/fontes/declaracoes/escolha.ts
index 890390a5..087bffe6 100644
--- a/fontes/declaracoes/escolha.ts
+++ b/fontes/declaracoes/escolha.ts
@@ -1,15 +1,17 @@
 import { Construto } from "../construtos";
 import { Declaracao } from "./declaracao";
 
-
+/**
+ * Declaração de escolha de caminho a executar de acordo com literal ou identificador.
+ */
 export class Escolha extends Declaracao {
-    condicao: Construto;
+    identificadorOuLiteral: Construto;
     caminhos: any;
     caminhoPadrao: any;
 
-    constructor(condicao: Construto, caminhos: any, caminhoPadrao: any) {
-        super(condicao.linha, condicao.hashArquivo);
-        this.condicao = condicao;
+    constructor(identificadorOuLiteral: Construto, caminhos: any, caminhoPadrao: any) {
+        super(identificadorOuLiteral.linha, identificadorOuLiteral.hashArquivo);
+        this.identificadorOuLiteral = identificadorOuLiteral;
         this.caminhos = caminhos;
         this.caminhoPadrao = caminhoPadrao;
     }
diff --git a/fontes/declaracoes/index.ts b/fontes/declaracoes/index.ts
index 23a24a8a..115ae99a 100644
--- a/fontes/declaracoes/index.ts
+++ b/fontes/declaracoes/index.ts
@@ -8,6 +8,7 @@ export * from './expressao';
 export * from './fazer';
 export * from './funcao';
 export * from './importar';
+export * from './leia';
 export * from './para';
 export * from './sustar';
 export * from './retorna';
diff --git a/fontes/declaracoes/leia.ts b/fontes/declaracoes/leia.ts
new file mode 100644
index 00000000..7bc2f8c3
--- /dev/null
+++ b/fontes/declaracoes/leia.ts
@@ -0,0 +1,20 @@
+import { Construto } from "../construtos";
+import { InterpretadorInterface } from "../interfaces";
+import { Declaracao } from "./declaracao";
+
+/**
+ * Declaração que pede a leitura de uma informação da entrada
+ * configurada no início da aplicação.
+ */
+export class Leia extends Declaracao {
+    argumentos: Construto[];
+
+    constructor(linha: number, hashArquivo: number, argumentos: Construto[]) {
+        super(linha, hashArquivo);
+        this.argumentos = argumentos;
+    }
+
+    aceitar(visitante: InterpretadorInterface): any {
+        return visitante.visitarExpressaoLeia(this);
+    }
+}
diff --git a/fontes/declaracoes/var.ts b/fontes/declaracoes/var.ts
index bad76b96..a59c0fe3 100644
--- a/fontes/declaracoes/var.ts
+++ b/fontes/declaracoes/var.ts
@@ -1,12 +1,13 @@
+import { Construto } from "../construtos";
 import { InterpretadorInterface, SimboloInterface } from "../interfaces";
 import { Declaracao } from "./declaracao";
 
 
 export class Var extends Declaracao {
     simbolo: SimboloInterface;
-    inicializador: any;
+    inicializador: Construto;
 
-    constructor(simbolo: SimboloInterface, inicializador: any) {
+    constructor(simbolo: SimboloInterface, inicializador: Construto) {
         super(Number(simbolo.linha), simbolo.hashArquivo);
         this.simbolo = simbolo;
         this.inicializador = inicializador;
diff --git a/fontes/delegua.ts b/fontes/delegua.ts
index ef65bad3..1050bf3b 100644
--- a/fontes/delegua.ts
+++ b/fontes/delegua.ts
@@ -6,7 +6,7 @@ import chalk from 'chalk';
 import { Lexador } from './lexador/lexador';
 import { AvaliadorSintatico } from './avaliador-sintatico/avaliador-sintatico';
 import { Interpretador } from './interpretador/interpretador';
-import tiposDeSimbolos from './tipos-de-simbolos';
+import tiposDeSimbolos from './tipos-de-simbolos/delegua';
 
 import {
     AvaliadorSintaticoInterface,
@@ -29,6 +29,8 @@ import { ImportadorInterface } from './interfaces/importador-interface';
 import { Importador, RetornoImportador } from './importador';
 import { InterpretadorComDepuracao } from './interpretador/interpretador-com-depuracao';
 import { ResolvedorEguaClassico } from './resolvedor/dialetos';
+import { LexadorVisuAlg } from './lexador/dialetos/lexador-visualg';
+import { AvaliadorSintaticoVisuAlg } from './avaliador-sintatico/dialetos/avaliador-sintatico-visualg';
 
 /**  
  * O núcleo da linguagem. 
@@ -40,7 +42,7 @@ export class Delegua implements DeleguaInterface {
     arquivosAbertos: { [identificador: string]: string };
     conteudoArquivosAbertos: { [identificador: string]: string[] };
 
-    interpretador: InterpretadorInterface | InterpretadorComDepuracaoInterface;
+    interpretador: InterpretadorInterface;
     lexador: LexadorInterface;
     avaliadorSintatico: AvaliadorSintaticoInterface;
     importador: ImportadorInterface;
@@ -85,6 +87,12 @@ export class Delegua implements DeleguaInterface {
 
                 console.log('Usando dialeto: ÉguaP');
                 break;
+            case 'visualg':
+                this.lexador = new LexadorVisuAlg();
+                this.avaliadorSintatico = new AvaliadorSintaticoVisuAlg();
+                this.importador = new Importador(this.lexador, this.avaliadorSintatico, this.arquivosAbertos, this.conteudoArquivosAbertos, depurador);
+                this.interpretador = new Interpretador(this.importador, process.cwd(), false, console.log);
+                break;
             default:
                 this.lexador = new Lexador(performance);
                 this.avaliadorSintatico = new AvaliadorSintatico(performance);
@@ -110,7 +118,7 @@ export class Delegua implements DeleguaInterface {
                     .version || '0.7'
             );
         } catch (error: any) {
-            return '0.6 (desenvolvimento)';
+            return '0.7 (desenvolvimento)';
         }
     }
 
diff --git a/fontes/interfaces/avaliador-sintatico-interface.ts b/fontes/interfaces/avaliador-sintatico-interface.ts
index ce0d1ebc..076d33d7 100644
--- a/fontes/interfaces/avaliador-sintatico-interface.ts
+++ b/fontes/interfaces/avaliador-sintatico-interface.ts
@@ -34,14 +34,12 @@ export interface AvaliadorSintaticoInterface {
     erro(simbolo: SimboloInterface, mensagemDeErro: string): ErroAvaliadorSintatico;
     verificarTipoSimboloAtual(tipo: string): boolean;
     verificarTipoProximoSimbolo(tipo: string): boolean;
-    simboloAtual(): SimboloInterface;
-    simboloAnterior(): SimboloInterface;
     estaNoFinal(): boolean;
     avancarEDevolverAnterior(): any;
     verificarSeSimboloAtualEIgualA(...argumentos: any[]): boolean;
     primario(): any;
     finalizarChamada(entidadeChamada: Construto): Construto;
-    chamar(): any;
+    chamar(): Construto;
     unario(): Construto;
     exponenciacao(): Construto;
     multiplicar(): Construto;
@@ -71,8 +69,8 @@ export interface AvaliadorSintaticoInterface {
     declaracaoFazer(): Fazer;
     resolverDeclaracao(): any;
     declaracaoDeVariavel(): Var;
-    funcao(tipo: any): FuncaoDeclaracao;
-    corpoDaFuncao(tipo: any): Funcao;
+    funcao(tipo: string): FuncaoDeclaracao;
+    corpoDaFuncao(tipo: string): Funcao;
     declaracaoDeClasse(): Classe;
     declaracao(): any;
     analisar(retornoLexador: RetornoLexador, hashArquivo?: number): RetornoAvaliadorSintatico;
diff --git a/fontes/interfaces/interpretador-interface.ts b/fontes/interfaces/interpretador-interface.ts
index bcae5c60..6f7ee853 100644
--- a/fontes/interfaces/interpretador-interface.ts
+++ b/fontes/interfaces/interpretador-interface.ts
@@ -1,6 +1,6 @@
 import { EspacoVariaveis } from "../espaco-variaveis";
 import { Atribuir, Literal, Super } from "../construtos";
-import { Bloco, Classe, Continua, Declaracao, Enquanto, Escolha, Escreva, Expressao, Fazer, Funcao, Importar, Para, Retorna, Se, Sustar, Tente, Var } from "../declaracoes";
+import { Bloco, Classe, Continua, Declaracao, Enquanto, Escolha, Escreva, Expressao, Fazer, Funcao, Importar, Leia, Para, Retorna, Se, Sustar, Tente, Var } from "../declaracoes";
 import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from "../quebras";
 import { PilhaEscoposExecucaoInterface } from "./pilha-escopos-execucao-interface";
 
@@ -26,6 +26,7 @@ export interface InterpretadorInterface {
     procurarVariavel(nome: SimboloInterface, expressao: any): any;
     visitarExpressaoDeVariavel(expressao: any): any;
     visitarDeclaracaoDeExpressao(declaracao: Expressao): any;
+    visitarExpressaoLeia(expressao: Leia): any;
     visitarExpressaoLogica(expressao: any): any;
     visitarExpressaoSe(declaracao: Se): any;
     visitarExpressaoPara(declaracao: Para): any;
diff --git a/fontes/interfaces/lexador-interface.ts b/fontes/interfaces/lexador-interface.ts
index 0458bd48..ee7f818b 100644
--- a/fontes/interfaces/lexador-interface.ts
+++ b/fontes/interfaces/lexador-interface.ts
@@ -3,7 +3,7 @@ import { SimboloInterface } from "./simbolo-interface";
 
 export interface LexadorInterface {
     simbolos: SimboloInterface[];
-    codigo: string[];
+    codigo: string | string[];
     inicioSimbolo: number;
     atual: number;
     linha: number;
@@ -12,7 +12,7 @@ export interface LexadorInterface {
     eAlfabeto(caractere: string): boolean;
     eAlfabetoOuDigito(caractere: string): boolean;
     eFinalDoCodigo(): boolean;
-    avancar(): void;
+    avancar(): string | void;
     adicionarSimbolo(tipo: any, literal: any): void;
     simboloAtual(): string;
     proximoSimbolo(): string;
diff --git a/fontes/interpretador/dialetos/egua-classico.ts b/fontes/interpretador/dialetos/egua-classico.ts
index 43e1aa0e..742346d1 100644
--- a/fontes/interpretador/dialetos/egua-classico.ts
+++ b/fontes/interpretador/dialetos/egua-classico.ts
@@ -1,7 +1,7 @@
 import * as caminho from 'path';
 import * as fs from 'fs';
 
-import tiposDeSimbolos from '../../tipos-de-simbolos';
+import tiposDeSimbolos from '../../tipos-de-simbolos/delegua';
 import { EspacoVariaveis } from '../../espaco-variaveis';
 import { Delegua } from '../../delegua';
 import carregarBibliotecaGlobal from '../../bibliotecas/biblioteca-global';
@@ -18,7 +18,7 @@ import {
     ErroEmTempoDeExecucao,
 } from '../../excecoes';
 import { InterpretadorInterface, SimboloInterface, ResolvedorInterface, VariavelInterface } from '../../interfaces';
-import { Classe, Declaracao, Enquanto, Escolha, Escreva, Expressao, Fazer, Funcao, Importar, Para, Se, Tente, Var } from '../../declaracoes';
+import { Classe, Declaracao, Enquanto, Escolha, Escreva, Expressao, Fazer, Funcao, Importar, Leia, Para, Se, Tente, Var } from '../../declaracoes';
 import { AcessoIndiceVariavel, Atribuir, Construto, Literal, Super, Variavel } from '../../construtos';
 import { RetornoInterpretador } from '../../interfaces/retornos/retorno-interpretador';
 import { ErroInterpretador } from '../erro-interpretador';
@@ -64,6 +64,10 @@ export class InterpretadorEguaClassico implements InterpretadorInterface {
         carregarBibliotecaGlobal(this, this.pilhaEscoposExecucao);
     }
 
+    visitarExpressaoLeia(expressao: Leia) {
+        throw new Error('Método não implementado.');
+    }
+
     visitarExpressaoLiteral(expressao: Literal) {
         return expressao.valor;
     }
@@ -448,7 +452,7 @@ export class InterpretadorEguaClassico implements InterpretadorInterface {
     }
 
     visitarExpressaoEscolha(declaracao: Escolha) {
-        let condicaoEscolha = this.avaliar(declaracao.condicao);
+        let condicaoEscolha = this.avaliar(declaracao.identificadorOuLiteral);
         let caminhos = declaracao.caminhos;
         let caminhoPadrao = declaracao.caminhoPadrao;
 
diff --git a/fontes/interpretador/interpretador.ts b/fontes/interpretador/interpretador.ts
index 293bacf8..cf80142d 100644
--- a/fontes/interpretador/interpretador.ts
+++ b/fontes/interpretador/interpretador.ts
@@ -1,7 +1,7 @@
 import * as caminho from 'path';
 import hrtime from 'browser-process-hrtime';
 
-import tiposDeSimbolos from '../tipos-de-simbolos';
+import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
 
 import { EspacoVariaveis } from '../espaco-variaveis';
 import carregarBibliotecaGlobal from '../bibliotecas/biblioteca-global';
@@ -26,6 +26,7 @@ import {
     Fazer,
     Funcao,
     Importar,
+    Leia,
     Para,
     Retorna,
     Se,
@@ -47,6 +48,7 @@ import {
     Construto,
     Literal,
     Super,
+    Variavel,
 } from '../construtos';
 import { ErroInterpretador } from './erro-interpretador';
 import { RetornoInterpretador } from '../interfaces/retornos/retorno-interpretador';
@@ -106,6 +108,15 @@ export class Interpretador implements InterpretadorInterface {
         carregarBibliotecaGlobal(this, this.pilhaEscoposExecucao);
     }
 
+    /**
+     * Execução da leitura de valores da entrada configurada no
+     * início da aplicação.
+     * @param expressao 
+     */
+    visitarExpressaoLeia(expressao: Leia) {
+        throw new Error('Método não implementado.');
+    }
+
     /**
      * Retira a interpolação de um texto.
      * @param {texto} texto O texto
@@ -513,7 +524,7 @@ export class Interpretador implements InterpretadorInterface {
         return this.pilhaEscoposExecucao.obterVariavel(simbolo);
     }
 
-    visitarExpressaoDeVariavel(expressao: any): any {
+    visitarExpressaoDeVariavel(expressao: Variavel): any {
         return this.procurarVariavel(expressao.simbolo);
     }
 
@@ -621,7 +632,7 @@ export class Interpretador implements InterpretadorInterface {
     }
 
     visitarExpressaoEscolha(declaracao: Escolha): any {
-        let condicaoEscolha = this.avaliar(declaracao.condicao);
+        let condicaoEscolha = this.avaliar(declaracao.identificadorOuLiteral);
         let caminhos = declaracao.caminhos;
         let caminhoPadrao = declaracao.caminhoPadrao;
 
diff --git a/fontes/lexador/dialetos/lexador-egua-classico.ts b/fontes/lexador/dialetos/lexador-egua-classico.ts
index e2de520a..5ddd8b7e 100644
--- a/fontes/lexador/dialetos/lexador-egua-classico.ts
+++ b/fontes/lexador/dialetos/lexador-egua-classico.ts
@@ -1,5 +1,5 @@
 import { LexadorInterface, SimboloInterface } from '../../interfaces';
-import tiposDeSimbolos from '../../tipos-de-simbolos';
+import tiposDeSimbolos from '../../tipos-de-simbolos/delegua';
 import { Simbolo } from '../simbolo';
 import palavrasReservadas from '../palavras-reservadas';
 import { ErroLexador } from '../erro-lexador';
diff --git a/fontes/lexador/dialetos/lexador-eguap.ts b/fontes/lexador/dialetos/lexador-eguap.ts
index 940cf88f..a4607a91 100644
--- a/fontes/lexador/dialetos/lexador-eguap.ts
+++ b/fontes/lexador/dialetos/lexador-eguap.ts
@@ -1,7 +1,7 @@
 import hrtime from 'browser-process-hrtime';
 
 import { LexadorInterface, SimboloInterface } from "../../interfaces";
-import tiposDeSimbolos from "./tipos-de-simbolos-eguap";
+import tiposDeSimbolos from "../../tipos-de-simbolos/eguap";
 import { Simbolo } from "../simbolo";
 import palavrasReservadas from "../palavras-reservadas";
 import { ErroLexador } from "../erro-lexador";
diff --git a/fontes/lexador/dialetos/lexador-visualg.ts b/fontes/lexador/dialetos/lexador-visualg.ts
new file mode 100644
index 00000000..2cba0a96
--- /dev/null
+++ b/fontes/lexador/dialetos/lexador-visualg.ts
@@ -0,0 +1,237 @@
+import { RetornoLexador } from "../../interfaces/retornos";
+import { LexadorBaseLinhaUnica } from "../lexador-base-linha-unica";
+import { ErroLexador } from "../erro-lexador";
+
+import tiposDeSimbolos from "../../tipos-de-simbolos/visualg";
+import palavrasReservadas from "./palavras-reservadas/visualg";
+import { Simbolo } from "../simbolo";
+
+export class LexadorVisuAlg extends LexadorBaseLinhaUnica {
+
+    analisarNumero(): void {
+        while (this.eDigito(this.simboloAtual())) {
+            this.avancar();
+        }
+
+        if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
+            this.avancar();
+
+            while (this.eDigito(this.simboloAtual())) {
+                this.avancar();
+            }
+        }
+
+        const numeroCompleto = this.codigo.substring(
+            this.inicioSimbolo,
+            this.atual
+        );
+        this.adicionarSimbolo(
+            tiposDeSimbolos.NUMERO,
+            parseFloat(numeroCompleto)
+        );
+    }
+    
+    analisarTexto(delimitador: string): void {
+        while (this.simboloAtual() !== delimitador && !this.eFinalDoCodigo()) {
+            this.avancar();
+        }
+
+        if (this.eFinalDoCodigo()) {
+            this.erros.push({
+                linha: this.linha + 1,
+                caractere: this.simboloAnterior(),
+                mensagem: 'Caractere não finalizado.',
+            } as ErroLexador);
+            return;
+        }
+
+        const valor = this.codigo.substring(
+            this.inicioSimbolo + 1,
+            this.atual
+        );
+        this.adicionarSimbolo(tiposDeSimbolos.CARACTERE, valor);
+    }
+
+    /**
+     * Identificação de palavra-chave. 
+     * Palavras-chaves em VisuAlg não são sensíveis a tamanho de caixa
+     * (caracteres maiúsculos e minúsculos são equivalentes).
+     */
+    identificarPalavraChave(): void {
+        while (this.eAlfabetoOuDigito(this.simboloAtual())) {
+            this.avancar();
+        }
+
+        const codigo = this.codigo.substring(this.inicioSimbolo, this.atual).toLowerCase();
+        if (codigo in palavrasReservadas) {
+            this.adicionarSimbolo(palavrasReservadas[codigo]);
+        } else {
+            this.adicionarSimbolo(tiposDeSimbolos.IDENTIFICADOR, codigo);
+        }
+    }
+
+    adicionarSimbolo(tipo: string, literal: any = null): void {
+        const texto: string = this.codigo[this.linha].substring(
+            this.inicioSimbolo,
+            this.atual
+        );
+        this.simbolos.push(
+            new Simbolo(
+                tipo,
+                literal || texto,
+                literal,
+                this.linha + 1,
+                -1
+            )
+        );
+    }
+
+    avancarParaProximaLinha(): void {
+        this.linha++;
+        this.atual = 0;
+    }
+
+    analisarToken(): void {
+        const caractere = this.simboloAtual();
+
+        switch (caractere) {
+            case '(':
+                this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_ESQUERDO);
+                this.avancar();
+                break;
+            case ')':
+                this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_DIREITO);
+                this.avancar();
+                break;
+            case ":":
+                this.adicionarSimbolo(tiposDeSimbolos.DOIS_PONTOS);
+                this.avancar();
+                break;
+            case '<':
+                this.avancar();
+                switch (this.simboloAtual()) {
+                    case '-':
+                        this.adicionarSimbolo(tiposDeSimbolos.SETA_ATRIBUICAO);
+                        this.avancar();
+                        break;
+                    case '=':
+                        this.adicionarSimbolo(tiposDeSimbolos.MENOR_IGUAL);
+                        this.avancar();
+                        break;
+                    case '>':
+                        this.adicionarSimbolo(tiposDeSimbolos.DIFERENTE);
+                        this.avancar();
+                        break;
+                    default:
+                        this.adicionarSimbolo(tiposDeSimbolos.MENOR);
+                        break;
+                }
+
+                break;
+            case '>':
+                this.avancar();
+                if (this.simboloAtual() === '=') {
+                    this.adicionarSimbolo(tiposDeSimbolos.MAIOR_IGUAL);
+                    this.avancar();
+                } else {
+                    this.adicionarSimbolo(tiposDeSimbolos.MAIOR);
+                }
+                break;
+            case '=':
+                this.adicionarSimbolo(tiposDeSimbolos.IGUAL);
+                this.avancar();
+                break;
+            case ',':
+                this.adicionarSimbolo(tiposDeSimbolos.VIRGULA);
+                this.avancar();
+                break;
+            case '-':
+                this.adicionarSimbolo(tiposDeSimbolos.SUBTRACAO);
+                this.avancar();
+                break;
+            case '+':
+                this.adicionarSimbolo(tiposDeSimbolos.ADICAO);
+                this.avancar();
+                break;
+            case '%':
+                this.adicionarSimbolo(tiposDeSimbolos.MODULO);
+                this.avancar();
+                break;
+            case '*':
+                this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO);
+                this.avancar();
+                break;
+            case '/':
+                this.avancar();
+                switch (this.simboloAtual()) {
+                    case '/':
+                        this.avancarParaProximaLinha();
+                        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 '\n':
+                this.adicionarSimbolo(tiposDeSimbolos.QUEBRA_LINHA);
+                this.avancar();
+                break;
+
+            case '"':
+                this.avancar();
+                this.analisarTexto('"');
+                this.avancar();
+                break;
+            case "'":
+                this.avancar();
+                this.analisarTexto("'");
+                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 = -1): RetornoLexador {
+        this.erros = [];
+        this.simbolos = [];
+        this.inicioSimbolo = 0;
+        this.atual = 0;
+        this.linha = 1;
+
+        // Em VisuAlg, quebras de linha são relevantes na avaliação sintática. 
+        // Portanto, o Lexador precisa trabalhar com uma linha só.
+        this.codigo = codigo.join('\n') || '';
+
+        while (!this.eFinalDoCodigo()) {
+            this.inicioSimbolo = this.atual;
+            this.analisarToken();
+        }
+
+        return { 
+            simbolos: this.simbolos,
+            erros: this.erros
+        } as RetornoLexador;
+    }
+}
\ No newline at end of file
diff --git a/fontes/lexador/dialetos/palavras-reservadas/visualg.ts b/fontes/lexador/dialetos/palavras-reservadas/visualg.ts
new file mode 100644
index 00000000..3d82906f
--- /dev/null
+++ b/fontes/lexador/dialetos/palavras-reservadas/visualg.ts
@@ -0,0 +1,27 @@
+import tiposDeSimbolos from "../../../tipos-de-simbolos/visualg";
+
+export default {
+    algoritmo: tiposDeSimbolos.ALGORITMO,
+    ate: tiposDeSimbolos.ATE,
+    caractere: tiposDeSimbolos.CARACTERE,
+    caso: tiposDeSimbolos.CASO,
+    de: tiposDeSimbolos.DE,
+    enquanto: tiposDeSimbolos.ENQUANTO,
+    escolha: tiposDeSimbolos.ESCOLHA,
+    escreva: tiposDeSimbolos.ESCREVA,
+    escreval: tiposDeSimbolos.ESCREVA_LINHA,
+    faca: tiposDeSimbolos.FACA,
+    fimalgoritmo: tiposDeSimbolos.FIM_ALGORITMO,
+    fimenquanto: tiposDeSimbolos.FIM_ENQUANTO,
+    fimescolha: tiposDeSimbolos.FIM_ESCOLHA,
+    fimfuncao: tiposDeSimbolos.FIM_FUNCAO,
+    fimpara: tiposDeSimbolos.FIM_PARA,
+    funcao: tiposDeSimbolos.FUNCAO,
+    inicio: tiposDeSimbolos.INICIO,
+    inteiro: tiposDeSimbolos.INTEIRO,
+    leia: tiposDeSimbolos.LEIA,
+    outrocaso: tiposDeSimbolos.OUTRO_CASO,
+    para: tiposDeSimbolos.PARA,
+    repita: tiposDeSimbolos.REPITA,
+    var: tiposDeSimbolos.VAR
+}
diff --git a/fontes/lexador/lexador-base-linha-unica.ts b/fontes/lexador/lexador-base-linha-unica.ts
new file mode 100644
index 00000000..aece3948
--- /dev/null
+++ b/fontes/lexador/lexador-base-linha-unica.ts
@@ -0,0 +1,131 @@
+import { LexadorInterface, SimboloInterface } from "../interfaces";
+import { RetornoLexador } from "../interfaces/retornos";
+import { ErroLexador } from "./erro-lexador";
+import { Simbolo } from "./simbolo";
+
+export abstract class LexadorBaseLinhaUnica implements LexadorInterface {
+    simbolos: SimboloInterface[];
+    codigo: string;
+    inicioSimbolo: number;
+    atual: number;
+    linha: number;
+    erros: ErroLexador[];
+
+    constructor() {
+        this.simbolos = [];
+        this.erros = [];
+
+        this.inicioSimbolo = 0;
+        this.atual = 0;
+        this.linha = 0;
+    }
+
+    eDigito(caractere: string): boolean {
+        return caractere >= '0' && caractere <= '9';
+    }
+
+    eAlfabeto(caractere: string): boolean {
+        const acentuacoes = [
+            'á',
+            'Á',
+            'ã',
+            'Ã',
+            'â',
+            'Â',
+            'à',
+            'À',
+            'é',
+            'É',
+            'ê',
+            'Ê',
+            'í',
+            'Í',
+            'ó',
+            'Ó',
+            'õ',
+            'Õ',
+            'ô',
+            'Ô',
+            'ú',
+            'Ú',
+            'ç',
+            'Ç',
+            '_',
+        ];
+
+        return (
+            (caractere >= 'a' && caractere <= 'z') ||
+            (caractere >= 'A' && caractere <= 'Z') ||
+            acentuacoes.includes(caractere)
+        );
+    }
+
+    eAlfabetoOuDigito(caractere: string): boolean {
+        return this.eDigito(caractere) || this.eAlfabeto(caractere);
+    }
+
+    eFinalDoCodigo(): boolean {
+        return this.atual >= this.codigo.length;
+    }
+
+    eFinalDaLinha(): boolean {
+        if (this.codigo.length === this.linha) {
+            return true;
+        }
+        return this.atual >= this.codigo[this.linha].length;
+    }
+
+    /**
+     * Indica se o código está na última linha.
+     * @returns Verdadeiro se contador de linhas está na última linha.
+     *          Falso caso contrário.
+     */
+     eUltimaLinha(): boolean {
+        return this.linha >= this.codigo.length - 1;
+    }
+    
+    avancar(): string {
+        this.atual += 1;
+        return this.codigo[this.atual - 1];
+    }
+
+    adicionarSimbolo(tipo: any, literal: any): void {
+        const texto: string = this.codigo[this.linha].substring(
+            this.inicioSimbolo,
+            this.atual
+        );
+        this.simbolos.push(
+            new Simbolo(
+                tipo,
+                literal || texto,
+                literal,
+                this.linha + 1,
+                -1
+            )
+        );
+    }
+
+    simboloAtual(): string {
+        if (this.eFinalDoCodigo()) return '\0';
+        return this.codigo.charAt(this.atual);
+    }
+
+    proximoSimbolo(): string {
+        if (this.atual + 1 >= this.codigo.length) return '\0';
+        return this.codigo.charAt(this.atual + 1);
+    }
+
+    simboloAnterior(): string {
+        return this.codigo.charAt(this.atual - 1);
+    }
+
+    abstract analisarTexto(delimitador: string): void;
+
+    abstract analisarNumero(): void;
+
+    abstract identificarPalavraChave(): void;
+
+    abstract analisarToken(): void;
+
+    abstract mapear(codigo: string[], hashArquivo: number): RetornoLexador;
+}
\ No newline at end of file
diff --git a/fontes/lexador/lexador.ts b/fontes/lexador/lexador.ts
index ba44e392..3b43c9c8 100644
--- a/fontes/lexador/lexador.ts
+++ b/fontes/lexador/lexador.ts
@@ -1,9 +1,9 @@
 import hrtime from 'browser-process-hrtime';
-import { LexadorInterface, SimboloInterface } from "../interfaces";
-import tiposDeSimbolos from "../tipos-de-simbolos";
-import { ErroLexador } from "./erro-lexador";
+import { LexadorInterface, SimboloInterface } from '../interfaces';
+import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
+import { ErroLexador } from './erro-lexador';
 import palavrasReservadas from './palavras-reservadas';
-import { RetornoLexador } from "../interfaces/retornos/retorno-lexador";
+import { RetornoLexador } from '../interfaces/retornos/retorno-lexador';
 import { Simbolo } from './simbolo';
 
 /**
@@ -79,7 +79,7 @@ export class Lexador implements LexadorInterface {
     }
 
     eFinalDaLinha(): boolean {
-        if(this.codigo.length === this.linha){
+        if (this.codigo.length === this.linha) {
             return true;
         }
         return this.atual >= this.codigo[this.linha].length;
@@ -95,8 +95,10 @@ export class Lexador implements LexadorInterface {
     }
 
     eFinalDoCodigo(): boolean {
-        return this.eUltimaLinha() && 
-            this.codigo[this.codigo.length - 1].length <= this.atual;
+        return (
+            this.eUltimaLinha() &&
+            this.codigo[this.codigo.length - 1].length <= this.atual
+        );
     }
 
     avancar(): void {
@@ -113,7 +115,15 @@ export class Lexador implements LexadorInterface {
             this.inicioSimbolo,
             this.atual
         );
-        this.simbolos.push(new Simbolo(tipo, literal || texto, literal, this.linha + 1, this.hashArquivo));
+        this.simbolos.push(
+            new Simbolo(
+                tipo,
+                literal || texto,
+                literal,
+                this.linha + 1,
+                this.hashArquivo
+            )
+        );
     }
 
     simboloAtual(): string {
@@ -143,7 +153,7 @@ export class Lexador implements LexadorInterface {
             this.erros.push({
                 linha: this.linha + 1,
                 caractere: this.simboloAnterior(),
-                mensagem: 'Texto não finalizado.'
+                mensagem: 'Texto não finalizado.',
             } as ErroLexador);
             return;
         }
@@ -196,7 +206,7 @@ export class Lexador implements LexadorInterface {
     }
 
     encontrarFimComentarioAsterisco(): void {
-        while (!this.eFinalDoCodigo()) { 
+        while (!this.eFinalDoCodigo()) {
             this.avancar();
             if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
                 this.avancar();
@@ -251,7 +261,7 @@ export class Lexador implements LexadorInterface {
                 } else {
                     this.adicionarSimbolo(tiposDeSimbolos.SUBTRACAO);
                 }
-                
+
                 break;
             case '+':
                 this.inicioSimbolo = this.atual;
@@ -262,13 +272,13 @@ export class Lexador implements LexadorInterface {
                 } else {
                     this.adicionarSimbolo(tiposDeSimbolos.ADICAO);
                 }
-                
+
                 break;
             case ':':
                 this.adicionarSimbolo(tiposDeSimbolos.DOIS_PONTOS);
                 this.avancar();
                 break;
-            
+
             case '%':
                 this.inicioSimbolo = this.atual;
                 this.avancar();
@@ -281,7 +291,7 @@ export class Lexador implements LexadorInterface {
                         this.adicionarSimbolo(tiposDeSimbolos.MODULO);
                         break;
                 }
-                
+
                 break;
             case '*':
                 this.inicioSimbolo = this.atual;
@@ -293,7 +303,9 @@ export class Lexador implements LexadorInterface {
                         break;
                     case '=':
                         this.avancar();
-                        this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO_IGUAL);
+                        this.adicionarSimbolo(
+                            tiposDeSimbolos.MULTIPLICACAO_IGUAL
+                        );
                         break;
                     default:
                         this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO);
@@ -309,7 +321,7 @@ export class Lexador implements LexadorInterface {
                 } else {
                     this.adicionarSimbolo(tiposDeSimbolos.NEGACAO);
                 }
-                
+
                 break;
             case '=':
                 this.avancar();
@@ -319,7 +331,7 @@ export class Lexador implements LexadorInterface {
                 } else {
                     this.adicionarSimbolo(tiposDeSimbolos.IGUAL);
                 }
-                
+
                 break;
 
             case '&':
@@ -418,7 +430,7 @@ export class Lexador implements LexadorInterface {
                     this.erros.push({
                         linha: this.linha + 1,
                         caractere: caractere,
-                        mensagem: 'Caractere inesperado.'
+                        mensagem: 'Caractere inesperado.',
                     } as ErroLexador);
                     this.avancar();
                 }
@@ -443,12 +455,16 @@ export class Lexador implements LexadorInterface {
 
         if (this.performance) {
             const deltaMapeamento: [number, number] = hrtime(inicioMapeamento);
-            console.log(`[Lexador] Tempo para mapeamento: ${deltaMapeamento[0] * 1e9 + deltaMapeamento[1]}ns`);
+            console.log(
+                `[Lexador] Tempo para mapeamento: ${
+                    deltaMapeamento[0] * 1e9 + deltaMapeamento[1]
+                }ns`
+            );
         }
-        
-        return { 
+
+        return {
             simbolos: this.simbolos,
-            erros: this.erros
+            erros: this.erros,
         } as RetornoLexador;
     }
 }
diff --git a/fontes/lexador/palavras-reservadas.ts b/fontes/lexador/palavras-reservadas.ts
index 05439f1f..81c197b3 100644
--- a/fontes/lexador/palavras-reservadas.ts
+++ b/fontes/lexador/palavras-reservadas.ts
@@ -1,4 +1,4 @@
-import tiposDeSimbolos from "../tipos-de-simbolos";
+import tiposDeSimbolos from "../tipos-de-simbolos/delegua";
 
 export default {    
     e: tiposDeSimbolos.E,
diff --git a/fontes/tipos-de-simbolos/comum.ts b/fontes/tipos-de-simbolos/comum.ts
new file mode 100644
index 00000000..8baa87df
--- /dev/null
+++ b/fontes/tipos-de-simbolos/comum.ts
@@ -0,0 +1,17 @@
+export default {
+    ADICAO: "ADICAO",
+    DIFERENTE: "DIFERENTE",
+    DIVISAO: "DIVISAO",
+    E: "E",
+    IDENTIFICADOR: "IDENTIFICADOR",
+    IGUAL: "IGUAL",
+    MAIOR: "MAIOR",
+    MAIOR_IGUAL: "MAIOR_IGUAL",
+    MENOR: "MENOR",
+    MENOR_IGUAL: "MENOR_IGUAL",
+    MODULO: "MODULO",
+    MULTIPLICACAO: "MULTIPLICACAO",
+    NEGACAO: "NEGACAO",
+    OU: "OU",
+    SUBTRACAO: "SUBTRACAO"
+}
\ No newline at end of file
diff --git a/fontes/tipos-de-simbolos.ts b/fontes/tipos-de-simbolos/delegua.ts
similarity index 100%
rename from fontes/tipos-de-simbolos.ts
rename to fontes/tipos-de-simbolos/delegua.ts
diff --git a/fontes/lexador/dialetos/tipos-de-simbolos-eguap.ts b/fontes/tipos-de-simbolos/eguap.ts
similarity index 100%
rename from fontes/lexador/dialetos/tipos-de-simbolos-eguap.ts
rename to fontes/tipos-de-simbolos/eguap.ts
diff --git a/fontes/tipos-de-simbolos/visualg.ts b/fontes/tipos-de-simbolos/visualg.ts
new file mode 100644
index 00000000..e6addbe4
--- /dev/null
+++ b/fontes/tipos-de-simbolos/visualg.ts
@@ -0,0 +1,46 @@
+export default {
+    ADICAO: "ADICAO",
+    ALGORITMO: "ALGORITMO",
+    ATE: "ATE",
+    CARACTERE: "CARACTERE",
+    CASO: "CASO",
+    DE: "DE",
+    DIFERENTE: "DIFERENTE",
+    DIVISAO: "DIVISAO",
+    DOIS_PONTOS: "DOIS_PONTOS",
+    ENQUANTO: "ENQUANTO",
+    ESCOLHA: "ESCOLHA",
+    ESCREVA: "ESCREVA",
+    ESCREVA_LINHA: "ESCREVA_LINHA",
+    FACA: "FACA",
+    FIM_ALGORITMO: "FIM_ALGORITMO",
+    FIM_ENQUANTO: "FIM_ENQUANTO",
+    FIM_ESCOLHA: "FIM_ESCOLHA",
+    FIM_FUNCAO: "FIM_FUNCAO",
+    FIM_PARA: "FIM_PARA",
+    FUNCAO: "FUNCAO",
+    IDENTIFICADOR: "IDENTIFICADOR",
+    IGUAL: "IGUAL",
+    INICIO: "INICIO",
+    INTEIRO: "INTEIRO",
+    LEIA: "LEIA",
+    MAIOR: "MAIOR",
+    MAIOR_IGUAL: "MAIOR_IGUAL",
+    MENOR: "MENOR",
+    MENOR_IGUAL: "MENOR_IGUAL",
+    MODULO: "MODULO",
+    MULTIPLICACAO: "MULTIPLICACAO",
+    NEGACAO: "NEGACAO",
+    NUMERO: "NUMERO",
+    OUTRO_CASO: "OUTRO_CASO",
+    PARA: "PARA",
+    PASSO: "PASSO",
+    PARENTESE_DIREITO: "PARENTESE_DIREITO",
+    PARENTESE_ESQUERDO: "PARENTESE_ESQUERDO",
+    REPITA: "REPITA",
+    SETA_ATRIBUICAO: "SETA_ATRIBUICAO",
+    SUBTRACAO: "SUBTRACAO",
+    QUEBRA_LINHA: "QUEBRA_LINHA",
+    VAR: "VAR",
+    VIRGULA: "VIRGULA"
+}
\ No newline at end of file


Test patch:
diff --git a/testes/avaliador-sintatico.test.ts b/testes/avaliador-sintatico.test.ts
index 5e3dcd69..70d17215 100644
--- a/testes/avaliador-sintatico.test.ts
+++ b/testes/avaliador-sintatico.test.ts
@@ -1,5 +1,4 @@
 import { Delegua } from "../fontes/delegua";
-import { RetornoLexador } from "../fontes/interfaces/retornos/retorno-lexador";
 
 describe('Avaliador sintático', () => {
     describe('analisar()', () => {
diff --git a/testes/egua-classico/avaliador-sintatico.test.ts b/testes/egua-classico/avaliador-sintatico.test.ts
index 10a16139..1d35bb08 100644
--- a/testes/egua-classico/avaliador-sintatico.test.ts
+++ b/testes/egua-classico/avaliador-sintatico.test.ts
@@ -3,7 +3,11 @@ import { RetornoLexador } from "../../fontes/interfaces/retornos/retorno-lexador
 
 describe('Avaliador sintático (Égua Clássico)', () => {
     describe('analisar()', () => {
-        const delegua = new Delegua('egua');
+        let delegua: Delegua;
+
+        beforeEach(() => {
+            delegua = new Delegua('egua');
+        });
 
         it('Sucesso - Olá Mundo', () => {
             const retornoLexador = delegua.lexador.mapear(["escreva('Olá mundo');"], -1);
diff --git a/testes/exemplos/dialetos/visualg/ola-mundo.alg b/testes/exemplos/dialetos/visualg/ola-mundo.alg
new file mode 100644
index 00000000..2a29f1ac
--- /dev/null
+++ b/testes/exemplos/dialetos/visualg/ola-mundo.alg
@@ -0,0 +1,4 @@
+algoritmo "ola-mundo"
+inicio
+escreva("Ola mundo")
+fimalgoritmo
\ No newline at end of file
diff --git a/testes/exemplos/dialetos/visualg/times.alg b/testes/exemplos/dialetos/visualg/times.alg
new file mode 100644
index 00000000..c4215212
--- /dev/null
+++ b/testes/exemplos/dialetos/visualg/times.alg
@@ -0,0 +1,14 @@
+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
\ No newline at end of file
diff --git a/testes/exemplos/dialetos/visualg/um-a-10.alg b/testes/exemplos/dialetos/visualg/um-a-10.alg
new file mode 100644
index 00000000..ccb2363e
--- /dev/null
+++ b/testes/exemplos/dialetos/visualg/um-a-10.alg
@@ -0,0 +1,7 @@
+algoritmo "Numeros de 1 a 10"
+var j: inteiro
+inicio
+para j de 1 ate 10 faca
+   escreva (j)
+fimpara
+fimalgoritmo
\ No newline at end of file
diff --git a/testes/lexador.test.ts b/testes/lexador.test.ts
index 095cac04..e11787fe 100644
--- a/testes/lexador.test.ts
+++ b/testes/lexador.test.ts
@@ -1,5 +1,5 @@
 import { Delegua } from '../fontes/delegua';
-import tiposDeSimbolos from '../fontes/tipos-de-simbolos';
+import tiposDeSimbolos from '../fontes/tipos-de-simbolos/delegua';
 
 describe('Lexador', () => {
     describe('mapear()', () => {
diff --git a/testes/visualg/avaliador-sintatico.test.ts b/testes/visualg/avaliador-sintatico.test.ts
new file mode 100644
index 00000000..39a5c368
--- /dev/null
+++ b/testes/visualg/avaliador-sintatico.test.ts
@@ -0,0 +1,124 @@
+import { Delegua } from "../../fontes/delegua";
+
+describe('Avaliador sintático (VisuAlg)', () => {
+    describe('analisar()', () => {
+        let delegua: Delegua;
+
+        beforeEach(() => {
+            delegua = new Delegua('visualg');
+        });
+
+        it('Sucesso - Olá Mundo', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                'algoritmo "olá-mundo"',
+                'inicio',
+                'escreva("Olá mundo")',
+                'fimalgoritmo'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
+        });
+
+        it('Sucesso - Enquanto', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                'algoritmo "Números de 1 a 10 (com enquanto...faca)"',
+                'var j: inteiro',
+                'inicio',
+                'j <- 1',
+                'enquanto j <= 10 faca',
+                '   escreva (j)',
+                '   j <- j + 1',
+                'fimenquanto',
+                'fimalgoritmo'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+        });
+
+        it('Sucesso - Escolha', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                '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'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+        });
+
+        it('Sucesso - Função', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                'Algoritmo "exemplo-funcoes"',
+                'Var',
+                '   n: inteiro',
+                '   m: inteiro',
+                '   res: inteiro',
+                'Inicio',
+                '   funcao soma: inteiro',
+                '   var aux: inteiro',
+                '   inicio',
+                '      aux <- n + m',
+                '      retorne aux',
+                '   fimfuncao',
+                '   n <- 4',
+                '   m <- -9',
+                '   res <- soma',
+                '   escreva(res)',
+                'Fimalgoritmo'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(8);
+        });
+
+        it('Sucesso - Para', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                'algoritmo "Numeros de 1 a 10"',
+                'var j: inteiro',
+                'inicio',
+                '    para j de 1 ate 10 faca',
+                '        escreva (j)',
+                '    fimpara',
+                'fimalgoritmo'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
+        });
+
+        it('Sucesso - Repita', () => {
+            const retornoLexador = delegua.lexador.mapear([
+                'algoritmo "Números de 1 a 10 (com repita)"',
+                'var j: inteiro',
+                'inicio',
+                'j <- 1',
+                'repita',
+                '   escreva (j)',
+                '   j <- j + 1',
+                'ate j > 10',
+                'fimalgoritmo'
+            ], -1);
+            const retornoAvaliadorSintatico = delegua.avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+        });
+    });
+});
diff --git a/testes/visualg/lexador.test.ts b/testes/visualg/lexador.test.ts
new file mode 100644
index 00000000..19f43ec3
--- /dev/null
+++ b/testes/visualg/lexador.test.ts
@@ -0,0 +1,74 @@
+import { Delegua } from "../../fontes/delegua";
+import tiposDeSimbolos from "../../fontes/tipos-de-simbolos/visualg"
+
+describe('Lexador (VisuAlg)', () => {
+    describe('mapear()', () => {
+        let delegua: Delegua;
+
+        beforeEach(() => {
+            delegua = new Delegua('visualg');
+        });
+
+        describe('Cenários de sucesso', () => {
+            it('Sucesso - Código vazio', () => {
+                const resultado = delegua.lexador.mapear([''], -1);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado.simbolos).toHaveLength(0);
+            });
+
+            it('Sucesso - Ponto-e-vírgula, opcional', () => {
+                const resultado = delegua.lexador.mapear([';;;;;;;;;;;;;;;;;;;;;'], -1);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado.simbolos).toHaveLength(0);
+            });
+
+            it('Sucesso - estrutura mínima', () => {
+                const resultado = delegua.lexador.mapear([
+                    "algoritmo \"vazio\"",
+                    "var",
+                    "inicio",
+                    "fimalgoritmo"
+                ], -1);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado.simbolos).toHaveLength(8);
+                expect(resultado.simbolos).toEqual(
+                    expect.arrayContaining([
+                        expect.objectContaining({ tipo: tiposDeSimbolos.ALGORITMO }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.CARACTERE }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.QUEBRA_LINHA }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.VAR }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.QUEBRA_LINHA }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.INICIO }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.QUEBRA_LINHA }),
+                        // expect.objectContaining({ tipo: tiposDeSimbolos.ESCREVA }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.FIM_ALGORITMO })
+                    ])
+                );
+            });
+
+            it('Sucesso - Olá mundo', () => {
+                const resultado = delegua.lexador.mapear(
+                    [
+                        "algoritmo \"ola-mundo\"",
+                        "var",
+                        "a: inteiro",
+                        "inicio"
+                    ], -1);
+    
+                expect(resultado).toBeTruthy();
+                /* expect(resultado.simbolos).toHaveLength(4);
+                expect(resultado.simbolos).toEqual(
+                    expect.arrayContaining([
+                        expect.objectContaining({ tipo: tiposDeSimbolos.ESCREVA }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.PARENTESE_ESQUERDO }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.TEXTO }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.PARENTESE_DIREITO }),
+                    ])
+                ); */
+            });
+        });
+    });
+});