Browse Source

Parse from

master
Dylan Baker 4 years ago
parent
commit
03f8dcd95f
5 changed files with 53 additions and 32 deletions
  1. 3
    1
      src/ast.ts
  2. 16
    0
      src/ast/selectStatement.ts
  3. 0
    20
      src/ast/statement.ts
  4. 18
    3
      src/parser.ts
  5. 16
    8
      test/parser.test.ts

+ 3
- 1
src/ast.ts View File

@@ -1,8 +1,10 @@
1 1
 import { Identifier } from "./ast/identifier";
2 2
 import { Number as _Number } from "./ast/number";
3
+import { SelectStatement } from "./ast/selectStatement";
3 4
 
4 5
 export * from "./ast/identifier";
5 6
 export * from "./ast/number";
6
-export * from "./ast/statement";
7
+export * from "./ast/selectStatement";
7 8
 
8 9
 export type Primary = _Number | Identifier;
10
+export type Statement = SelectStatement;

+ 16
- 0
src/ast/selectStatement.ts View File

@@ -0,0 +1,16 @@
1
+import * as AST from "../ast";
2
+
3
+export interface ISelectStatementOptions {
4
+  arguments: AST.Primary[];
5
+  from?: AST.Primary | null;
6
+}
7
+
8
+export class SelectStatement {
9
+  public arguments: AST.Primary[];
10
+  public from: AST.Primary | null;
11
+
12
+  constructor(opts: ISelectStatementOptions) {
13
+    this.arguments = opts.arguments;
14
+    this.from = opts.from ? opts.from : null;
15
+  }
16
+}

+ 0
- 20
src/ast/statement.ts View File

@@ -1,20 +0,0 @@
1
-import * as AST from "../ast";
2
-
3
-export enum StatementType {
4
-  SELECT = "SELECT",
5
-}
6
-
7
-export interface IStatementOptions {
8
-  type: StatementType;
9
-  arguments: AST.Primary[];
10
-}
11
-
12
-export class Statement {
13
-  public type: StatementType;
14
-  public arguments: AST.Primary[];
15
-
16
-  constructor(opts: IStatementOptions) {
17
-    this.type = opts.type;
18
-    this.arguments = opts.arguments;
19
-  }
20
-}

+ 18
- 3
src/parser.ts View File

@@ -43,9 +43,16 @@ export default class Parser {
43 43
     if (isError(args)) {
44 44
       return args;
45 45
     }
46
-    return new AST.Statement({
46
+
47
+    const from =
48
+      this.currentToken().kind === TokenKind.FROM ? this.from() : null;
49
+    if (isError(from)) {
50
+      return from;
51
+    }
52
+
53
+    return new AST.SelectStatement({
47 54
       arguments: args,
48
-      type: AST.StatementType.SELECT,
55
+      from,
49 56
     });
50 57
   }
51 58
 
@@ -69,6 +76,11 @@ export default class Parser {
69 76
     return args;
70 77
   }
71 78
 
79
+  private from(): AST.Primary | Error {
80
+    this.eat(TokenKind.FROM);
81
+    return this.identifier();
82
+  }
83
+
72 84
   private primary(): AST.Primary | Error {
73 85
     const token = this.currentToken();
74 86
     switch (token.kind) {
@@ -78,7 +90,10 @@ export default class Parser {
78 90
         return this.identifier();
79 91
     }
80 92
 
81
-    return new Error(`Unexpected token ${token.kind} ${token.value}`, token.line);
93
+    return new Error(
94
+      `Unexpected token ${token.kind} ${token.value}`,
95
+      token.line,
96
+    );
82 97
   }
83 98
 
84 99
   private identifier(): AST.Identifier | Error {

+ 16
- 8
test/parser.test.ts View File

@@ -23,9 +23,8 @@ describe("Parser", () => {
23 23
   it("should parse a number selection", () => {
24 24
     const tree = parse("select 5");
25 25
     expect(tree).to.deep.equal([
26
-      new AST.Statement({
26
+      new AST.SelectStatement({
27 27
         arguments: [new AST.Number(5)],
28
-        type: AST.StatementType.SELECT,
29 28
       }),
30 29
     ]);
31 30
   });
@@ -33,12 +32,11 @@ describe("Parser", () => {
33 32
   it("should parse a multiple number selection", () => {
34 33
     const tree = parse("select 5, 6");
35 34
     expect(tree).to.deep.equal([
36
-      new AST.Statement({
35
+      new AST.SelectStatement({
37 36
         arguments: [
38 37
           new AST.Number(5),
39 38
           new AST.Number(6),
40 39
         ],
41
-        type: AST.StatementType.SELECT,
42 40
       }),
43 41
     ]);
44 42
   });
@@ -46,12 +44,11 @@ describe("Parser", () => {
46 44
   it("should parse a selection of identifiers", () => {
47 45
     const tree = parse("select a, b");
48 46
     expect(tree).to.deep.equal([
49
-      new AST.Statement({
47
+      new AST.SelectStatement({
50 48
         arguments: [
51 49
           new AST.Identifier("a"),
52 50
           new AST.Identifier("b"),
53 51
         ],
54
-        type: AST.StatementType.SELECT,
55 52
       }),
56 53
     ]);
57 54
   });
@@ -59,12 +56,23 @@ describe("Parser", () => {
59 56
   it("should parse a selection of identifiers and numbers", () => {
60 57
     const tree = parse("select a, 5");
61 58
     expect(tree).to.deep.equal([
62
-      new AST.Statement({
59
+      new AST.SelectStatement({
63 60
         arguments: [
64 61
           new AST.Identifier("a"),
65 62
           new AST.Number(5),
66 63
         ],
67
-        type: AST.StatementType.SELECT,
64
+      }),
65
+    ]);
66
+  });
67
+
68
+  it("should parse the from of a selection", () => {
69
+    const tree = parse("select a from t");
70
+    expect(tree).to.deep.equal([
71
+      new AST.SelectStatement({
72
+        arguments: [
73
+          new AST.Identifier("a"),
74
+        ],
75
+        from: new AST.Identifier("t"),
68 76
       }),
69 77
     ]);
70 78
   });

Loading…
Cancel
Save