@@ -6,48 +6,132 @@ import {
66} from '../interfaces/retornos' ;
77import tiposDeSimbolos from '../tipos-de-simbolos' ;
88import { AvaliadorSintaticoBase } from './avaliador-sintatico-base' ;
9- import { InformacoesColuna } from './informacaoColuna ' ;
9+ import { Coluna } from '../construtos/coluna ' ;
1010
1111export class AvaliadorSintatico extends AvaliadorSintaticoBase {
1212 private avancar ( ) : void {
13- this . atual ++ ;
13+ if ( ! this . estaNoFinal ( ) ) {
14+ this . atual ++ ;
15+ }
1416 }
1517
16- private logicaColunas ( ) : InformacoesColuna {
17- return null ;
18+ private declaracaoCriacaoColuna ( ) : Coluna {
19+ // Nome
20+ const nomeDaColuna = this . consumir ( tiposDeSimbolos . IDENTIFICADOR ,
21+ 'Esperado identificador de nome de coluna em comando de criação de tabela.' ) ;
22+
23+ // Tipo de dados
24+ let tipoColuna = null ;
25+ let tamanhoColuna = null ;
26+ switch ( this . simbolos [ this . atual ] . tipo ) {
27+ case tiposDeSimbolos . INTEIRO :
28+ tipoColuna = tiposDeSimbolos . INTEIRO ;
29+ this . avancar ( ) ;
30+ break ;
31+ case tiposDeSimbolos . LOGICO :
32+ tipoColuna = tiposDeSimbolos . LOGICO ;
33+ this . avancar ( ) ;
34+ break ;
35+ case tiposDeSimbolos . TEXTO :
36+ tipoColuna = tiposDeSimbolos . TEXTO ;
37+ this . avancar ( ) ;
38+ if ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . PARENTESE_ESQUERDO ) ) {
39+ tamanhoColuna = this . consumir ( tiposDeSimbolos . NUMERO ,
40+ 'Esperado tamanho de texto de coluna em comando de criação de tabela.' ) ;
41+ this . consumir ( tiposDeSimbolos . PARENTESE_DIREITO ,
42+ 'Esperado parêntese direito após declaração de tamanho de coluna em comando de criação de tabela.' ) ;
43+ }
44+
45+ break ;
46+ default :
47+ throw this . erro ( this . simbolos [ this . atual ] ,
48+ 'Esperado tipo de dados válido na definição de coluna em comando de criação de tabela.' ) ;
49+ }
50+
51+ // Nulo/Não Nulo
52+ let nulo = true ;
53+ if ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . NAO , tiposDeSimbolos . NULO ) ) {
54+ const simboloAnterior = this . simbolos [ this . atual - 1 ] ;
55+ switch ( simboloAnterior . tipo ) {
56+ case tiposDeSimbolos . NAO :
57+ this . consumir ( tiposDeSimbolos . NULO ,
58+ 'Esperado palavra reservada "NULO" após palavra reservada "NÃO" em declaração de coluna em comando de criação de tabela.' ) ;
59+ nulo = false ;
60+ break ;
61+ case tiposDeSimbolos . NULO :
62+ default :
63+ break ;
64+ }
65+ }
66+
67+ // Chave primária?
68+ let chavePrimaria = false ;
69+ let autoIncremento = false ;
70+ if ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . CHAVE ) ) {
71+ switch ( this . simbolos [ this . atual ] . tipo ) {
72+ case tiposDeSimbolos . PRIMARIA :
73+ chavePrimaria = true ;
74+ this . avancar ( ) ;
75+ if ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . AUTO ) ) {
76+ this . consumir ( tiposDeSimbolos . INCREMENTO ,
77+ 'Esperado palavra reservada "INCREMENTO" após palavra reservada "AUTO" em declaração de coluna em comando de criação de tabela.' ) ;
78+ autoIncremento = true ;
79+ }
80+ break ;
81+ default :
82+ throw this . erro ( this . simbolos [ this . atual ] ,
83+ 'Esperado palavra reservada "PRIMARIA" após palavra reservada "CHAVE" na definição de coluna em comando de criação de tabela.' ) ;
84+ }
85+ }
86+
87+ return new Coluna ( nomeDaColuna . lexema , tipoColuna , tamanhoColuna , nulo , chavePrimaria , false ) ;
1888 }
1989
2090 private declaracaoCriar ( ) : Criar {
21- this . avancar ( ) ;
22- if ( this . verificaSeLexemaSimboloAtual ( 'TABELA' ) ) {
23- this . avancar ( ) ;
24- const nomeDaTabela = this . simbolos [ this . atual ] . lexema ;
25- this . avancar ( ) ;
26- if ( this . verificaSeLexemaSimboloAtual ( '(' ) ) {
27- this . consumir (
28- '(' ,
29- 'Esperado abrir parenteses após nome da tabela'
30- ) ;
31-
32- const colunas : InformacoesColuna [ ] = [ ] ;
33-
34- while ( ! this . verificaSeLexemaSimboloAtual ( ')' ) ) {
35- this . logicaColunas ( ) ;
36- this . avancar ( ) ;
37- }
91+ // Essa linha nunca deve retornar erro.
92+ this . consumir ( tiposDeSimbolos . CRIAR , 'Esperado palavra reservada "CRIAR".' ) ;
3893
39- return new Criar (
40- this . simbolos [ this . atual ] . linha ,
41- nomeDaTabela ,
42- colunas
43- ) ;
44- }
94+ switch ( this . simbolos [ this . atual ] . tipo ) {
95+ case 'TABELA' :
96+ default :
97+ return this . declaracaoCriarTabela ( ) ;
98+ }
99+ }
100+
101+ private declaracaoCriarTabela ( ) {
102+ // Essa linha nunca deve retornar erro.
103+ this . consumir ( tiposDeSimbolos . TABELA , 'Esperado palavra reservada "TABELA".' ) ;
104+
105+ const nomeDaTabela = this . consumir ( tiposDeSimbolos . IDENTIFICADOR ,
106+ 'Esperado identificador de nome de tabela após palavra reservada "TABELA".' ) ;
107+
108+ this . consumir ( tiposDeSimbolos . PARENTESE_ESQUERDO ,
109+ 'Esperado abertura de parênteses após nome da tabela' ) ;
110+
111+ const colunas : Coluna [ ] = [ ] ;
112+
113+ do {
114+ colunas . push ( this . declaracaoCriacaoColuna ( ) ) ;
45115 }
116+ while ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . VIRGULA ) ) ;
117+
118+ this . consumir ( tiposDeSimbolos . PARENTESE_DIREITO ,
119+ 'Esperado fechamento de parênteses após nome da tabela' ) ;
120+
121+ // Ponto-e-vírgula opcional.
122+ // TODO: trazer isso mais tarde.
123+ // this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_VIRGULA);
124+
125+ return new Criar (
126+ this . simbolos [ this . atual ] . linha ,
127+ nomeDaTabela . lexema ,
128+ colunas
129+ ) ;
46130 }
47131
48132 private declaracaoSelecionar ( ) {
49133 // Essa linha nunca deve retornar erro.
50- this . consumir ( tiposDeSimbolos . SELECIONAR , 'Esperado palavra reservada "SELECIONAR".' )
134+ this . consumir ( tiposDeSimbolos . SELECIONAR , 'Esperado palavra reservada "SELECIONAR".' ) ;
51135
52136 // Colunas
53137 let tudo = false ;
@@ -93,11 +177,14 @@ export class AvaliadorSintatico extends AvaliadorSintaticoBase {
93177
94178 const direita = this . simbolos [ this . atual ] ;
95179 this . avancar ( ) ;
96-
180+
97181 condicoes . push ( new Condicao ( esquerda , operador , direita . literal || direita . lexema ) ) ;
98182 } while ( this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . E ) ) ;
99183 }
100184
185+ // Ponto-e-vírgula opcional.
186+ this . verificarSeSimboloAtualEIgualA ( tiposDeSimbolos . PONTO_VIRGULA ) ;
187+
101188 return new Selecionar ( - 1 , nomeTabela . lexema , colunas , condicoes , tudo ) ;
102189 }
103190
0 commit comments