|
@@ -83,16 +83,42 @@ export default class Parser {
|
83
|
83
|
|
84
|
84
|
private from(): AST.FromTarget | Error {
|
85
|
85
|
this.eat(TokenKind.FROM);
|
86
|
|
-
|
87
|
86
|
return this.fromTarget();
|
88
|
87
|
}
|
89
|
88
|
|
90
|
89
|
private fromTarget(): AST.FromTarget | Error {
|
|
90
|
+ if (this.match(TokenKind.LPAREN)) {
|
|
91
|
+ this.eat(TokenKind.LPAREN);
|
|
92
|
+ const stmt = this.select();
|
|
93
|
+ if (isError(stmt)) {
|
|
94
|
+ return stmt;
|
|
95
|
+ }
|
|
96
|
+
|
|
97
|
+ const rparen = this.eat(TokenKind.RPAREN);
|
|
98
|
+ if (isError(rparen)) {
|
|
99
|
+ return rparen;
|
|
100
|
+ }
|
|
101
|
+
|
|
102
|
+ if (this.match(TokenKind.AS)) {
|
|
103
|
+ return this.alias(stmt);
|
|
104
|
+ }
|
|
105
|
+
|
|
106
|
+ return stmt;
|
|
107
|
+ }
|
|
108
|
+
|
91
|
109
|
const primary = this.backtickOrIdentifier();
|
92
|
|
- if (!this.match(TokenKind.AS) || isError(primary)) {
|
|
110
|
+ if (isError(primary)) {
|
93
|
111
|
return primary;
|
94
|
112
|
}
|
95
|
113
|
|
|
114
|
+ return this.alias(primary);
|
|
115
|
+ }
|
|
116
|
+
|
|
117
|
+ private alias<T extends AST.Expr | AST.Statement>(obj: T): AST.Alias | T | Error {
|
|
118
|
+ if (!this.match(TokenKind.AS)) {
|
|
119
|
+ return obj;
|
|
120
|
+ }
|
|
121
|
+
|
96
|
122
|
this.eat(TokenKind.AS);
|
97
|
123
|
|
98
|
124
|
const token = this.currentToken();
|
|
@@ -106,7 +132,7 @@ export default class Parser {
|
106
|
132
|
return alias;
|
107
|
133
|
}
|
108
|
134
|
|
109
|
|
- return new AST.Alias(primary, alias);
|
|
135
|
+ return new AST.Alias(obj, alias);
|
110
|
136
|
}
|
111
|
137
|
|
112
|
138
|
private where(): AST.Expr | Error {
|
|
@@ -232,7 +258,7 @@ export default class Parser {
|
232
|
258
|
|
233
|
259
|
if (this.match(TokenKind.STAR)) {
|
234
|
260
|
this.eat(TokenKind.STAR);
|
235
|
|
- const right = this.alias();
|
|
261
|
+ const right = this.primary();
|
236
|
262
|
if (isError(right)) {
|
237
|
263
|
return right;
|
238
|
264
|
}
|
|
@@ -246,7 +272,7 @@ export default class Parser {
|
246
|
272
|
|
247
|
273
|
if (this.match(TokenKind.SLASH)) {
|
248
|
274
|
this.eat(TokenKind.SLASH);
|
249
|
|
- const right = this.alias();
|
|
275
|
+ const right = this.primary();
|
250
|
276
|
if (isError(right)) {
|
251
|
277
|
return right;
|
252
|
278
|
}
|
|
@@ -261,27 +287,6 @@ export default class Parser {
|
261
|
287
|
return left;
|
262
|
288
|
}
|
263
|
289
|
|
264
|
|
- private alias(): AST.Expr | Error {
|
265
|
|
- const primary = this.primary();
|
266
|
|
- if (isError(primary)) {
|
267
|
|
- return primary;
|
268
|
|
- }
|
269
|
|
-
|
270
|
|
- if (this.match(TokenKind.AS)) {
|
271
|
|
- this.eat(TokenKind.AS);
|
272
|
|
-
|
273
|
|
- const name = this.match(TokenKind.BACKTICK) ? this.backtick() : this.identifier();
|
274
|
|
-
|
275
|
|
- if (isError(name)) {
|
276
|
|
- return name;
|
277
|
|
- }
|
278
|
|
-
|
279
|
|
- return new AST.Alias(primary, name);
|
280
|
|
- }
|
281
|
|
-
|
282
|
|
- return primary;
|
283
|
|
- }
|
284
|
|
-
|
285
|
290
|
private primary(): AST.Expr | Error {
|
286
|
291
|
const token = this.currentToken();
|
287
|
292
|
|
|
@@ -293,6 +298,8 @@ export default class Parser {
|
293
|
298
|
return this.identifier();
|
294
|
299
|
case TokenKind.BACKTICK:
|
295
|
300
|
return this.backtick();
|
|
301
|
+ case TokenKind.LPAREN:
|
|
302
|
+ return this.group();
|
296
|
303
|
default:
|
297
|
304
|
return new Error(`Unexpected token: ${token.repr()}`, token.line);
|
298
|
305
|
}
|
|
@@ -330,6 +337,16 @@ export default class Parser {
|
330
|
337
|
return primary;
|
331
|
338
|
}
|
332
|
339
|
|
|
340
|
+ private group(): AST.Expr | Error {
|
|
341
|
+ this.eat(TokenKind.LPAREN);
|
|
342
|
+ const expr = this.expr();
|
|
343
|
+ const rparen = this.eat(TokenKind.RPAREN);
|
|
344
|
+ if (isError(rparen)) {
|
|
345
|
+ return rparen;
|
|
346
|
+ }
|
|
347
|
+ return expr;
|
|
348
|
+ }
|
|
349
|
+
|
333
|
350
|
private backtickOrIdentifier(): AST.Backtick | AST.Identifier | Error {
|
334
|
351
|
const token = this.currentToken();
|
335
|
352
|
switch (token.kind) {
|