@designliquido/delegua 0.0.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/bin/delegua +1 -1
- package/bin/delegua.cmd +1 -1
- package/bin/package.json +51 -0
- package/index.js +27 -0
- package/index.js.map +1 -0
- package/package.json +10 -5
- package/src/ambiente.js +34 -38
- package/src/ambiente.js.map +1 -0
- package/src/avaliador-sintatico/dialetos/egua-classico.js +635 -0
- package/src/avaliador-sintatico/dialetos/egua-classico.js.map +1 -0
- package/src/avaliador-sintatico/dialetos/index.js +14 -0
- package/src/avaliador-sintatico/dialetos/index.js.map +1 -0
- package/src/avaliador-sintatico/index.js +635 -0
- package/src/avaliador-sintatico/index.js.map +1 -0
- package/src/avaliador-sintatico/parser-error.js +27 -0
- package/src/avaliador-sintatico/parser-error.js.map +1 -0
- package/src/bibliotecas/bibliotecaGlobal.js +97 -0
- package/src/bibliotecas/bibliotecaGlobal.js.map +1 -0
- package/src/bibliotecas/importarBiblioteca.js +32 -0
- package/src/bibliotecas/importarBiblioteca.js.map +1 -0
- package/src/construtos/assign-subscript.js +35 -0
- package/src/construtos/assign-subscript.js.map +1 -0
- package/src/construtos/atribuir.js +34 -0
- package/src/construtos/atribuir.js.map +1 -0
- package/src/construtos/binario.js +35 -0
- package/src/construtos/binario.js.map +1 -0
- package/src/construtos/call.js +35 -0
- package/src/construtos/call.js.map +1 -0
- package/src/construtos/conjunto.js +35 -0
- package/src/construtos/conjunto.js.map +1 -0
- package/src/construtos/dicionario.js +34 -0
- package/src/construtos/dicionario.js.map +1 -0
- package/src/construtos/expr.js +11 -0
- package/src/construtos/expr.js.map +1 -0
- package/src/construtos/funcao.js +34 -0
- package/src/construtos/funcao.js.map +1 -0
- package/src/construtos/get.js +34 -0
- package/src/construtos/get.js.map +1 -0
- package/src/construtos/grouping.js +33 -0
- package/src/construtos/grouping.js.map +1 -0
- package/src/construtos/index.js +31 -0
- package/src/construtos/index.js.map +1 -0
- package/src/construtos/isto.js +33 -0
- package/src/construtos/isto.js.map +1 -0
- package/src/construtos/literal.js +33 -0
- package/src/construtos/literal.js.map +1 -0
- package/src/construtos/logical.js +35 -0
- package/src/construtos/logical.js.map +1 -0
- package/src/construtos/subscript.js +35 -0
- package/src/construtos/subscript.js.map +1 -0
- package/src/construtos/super.js +34 -0
- package/src/construtos/super.js.map +1 -0
- package/src/construtos/unario.js +34 -0
- package/src/construtos/unario.js.map +1 -0
- package/src/construtos/variavel.js +33 -0
- package/src/construtos/variavel.js.map +1 -0
- package/src/construtos/vetor.js +33 -0
- package/src/construtos/vetor.js.map +1 -0
- package/src/declaracoes/index.js +249 -0
- package/src/declaracoes/index.js.map +1 -0
- package/src/delegua.js +110 -83
- package/src/delegua.js.map +1 -0
- package/src/estruturas/callable.js +15 -4
- package/src/estruturas/callable.js.map +1 -0
- package/src/estruturas/classe.js +44 -30
- package/src/estruturas/classe.js.map +1 -0
- package/src/estruturas/funcao-padrao.js +38 -0
- package/src/estruturas/funcao-padrao.js.map +1 -0
- package/src/estruturas/funcao.js +71 -52
- package/src/estruturas/funcao.js.map +1 -0
- package/src/estruturas/index.js +19 -0
- package/src/estruturas/index.js.map +1 -0
- package/src/estruturas/instancia.js +23 -22
- package/src/estruturas/instancia.js.map +1 -0
- package/src/estruturas/modulo.js +14 -8
- package/src/estruturas/modulo.js.map +1 -0
- package/src/excecoes/break-exception.js +27 -0
- package/src/excecoes/break-exception.js.map +1 -0
- package/src/excecoes/continue-exception.js +27 -0
- package/src/excecoes/continue-exception.js.map +1 -0
- package/src/excecoes/erro-em-tempo-de-execucao.js +31 -0
- package/src/excecoes/erro-em-tempo-de-execucao.js.map +1 -0
- package/src/excecoes/index.js +17 -0
- package/src/excecoes/index.js.map +1 -0
- package/src/excecoes/return-exception.js +30 -0
- package/src/excecoes/return-exception.js.map +1 -0
- package/src/interfaces/avaliador-sintatico-interface.js +3 -0
- package/src/interfaces/avaliador-sintatico-interface.js.map +1 -0
- package/src/interfaces/index.js +19 -0
- package/src/interfaces/index.js.map +1 -0
- package/src/interfaces/interpretador-interface.js +3 -0
- package/src/interfaces/interpretador-interface.js.map +1 -0
- package/src/interfaces/lexador-interface.js +3 -0
- package/src/interfaces/lexador-interface.js.map +1 -0
- package/src/interfaces/pilha-interface.js +3 -0
- package/src/interfaces/pilha-interface.js.map +1 -0
- package/src/interfaces/resolvedor-interface.js +3 -0
- package/src/interfaces/resolvedor-interface.js.map +1 -0
- package/src/interfaces/simbolo-interface.js +3 -0
- package/src/interfaces/simbolo-interface.js.map +1 -0
- package/src/interpretador/dialetos/egua-classico.js +656 -0
- package/src/interpretador/dialetos/egua-classico.js.map +1 -0
- package/src/interpretador/dialetos/index.js +14 -0
- package/src/interpretador/dialetos/index.js.map +1 -0
- package/src/interpretador/index.js +665 -0
- package/src/interpretador/index.js.map +1 -0
- package/src/lexador/dialetos/egua-classico.js +287 -0
- package/src/lexador/dialetos/egua-classico.js.map +1 -0
- package/src/lexador/dialetos/index.js +14 -0
- package/src/lexador/dialetos/index.js.map +1 -0
- package/src/lexador/index.js +287 -0
- package/src/lexador/index.js.map +1 -0
- package/src/resolvedor/Pilha.js +27 -0
- package/src/resolvedor/Pilha.js.map +1 -0
- package/src/resolvedor/ResolverError.js +29 -0
- package/src/resolvedor/ResolverError.js.map +1 -0
- package/src/resolvedor/dialetos/egua-classico.js +331 -0
- package/src/resolvedor/dialetos/egua-classico.js.map +1 -0
- package/src/resolvedor/dialetos/index.js +14 -0
- package/src/resolvedor/dialetos/index.js.map +1 -0
- package/src/resolvedor/index.js +331 -0
- package/src/resolvedor/index.js.map +1 -0
- package/src/tiposDeSimbolos.js +25 -23
- package/src/tiposDeSimbolos.js.map +1 -0
- package/src/web.js +64 -68
- package/src/web.js.map +1 -0
- package/.github/CONTRIBUTING.md +0 -0
- package/.github/workflows/principal.yml +0 -20
- package/.release-it.json +0 -8
- package/.vscode/launch.json +0 -29
- package/.vscode/settings.json +0 -3
- package/LICENSE +0 -21
- package/babel.config.js +0 -1
- package/indice.js +0 -14
- package/src/erro.js +0 -18
- package/src/estruturas/funcaoPadrao.js +0 -18
- package/src/expr.js +0 -228
- package/src/interpretador.js +0 -802
- package/src/lexer.js +0 -316
- package/src/lib/globalLib.js +0 -171
- package/src/lib/importStdlib.js +0 -32
- package/src/parser.js +0 -822
- package/src/resolver.js +0 -425
- package/src/stmt.js +0 -215
- package/testes/testes.egua +0 -630
package/src/parser.js
DELETED
|
@@ -1,822 +0,0 @@
|
|
|
1
|
-
const tiposDeSimbolos = require("./tiposDeSimbolos.js");
|
|
2
|
-
const Expr = require("./expr.js");
|
|
3
|
-
const Stmt = require("./stmt.js");
|
|
4
|
-
|
|
5
|
-
class ParserError extends Error { }
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* O avaliador sintático (Parser) é responsável por transformar os símbolos do Lexador em estruturas de alto nível.
|
|
9
|
-
* Essas estruturas de alto nível são as partes que executam lógica de programação de fato.
|
|
10
|
-
*/
|
|
11
|
-
module.exports = class Parser {
|
|
12
|
-
constructor(simbolos, Delegua) {
|
|
13
|
-
this.simbolos = simbolos;
|
|
14
|
-
this.Delegua = Delegua;
|
|
15
|
-
|
|
16
|
-
this.atual = 0;
|
|
17
|
-
this.ciclos = 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
sincronizar() {
|
|
21
|
-
this.avancar();
|
|
22
|
-
|
|
23
|
-
while (!this.estaNoFinal()) {
|
|
24
|
-
if (this.voltar().tipo === tiposDeSimbolos.SEMICOLON) return;
|
|
25
|
-
|
|
26
|
-
switch (this.peek().tipo) {
|
|
27
|
-
case tiposDeSimbolos.CLASSE:
|
|
28
|
-
case tiposDeSimbolos.FUNCAO:
|
|
29
|
-
case tiposDeSimbolos.VAR:
|
|
30
|
-
case tiposDeSimbolos.PARA:
|
|
31
|
-
case tiposDeSimbolos.SE:
|
|
32
|
-
case tiposDeSimbolos.ENQUANTO:
|
|
33
|
-
case tiposDeSimbolos.ESCREVA:
|
|
34
|
-
case tiposDeSimbolos.RETORNA:
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
this.avancar();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
erro(simbolo, mensagemDeErro) {
|
|
43
|
-
this.Delegua.erro(simbolo, mensagemDeErro);
|
|
44
|
-
return new ParserError();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
consumir(tipo, mensagemDeErro) {
|
|
48
|
-
if (this.verificar(tipo)) return this.avancar();
|
|
49
|
-
else throw this.erro(this.peek(), mensagemDeErro);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
verificar(tipo) {
|
|
53
|
-
if (this.estaNoFinal()) return false;
|
|
54
|
-
return this.peek().tipo === tipo;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
verificarProximo(tipo) {
|
|
58
|
-
if (this.estaNoFinal()) return false;
|
|
59
|
-
return this.simbolos[this.atual + 1].tipo === tipo;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
peek() {
|
|
63
|
-
return this.simbolos[this.atual];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
voltar() {
|
|
67
|
-
return this.simbolos[this.atual - 1];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
seek(posicao) {
|
|
71
|
-
return this.simbolos[this.atual + posicao];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
estaNoFinal() {
|
|
75
|
-
return this.peek().tipo === tiposDeSimbolos.EOF;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
avancar() {
|
|
79
|
-
if (!this.estaNoFinal()) this.atual += 1;
|
|
80
|
-
return this.voltar();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
match(...argumentos) {
|
|
84
|
-
for (let i = 0; i < argumentos.length; i++) {
|
|
85
|
-
const tipoAtual = argumentos[i];
|
|
86
|
-
if (this.verificar(tipoAtual)) {
|
|
87
|
-
this.avancar();
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
primario() {
|
|
96
|
-
if (this.match(tiposDeSimbolos.SUPER)) {
|
|
97
|
-
const palavraChave = this.voltar();
|
|
98
|
-
this.consumir(tiposDeSimbolos.DOT, "Esperado '.' após 'super'.");
|
|
99
|
-
const metodo = this.consumir(
|
|
100
|
-
tiposDeSimbolos.IDENTIFICADOR,
|
|
101
|
-
"Esperado nome do método da SuperClasse."
|
|
102
|
-
);
|
|
103
|
-
return new Expr.Super(palavraChave, metodo);
|
|
104
|
-
}
|
|
105
|
-
if (this.match(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
|
|
106
|
-
const valores = [];
|
|
107
|
-
if (this.match(tiposDeSimbolos.COLCHETE_DIREITO)) {
|
|
108
|
-
return new Expr.Array([]);
|
|
109
|
-
}
|
|
110
|
-
while (!this.match(tiposDeSimbolos.COLCHETE_DIREITO)) {
|
|
111
|
-
const valor = this.atribuir();
|
|
112
|
-
valores.push(valor);
|
|
113
|
-
if (this.peek().tipo !== tiposDeSimbolos.COLCHETE_DIREITO) {
|
|
114
|
-
this.consumir(
|
|
115
|
-
tiposDeSimbolos.COMMA,
|
|
116
|
-
"Esperado vírgula antes da próxima expressão."
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return new Expr.Array(valores);
|
|
121
|
-
}
|
|
122
|
-
if (this.match(tiposDeSimbolos.CHAVE_ESQUERDA)) {
|
|
123
|
-
const chaves = [];
|
|
124
|
-
const valores = [];
|
|
125
|
-
if (this.match(tiposDeSimbolos.CHAVE_DIREITA)) {
|
|
126
|
-
return new Expr.Dicionario([], []);
|
|
127
|
-
}
|
|
128
|
-
while (!this.match(tiposDeSimbolos.CHAVE_DIREITA)) {
|
|
129
|
-
let chave = this.atribuir();
|
|
130
|
-
this.consumir(
|
|
131
|
-
tiposDeSimbolos.COLON,
|
|
132
|
-
"Esperado ':' entre chave e valor."
|
|
133
|
-
);
|
|
134
|
-
let valor = this.atribuir();
|
|
135
|
-
|
|
136
|
-
chaves.push(chave);
|
|
137
|
-
valores.push(valor);
|
|
138
|
-
|
|
139
|
-
if (this.peek().tipo !== tiposDeSimbolos.CHAVE_DIREITA) {
|
|
140
|
-
this.consumir(
|
|
141
|
-
tiposDeSimbolos.COMMA,
|
|
142
|
-
"Esperado vírgula antes da próxima expressão."
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return new Expr.Dicionario(chaves, valores);
|
|
147
|
-
}
|
|
148
|
-
if (this.match(tiposDeSimbolos.FUNCAO)) return this.corpoDaFuncao("funcao");
|
|
149
|
-
if (this.match(tiposDeSimbolos.FALSO)) return new Expr.Literal(false);
|
|
150
|
-
if (this.match(tiposDeSimbolos.VERDADEIRO)) return new Expr.Literal(true);
|
|
151
|
-
if (this.match(tiposDeSimbolos.NULO)) return new Expr.Literal(null);
|
|
152
|
-
if (this.match(tiposDeSimbolos.ISTO)) return new Expr.Isto(this.voltar());
|
|
153
|
-
if (this.match(tiposDeSimbolos.NUMERO, tiposDeSimbolos.TEXTO)) {
|
|
154
|
-
return new Expr.Literal(this.voltar().literal);
|
|
155
|
-
}
|
|
156
|
-
if (this.match(tiposDeSimbolos.IDENTIFICADOR)) {
|
|
157
|
-
return new Expr.Variavel(this.voltar());
|
|
158
|
-
}
|
|
159
|
-
if (this.match(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
|
|
160
|
-
let expr = this.expressao();
|
|
161
|
-
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após a expressão.");
|
|
162
|
-
return new Expr.Grouping(expr);
|
|
163
|
-
}
|
|
164
|
-
if (this.match(tiposDeSimbolos.IMPORTAR)) return this.importStatement();
|
|
165
|
-
|
|
166
|
-
throw this.erro(this.peek(), "Esperado expressão.");
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
finalizarChamada(callee) {
|
|
170
|
-
const argumentos = [];
|
|
171
|
-
if (!this.verificar(tiposDeSimbolos.PARENTESE_DIREITO)) {
|
|
172
|
-
do {
|
|
173
|
-
if (argumentos.length >= 255) {
|
|
174
|
-
throw this.erro(this.peek(), "Não pode haver mais de 255 argumentos.");
|
|
175
|
-
}
|
|
176
|
-
argumentos.push(this.expressao());
|
|
177
|
-
} while (this.match(tiposDeSimbolos.COMMA));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const parenteseDireito = this.consumir(
|
|
181
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
182
|
-
"Esperado ')' após os argumentos."
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
return new Expr.Call(callee, parenteseDireito, argumentos);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
chamar() {
|
|
189
|
-
let expr = this.primario();
|
|
190
|
-
|
|
191
|
-
while (true) {
|
|
192
|
-
if (this.match(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
|
|
193
|
-
expr = this.finalizarChamada(expr);
|
|
194
|
-
} else if (this.match(tiposDeSimbolos.DOT)) {
|
|
195
|
-
let nome = this.consumir(
|
|
196
|
-
tiposDeSimbolos.IDENTIFICADOR,
|
|
197
|
-
"Esperado nome do método após '.'."
|
|
198
|
-
);
|
|
199
|
-
expr = new Expr.Get(expr, nome);
|
|
200
|
-
} else if (this.match(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
|
|
201
|
-
const indice = this.expressao();
|
|
202
|
-
let closeBracket = this.consumir(
|
|
203
|
-
tiposDeSimbolos.COLCHETE_DIREITO,
|
|
204
|
-
"Esperado ']' após escrita do indice."
|
|
205
|
-
);
|
|
206
|
-
expr = new Expr.Subscript(expr, indice, closeBracket);
|
|
207
|
-
} else {
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return expr;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
unario() {
|
|
216
|
-
if (this.match(tiposDeSimbolos.NEGACAO, tiposDeSimbolos.SUBTRACAO, tiposDeSimbolos.BIT_NOT)) {
|
|
217
|
-
const operador = this.voltar();
|
|
218
|
-
const direito = this.unario();
|
|
219
|
-
return new Expr.Unary(operador, direito);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return this.chamar();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
exponent() {
|
|
226
|
-
let expr = this.unario();
|
|
227
|
-
|
|
228
|
-
while (this.match(tiposDeSimbolos.STAR_STAR)) {
|
|
229
|
-
const operador = this.voltar();
|
|
230
|
-
const direito = this.unario();
|
|
231
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return expr;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
multiplicar() {
|
|
238
|
-
let expr = this.exponent();
|
|
239
|
-
|
|
240
|
-
while (this.match(tiposDeSimbolos.SLASH, tiposDeSimbolos.STAR, tiposDeSimbolos.MODULUS)) {
|
|
241
|
-
const operador = this.voltar();
|
|
242
|
-
const direito = this.exponent();
|
|
243
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return expr;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
adicionar() {
|
|
250
|
-
let expr = this.multiplicar();
|
|
251
|
-
|
|
252
|
-
while (this.match(tiposDeSimbolos.SUBTRACAO, tiposDeSimbolos.ADICAO)) {
|
|
253
|
-
const operador = this.voltar();
|
|
254
|
-
const direito = this.multiplicar();
|
|
255
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
return expr;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
bitFill() {
|
|
262
|
-
let expr = this.adicionar();
|
|
263
|
-
|
|
264
|
-
while (this.match(tiposDeSimbolos.MENOR_MENOR, tiposDeSimbolos.MAIOR_MAIOR)) {
|
|
265
|
-
const operador = this.voltar();
|
|
266
|
-
const direito = this.adicionar();
|
|
267
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return expr;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
bitE() {
|
|
274
|
-
let expr = this.bitFill();
|
|
275
|
-
|
|
276
|
-
while (this.match(tiposDeSimbolos.BIT_AND)) {
|
|
277
|
-
const operador = this.voltar();
|
|
278
|
-
const direito = this.bitFill();
|
|
279
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return expr;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
bitOu() {
|
|
286
|
-
let expr = this.bitE();
|
|
287
|
-
|
|
288
|
-
while (this.match(tiposDeSimbolos.BIT_OR, tiposDeSimbolos.BIT_XOR)) {
|
|
289
|
-
const operador = this.voltar();
|
|
290
|
-
const direito = this.bitE();
|
|
291
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return expr;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
comparar() {
|
|
298
|
-
let expr = this.bitOu();
|
|
299
|
-
|
|
300
|
-
while (
|
|
301
|
-
this.match(
|
|
302
|
-
tiposDeSimbolos.MAIOR,
|
|
303
|
-
tiposDeSimbolos.MAIOR_IGUAL,
|
|
304
|
-
tiposDeSimbolos.MENOR,
|
|
305
|
-
tiposDeSimbolos.MENOR_IGUAL
|
|
306
|
-
)
|
|
307
|
-
) {
|
|
308
|
-
const operador = this.voltar();
|
|
309
|
-
const direito = this.bitOu();
|
|
310
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return expr;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
equality() {
|
|
317
|
-
let expr = this.comparar();
|
|
318
|
-
|
|
319
|
-
while (this.match(tiposDeSimbolos.DIFERENTE, tiposDeSimbolos.IGUAL_IGUAL)) {
|
|
320
|
-
const operador = this.voltar();
|
|
321
|
-
const direito = this.comparar();
|
|
322
|
-
expr = new Expr.Binary(expr, operador, direito);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return expr;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
em() {
|
|
329
|
-
let expr = this.equality();
|
|
330
|
-
|
|
331
|
-
while (this.match(tiposDeSimbolos.EM)) {
|
|
332
|
-
const operador = this.voltar();
|
|
333
|
-
const direito = this.equality();
|
|
334
|
-
expr = new Expr.Logical(expr, operador, direito);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
return expr;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
e() {
|
|
341
|
-
let expr = this.em();
|
|
342
|
-
|
|
343
|
-
while (this.match(tiposDeSimbolos.E)) {
|
|
344
|
-
const operador = this.voltar();
|
|
345
|
-
const direito = this.em();
|
|
346
|
-
expr = new Expr.Logical(expr, operador, direito);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return expr;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
ou() {
|
|
353
|
-
let expr = this.e();
|
|
354
|
-
|
|
355
|
-
while (this.match(tiposDeSimbolos.OU)) {
|
|
356
|
-
const operador = this.voltar();
|
|
357
|
-
const direito = this.e();
|
|
358
|
-
expr = new Expr.Logical(expr, operador, direito);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return expr;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
atribuir() {
|
|
365
|
-
const expr = this.ou();
|
|
366
|
-
|
|
367
|
-
if (this.match(tiposDeSimbolos.IGUAL) || this.match(tiposDeSimbolos.MAIS_IGUAL)) {
|
|
368
|
-
const igual = this.voltar();
|
|
369
|
-
const valor = this.atribuir();
|
|
370
|
-
|
|
371
|
-
if (expr instanceof Expr.Variavel) {
|
|
372
|
-
const nome = expr.nome;
|
|
373
|
-
return new Expr.Assign(nome, valor);
|
|
374
|
-
} else if (expr instanceof Expr.Get) {
|
|
375
|
-
const get = expr;
|
|
376
|
-
return new Expr.Set(get.objeto, get.nome, valor);
|
|
377
|
-
} else if (expr instanceof Expr.Subscript) {
|
|
378
|
-
return new Expr.Assignsubscript(expr.callee, expr.indice, valor);
|
|
379
|
-
}
|
|
380
|
-
this.erro(igual, "Tarefa de atribuição inválida");
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
return expr;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
expressao() {
|
|
387
|
-
return this.atribuir();
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
declaracaoMostrar() {
|
|
391
|
-
this.consumir(
|
|
392
|
-
tiposDeSimbolos.PARENTESE_ESQUERDO,
|
|
393
|
-
"Esperado '(' antes dos valores em escreva."
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
const valor = this.expressao();
|
|
397
|
-
|
|
398
|
-
this.consumir(
|
|
399
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
400
|
-
"Esperado ')' após os valores em escreva."
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após o valor.");
|
|
404
|
-
|
|
405
|
-
return new Stmt.Escreva(valor);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
expressionStatement() {
|
|
409
|
-
const expr = this.expressao();
|
|
410
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após expressão.");
|
|
411
|
-
return new Stmt.Expressao(expr);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
block() {
|
|
415
|
-
const declaracoes = [];
|
|
416
|
-
|
|
417
|
-
while (!this.verificar(tiposDeSimbolos.CHAVE_DIREITA) && !this.estaNoFinal()) {
|
|
418
|
-
declaracoes.push(this.declaracao());
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
this.consumir(tiposDeSimbolos.CHAVE_DIREITA, "Esperado '}' após o bloco.");
|
|
422
|
-
return declaracoes;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
declaracaoSe() {
|
|
426
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'se'.");
|
|
427
|
-
const condicao = this.expressao();
|
|
428
|
-
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após condição do se.");
|
|
429
|
-
|
|
430
|
-
const thenBranch = this.statement();
|
|
431
|
-
|
|
432
|
-
const elifBranches = [];
|
|
433
|
-
while (this.match(tiposDeSimbolos.SENAOSE)) {
|
|
434
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'senaose'.");
|
|
435
|
-
let elifCondition = this.expressao();
|
|
436
|
-
this.consumir(
|
|
437
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
438
|
-
"Esperado ')' apóes codição do 'senaose."
|
|
439
|
-
);
|
|
440
|
-
|
|
441
|
-
const branch = this.statement();
|
|
442
|
-
|
|
443
|
-
elifBranches.push({
|
|
444
|
-
condition: elifCondition,
|
|
445
|
-
branch
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
let elseBranch = null;
|
|
450
|
-
if (this.match(tiposDeSimbolos.SENAO)) {
|
|
451
|
-
elseBranch = this.statement();
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
return new Stmt.Se(condicao, thenBranch, elifBranches, elseBranch);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
whileStatement() {
|
|
458
|
-
try {
|
|
459
|
-
this.ciclos += 1;
|
|
460
|
-
|
|
461
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'enquanto'.");
|
|
462
|
-
const condicao = this.expressao();
|
|
463
|
-
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após condicional.");
|
|
464
|
-
const corpo = this.statement();
|
|
465
|
-
|
|
466
|
-
return new Stmt.Enquanto(condicao, corpo);
|
|
467
|
-
} finally {
|
|
468
|
-
this.ciclos -= 1;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
forStatement() {
|
|
473
|
-
try {
|
|
474
|
-
this.ciclos += 1;
|
|
475
|
-
|
|
476
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após 'para'.");
|
|
477
|
-
|
|
478
|
-
let inicializador;
|
|
479
|
-
if (this.match(tiposDeSimbolos.SEMICOLON)) {
|
|
480
|
-
inicializador = null;
|
|
481
|
-
} else if (this.match(tiposDeSimbolos.VAR)) {
|
|
482
|
-
inicializador = this.declaracaoDeVariavel();
|
|
483
|
-
} else {
|
|
484
|
-
inicializador = this.expressionStatement();
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
let condicao = null;
|
|
488
|
-
if (!this.verificar(tiposDeSimbolos.SEMICOLON)) {
|
|
489
|
-
condicao = this.expressao();
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após valores da condicional");
|
|
493
|
-
|
|
494
|
-
let incrementar = null;
|
|
495
|
-
if (!this.verificar(tiposDeSimbolos.PARENTESE_DIREITO)) {
|
|
496
|
-
incrementar = this.expressao();
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após cláusulas");
|
|
500
|
-
|
|
501
|
-
const corpo = this.statement();
|
|
502
|
-
|
|
503
|
-
return new Stmt.Para(inicializador, condicao, incrementar, corpo);
|
|
504
|
-
} finally {
|
|
505
|
-
this.ciclos -= 1;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
breakStatement() {
|
|
510
|
-
if (this.ciclos < 1) {
|
|
511
|
-
this.erro(this.voltar(), "'pausa' deve estar dentro de um loop.");
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após 'pausa'.");
|
|
515
|
-
return new Stmt.Pausa();
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
declaracaoContinue() {
|
|
519
|
-
if (this.ciclos < 1) {
|
|
520
|
-
this.erro(this.voltar(), "'continua' precisa estar em um laço de repetição.");
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após 'continua'.");
|
|
524
|
-
return new Stmt.Continua();
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
declaracaoRetorna() {
|
|
528
|
-
const palavraChave = this.voltar();
|
|
529
|
-
let valor = null;
|
|
530
|
-
|
|
531
|
-
if (!this.verificar(tiposDeSimbolos.SEMICOLON)) {
|
|
532
|
-
valor = this.expressao();
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após o retorno.");
|
|
536
|
-
return new Stmt.Retorna(palavraChave, valor);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
declaracaoEscolha() {
|
|
540
|
-
try {
|
|
541
|
-
this.ciclos += 1;
|
|
542
|
-
|
|
543
|
-
this.consumir(
|
|
544
|
-
tiposDeSimbolos.PARENTESE_ESQUERDO,
|
|
545
|
-
"Esperado '{' após 'escolha'."
|
|
546
|
-
);
|
|
547
|
-
const condicao = this.expressao();
|
|
548
|
-
this.consumir(
|
|
549
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
550
|
-
"Esperado '}' após a condição de 'escolha'."
|
|
551
|
-
);
|
|
552
|
-
this.consumir(
|
|
553
|
-
tiposDeSimbolos.CHAVE_ESQUERDA,
|
|
554
|
-
"Esperado '{' antes do escopo do 'escolha'."
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
const branches = [];
|
|
558
|
-
let defaultBranch = null;
|
|
559
|
-
while (!this.match(tiposDeSimbolos.CHAVE_DIREITA) && !this.estaNoFinal()) {
|
|
560
|
-
if (this.match(tiposDeSimbolos.CASO)) {
|
|
561
|
-
let branchConditions = [this.expressao()];
|
|
562
|
-
this.consumir(
|
|
563
|
-
tiposDeSimbolos.COLON,
|
|
564
|
-
"Esperado ':' após o 'caso'."
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
while (this.verificar(tiposDeSimbolos.CASO)) {
|
|
568
|
-
this.consumir(tiposDeSimbolos.CASO, null);
|
|
569
|
-
branchConditions.push(this.expressao());
|
|
570
|
-
this.consumir(
|
|
571
|
-
tiposDeSimbolos.COLON,
|
|
572
|
-
"Esperado ':' após declaração do 'caso'."
|
|
573
|
-
);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
const stmts = [];
|
|
577
|
-
do {
|
|
578
|
-
stmts.push(this.statement());
|
|
579
|
-
} while (
|
|
580
|
-
!this.verificar(tiposDeSimbolos.CASO) &&
|
|
581
|
-
!this.verificar(tiposDeSimbolos.PADRAO) &&
|
|
582
|
-
!this.verificar(tiposDeSimbolos.CHAVE_DIREITA)
|
|
583
|
-
);
|
|
584
|
-
|
|
585
|
-
branches.push({
|
|
586
|
-
conditions: branchConditions,
|
|
587
|
-
stmts
|
|
588
|
-
});
|
|
589
|
-
} else if (this.match(tiposDeSimbolos.PADRAO)) {
|
|
590
|
-
if (defaultBranch !== null)
|
|
591
|
-
throw new ParserError(
|
|
592
|
-
"Você só pode ter um 'padrao' em cada declaração de 'escolha'."
|
|
593
|
-
);
|
|
594
|
-
|
|
595
|
-
this.consumir(
|
|
596
|
-
tiposDeSimbolos.COLON,
|
|
597
|
-
"Esperado ':' após declaração do 'padrao'."
|
|
598
|
-
);
|
|
599
|
-
|
|
600
|
-
const stmts = [];
|
|
601
|
-
do {
|
|
602
|
-
stmts.push(this.statement());
|
|
603
|
-
} while (
|
|
604
|
-
!this.verificar(tiposDeSimbolos.CASO) &&
|
|
605
|
-
!this.verificar(tiposDeSimbolos.PADRAO) &&
|
|
606
|
-
!this.verificar(tiposDeSimbolos.CHAVE_DIREITA)
|
|
607
|
-
);
|
|
608
|
-
|
|
609
|
-
defaultBranch = {
|
|
610
|
-
stmts
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
return new Stmt.Escolha(condicao, branches, defaultBranch);
|
|
616
|
-
} finally {
|
|
617
|
-
this.ciclos -= 1;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
importStatement() {
|
|
622
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' após declaração.");
|
|
623
|
-
|
|
624
|
-
const caminho = this.expressao();
|
|
625
|
-
|
|
626
|
-
let closeBracket = this.consumir(
|
|
627
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
628
|
-
"Esperado ')' após declaração."
|
|
629
|
-
);
|
|
630
|
-
|
|
631
|
-
return new Stmt.Importar(caminho, closeBracket);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
tryStatement() {
|
|
635
|
-
this.consumir(tiposDeSimbolos.CHAVE_ESQUERDA, "Esperado '{' após a declaração 'tente'.");
|
|
636
|
-
|
|
637
|
-
let tryBlock = this.block();
|
|
638
|
-
|
|
639
|
-
let catchBlock = null;
|
|
640
|
-
if (this.match(tiposDeSimbolos.PEGUE)) {
|
|
641
|
-
this.consumir(
|
|
642
|
-
tiposDeSimbolos.CHAVE_ESQUERDA,
|
|
643
|
-
"Esperado '{' após a declaração 'pegue'."
|
|
644
|
-
);
|
|
645
|
-
|
|
646
|
-
catchBlock = this.block();
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
let elseBlock = null;
|
|
650
|
-
if (this.match(tiposDeSimbolos.SENAO)) {
|
|
651
|
-
this.consumir(
|
|
652
|
-
tiposDeSimbolos.CHAVE_ESQUERDA,
|
|
653
|
-
"Esperado '{' após a declaração 'pegue'."
|
|
654
|
-
);
|
|
655
|
-
|
|
656
|
-
elseBlock = this.block();
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
let finallyBlock = null;
|
|
660
|
-
if (this.match(tiposDeSimbolos.FINALMENTE)) {
|
|
661
|
-
this.consumir(
|
|
662
|
-
tiposDeSimbolos.CHAVE_ESQUERDA,
|
|
663
|
-
"Esperado '{' após a declaração 'pegue'."
|
|
664
|
-
);
|
|
665
|
-
|
|
666
|
-
finallyBlock = this.block();
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
return new Stmt.Tente(tryBlock, catchBlock, elseBlock, finallyBlock);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
doStatement() {
|
|
673
|
-
try {
|
|
674
|
-
this.ciclos += 1;
|
|
675
|
-
|
|
676
|
-
const doBranch = this.statement();
|
|
677
|
-
|
|
678
|
-
this.consumir(
|
|
679
|
-
tiposDeSimbolos.ENQUANTO,
|
|
680
|
-
"Esperado declaração do 'enquanto' após o escopo do 'fazer'."
|
|
681
|
-
);
|
|
682
|
-
this.consumir(
|
|
683
|
-
tiposDeSimbolos.PARENTESE_ESQUERDO,
|
|
684
|
-
"Esperado '(' após declaração 'enquanto'."
|
|
685
|
-
);
|
|
686
|
-
|
|
687
|
-
const whileCondition = this.expressao();
|
|
688
|
-
|
|
689
|
-
this.consumir(
|
|
690
|
-
tiposDeSimbolos.PARENTESE_DIREITO,
|
|
691
|
-
"Esperado ')' após declaração do 'enquanto'."
|
|
692
|
-
);
|
|
693
|
-
|
|
694
|
-
return new Stmt.Fazer(doBranch, whileCondition);
|
|
695
|
-
} finally {
|
|
696
|
-
this.ciclos -= 1;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
statement() {
|
|
701
|
-
if (this.match(tiposDeSimbolos.FAZER)) return this.doStatement();
|
|
702
|
-
if (this.match(tiposDeSimbolos.TENTE)) return this.tryStatement();
|
|
703
|
-
if (this.match(tiposDeSimbolos.ESCOLHA)) return this.declaracaoEscolha();
|
|
704
|
-
if (this.match(tiposDeSimbolos.RETORNA)) return this.declaracaoRetorna();
|
|
705
|
-
if (this.match(tiposDeSimbolos.CONTINUA)) return this.declaracaoContinue();
|
|
706
|
-
if (this.match(tiposDeSimbolos.PAUSA)) return this.breakStatement();
|
|
707
|
-
if (this.match(tiposDeSimbolos.PARA)) return this.forStatement();
|
|
708
|
-
if (this.match(tiposDeSimbolos.ENQUANTO)) return this.whileStatement();
|
|
709
|
-
if (this.match(tiposDeSimbolos.SE)) return this.declaracaoSe();
|
|
710
|
-
if (this.match(tiposDeSimbolos.ESCREVA)) return this.declaracaoMostrar();
|
|
711
|
-
if (this.match(tiposDeSimbolos.CHAVE_ESQUERDA)) return new Stmt.Block(this.block());
|
|
712
|
-
|
|
713
|
-
return this.expressionStatement();
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
declaracaoDeVariavel() {
|
|
717
|
-
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome de variável.");
|
|
718
|
-
let inicializador = null;
|
|
719
|
-
if (this.match(tiposDeSimbolos.IGUAL) || this.match(tiposDeSimbolos.MAIS_IGUAL)) {
|
|
720
|
-
inicializador = this.expressao();
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
this.consumir(tiposDeSimbolos.SEMICOLON, "Esperado ';' após a declaração da variável.");
|
|
724
|
-
|
|
725
|
-
return new Stmt.Var(nome, inicializador);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
funcao(kind) {
|
|
729
|
-
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, `Esperado nome ${kind}.`);
|
|
730
|
-
return new Stmt.Funcao(nome, this.corpoDaFuncao(kind));
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
corpoDaFuncao(kind) {
|
|
734
|
-
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, `Esperado '(' após o nome ${kind}.`);
|
|
735
|
-
|
|
736
|
-
let parametros = [];
|
|
737
|
-
if (!this.verificar(tiposDeSimbolos.PARENTESE_DIREITO)) {
|
|
738
|
-
do {
|
|
739
|
-
if (parametros.length >= 255) {
|
|
740
|
-
this.erro(this.peek(), "Não pode haver mais de 255 parâmetros");
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
let paramObj = {};
|
|
744
|
-
|
|
745
|
-
if (this.peek().tipo === tiposDeSimbolos.STAR) {
|
|
746
|
-
this.consumir(tiposDeSimbolos.STAR, null);
|
|
747
|
-
paramObj["tipo"] = "wildcard";
|
|
748
|
-
} else {
|
|
749
|
-
paramObj["tipo"] = "standard";
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
paramObj['nome'] = this.consumir(
|
|
753
|
-
tiposDeSimbolos.IDENTIFICADOR,
|
|
754
|
-
"Esperado nome do parâmetro."
|
|
755
|
-
);
|
|
756
|
-
|
|
757
|
-
if (this.match(tiposDeSimbolos.IGUAL)) {
|
|
758
|
-
paramObj["default"] = this.primario();
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
parametros.push(paramObj);
|
|
762
|
-
|
|
763
|
-
if (paramObj["tipo"] === "wildcard") break;
|
|
764
|
-
} while (this.match(tiposDeSimbolos.COMMA));
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
|
|
768
|
-
this.consumir(tiposDeSimbolos.CHAVE_ESQUERDA, `Esperado '{' antes do escopo do ${kind}.`);
|
|
769
|
-
|
|
770
|
-
const corpo = this.block();
|
|
771
|
-
|
|
772
|
-
return new Expr.Funcao(parametros, corpo);
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
declaracaoDeClasse() {
|
|
776
|
-
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome da classe.");
|
|
777
|
-
|
|
778
|
-
let superClasse = null;
|
|
779
|
-
if (this.match(tiposDeSimbolos.HERDA)) {
|
|
780
|
-
this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome da SuperClasse.");
|
|
781
|
-
superClasse = new Expr.Variavel(this.voltar());
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
this.consumir(tiposDeSimbolos.CHAVE_ESQUERDA, "Esperado '{' antes do escopo da classe.");
|
|
785
|
-
|
|
786
|
-
const metodos = [];
|
|
787
|
-
while (!this.verificar(tiposDeSimbolos.CHAVE_DIREITA) && !this.estaNoFinal()) {
|
|
788
|
-
metodos.push(this.funcao("método"));
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
this.consumir(tiposDeSimbolos.CHAVE_DIREITA, "Esperado '}' após o escopo da classe.");
|
|
792
|
-
return new Stmt.Classe(nome, superClasse, metodos);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
declaracao() {
|
|
796
|
-
try {
|
|
797
|
-
if (
|
|
798
|
-
this.verificar(tiposDeSimbolos.FUNCAO) &&
|
|
799
|
-
this.verificarProximo(tiposDeSimbolos.IDENTIFICADOR)
|
|
800
|
-
) {
|
|
801
|
-
this.consumir(tiposDeSimbolos.FUNCAO, null);
|
|
802
|
-
return this.funcao("funcao");
|
|
803
|
-
}
|
|
804
|
-
if (this.match(tiposDeSimbolos.VAR)) return this.declaracaoDeVariavel();
|
|
805
|
-
if (this.match(tiposDeSimbolos.CLASSE)) return this.declaracaoDeClasse();
|
|
806
|
-
|
|
807
|
-
return this.statement();
|
|
808
|
-
} catch (erro) {
|
|
809
|
-
this.sincronizar();
|
|
810
|
-
return null;
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
analisar() {
|
|
815
|
-
const declaracoes = [];
|
|
816
|
-
while (!this.estaNoFinal()) {
|
|
817
|
-
declaracoes.push(this.declaracao());
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
return declaracoes
|
|
821
|
-
}
|
|
822
|
-
};
|