浏览代码

Parse chained AND and OR

master
Dylan Baker 4 年前
父节点
当前提交
80f8bb450a
共有 2 个文件被更改,包括 46 次插入6 次删除
  1. 8
    6
      src/parser.ts
  2. 38
    0
      test/parser.test.ts

+ 8
- 6
src/parser.ts 查看文件

96
   }
96
   }
97
 
97
 
98
   private or(): AST.Expr | Error {
98
   private or(): AST.Expr | Error {
99
-    const left = this.and();
99
+    let left = this.and();
100
     if (isError(left)) {
100
     if (isError(left)) {
101
       return left;
101
       return left;
102
     }
102
     }
103
 
103
 
104
-    if (this.match(TokenKind.OR)) {
104
+    while (this.match(TokenKind.OR)) {
105
       this.eat(TokenKind.OR);
105
       this.eat(TokenKind.OR);
106
       const right = this.and();
106
       const right = this.and();
107
       if (isError(right)) {
107
       if (isError(right)) {
108
         return right;
108
         return right;
109
       }
109
       }
110
-      return new AST.Binary({
110
+
111
+      left = new AST.Binary({
111
         left,
112
         left,
112
         right,
113
         right,
113
         type: AST.BinaryExpressionTypes.OR,
114
         type: AST.BinaryExpressionTypes.OR,
118
   }
119
   }
119
 
120
 
120
   private and(): AST.Expr | Error {
121
   private and(): AST.Expr | Error {
121
-    const left = this.equality();
122
+    let left = this.equality();
122
     if (isError(left)) {
123
     if (isError(left)) {
123
       return left;
124
       return left;
124
     }
125
     }
125
 
126
 
126
-    if (this.match(TokenKind.AND)) {
127
+    while (this.match(TokenKind.AND)) {
127
       this.eat(TokenKind.AND);
128
       this.eat(TokenKind.AND);
128
       const right = this.equality();
129
       const right = this.equality();
129
       if (isError(right)) {
130
       if (isError(right)) {
130
         return right;
131
         return right;
131
       }
132
       }
132
-      return new AST.Binary({
133
+
134
+      left = new AST.Binary({
133
         left,
135
         left,
134
         right,
136
         right,
135
         type: AST.BinaryExpressionTypes.AND,
137
         type: AST.BinaryExpressionTypes.AND,

+ 38
- 0
test/parser.test.ts 查看文件

222
       }),
222
       }),
223
     ]);
223
     ]);
224
   });
224
   });
225
+
226
+  it("should parse chained ANDs", () => {
227
+    const tree = parse("select a from b where c and d and e");
228
+    expect(tree).to.deep.equal([
229
+      new AST.SelectStatement({
230
+        arguments: [new AST.Identifier("a")],
231
+        from: new AST.Identifier("b"),
232
+        where: new AST.Binary({
233
+          left: new AST.Binary({
234
+            left: new AST.Identifier("c"),
235
+            right: new AST.Identifier("d"),
236
+            type: AST.BinaryExpressionTypes.AND,
237
+          }),
238
+          right: new AST.Identifier("e"),
239
+          type: AST.BinaryExpressionTypes.AND,
240
+        }),
241
+      }),
242
+    ]);
243
+  });
244
+
245
+  it("should parse chained ORs", () => {
246
+    const tree = parse("select a from b where c or d or e");
247
+    expect(tree).to.deep.equal([
248
+      new AST.SelectStatement({
249
+        arguments: [new AST.Identifier("a")],
250
+        from: new AST.Identifier("b"),
251
+        where: new AST.Binary({
252
+          left: new AST.Binary({
253
+            left: new AST.Identifier("c"),
254
+            right: new AST.Identifier("d"),
255
+            type: AST.BinaryExpressionTypes.OR,
256
+          }),
257
+          right: new AST.Identifier("e"),
258
+          type: AST.BinaryExpressionTypes.OR,
259
+        }),
260
+      }),
261
+    ]);
262
+  });
225
 });
263
 });

正在加载...
取消
保存