@@ -67,16 +67,7 @@ export default class Parser {
67
67
private clause ( ) : Clause | undefined {
68
68
if ( this . look ( ) . type === TokenType . RESERVED_COMMAND ) {
69
69
const name = this . next ( ) ;
70
- const children : AstNode [ ] = [ ] ;
71
- while (
72
- this . look ( ) . type !== TokenType . RESERVED_COMMAND &&
73
- this . look ( ) . type !== TokenType . RESERVED_BINARY_COMMAND &&
74
- this . look ( ) . type !== TokenType . EOF &&
75
- this . look ( ) . type !== TokenType . CLOSE_PAREN &&
76
- this . look ( ) . type !== TokenType . DELIMITER
77
- ) {
78
- children . push ( this . expression ( ) ) ;
79
- }
70
+ const children = this . expressionsUntilClauseEnd ( ) ;
80
71
return { type : NodeType . clause , nameToken : name , children } ;
81
72
}
82
73
return undefined ;
@@ -85,16 +76,7 @@ export default class Parser {
85
76
private binaryClause ( ) : BinaryClause | undefined {
86
77
if ( this . look ( ) . type === TokenType . RESERVED_BINARY_COMMAND ) {
87
78
const name = this . next ( ) ;
88
- const children : AstNode [ ] = [ ] ;
89
- while (
90
- this . look ( ) . type !== TokenType . RESERVED_COMMAND &&
91
- this . look ( ) . type !== TokenType . RESERVED_BINARY_COMMAND &&
92
- this . look ( ) . type !== TokenType . EOF &&
93
- this . look ( ) . type !== TokenType . CLOSE_PAREN &&
94
- this . look ( ) . value !== TokenType . DELIMITER
95
- ) {
96
- children . push ( this . expression ( ) ) ;
97
- }
79
+ const children = this . expressionsUntilClauseEnd ( ) ;
98
80
return { type : NodeType . binary_clause , nameToken : name , children } ;
99
81
}
100
82
return undefined ;
@@ -162,20 +144,25 @@ export default class Parser {
162
144
}
163
145
164
146
private limitClause ( ) : LimitClause | undefined {
165
- if ( isToken . LIMIT ( this . look ( ) ) && this . look ( 2 ) . type === TokenType . COMMA ) {
166
- return {
167
- type : NodeType . limit_clause ,
168
- limitToken : this . next ( ) ,
169
- offsetToken : this . next ( ) ,
170
- countToken : this . next ( ) && this . next ( ) , // Discard comma token
171
- } ;
172
- }
173
147
if ( isToken . LIMIT ( this . look ( ) ) ) {
174
- return {
175
- type : NodeType . limit_clause ,
176
- limitToken : this . next ( ) ,
177
- countToken : this . next ( ) ,
178
- } ;
148
+ const limitToken = this . next ( ) ;
149
+ const expr1 = this . expressionsUntilClauseEnd ( t => t . type === TokenType . COMMA ) ;
150
+ if ( this . look ( ) . type === TokenType . COMMA ) {
151
+ this . next ( ) ; // Discard comma token
152
+ const expr2 = this . expressionsUntilClauseEnd ( ) ;
153
+ return {
154
+ type : NodeType . limit_clause ,
155
+ limitToken,
156
+ offset : expr1 ,
157
+ count : expr2 ,
158
+ } ;
159
+ } else {
160
+ return {
161
+ type : NodeType . limit_clause ,
162
+ limitToken,
163
+ count : expr1 ,
164
+ } ;
165
+ }
179
166
}
180
167
return undefined ;
181
168
}
@@ -188,6 +175,23 @@ export default class Parser {
188
175
return undefined ;
189
176
}
190
177
178
+ private expressionsUntilClauseEnd (
179
+ extraPredicate : ( token : Token ) => boolean = ( ) => false
180
+ ) : AstNode [ ] {
181
+ const children : AstNode [ ] = [ ] ;
182
+ while (
183
+ this . look ( ) . type !== TokenType . RESERVED_COMMAND &&
184
+ this . look ( ) . type !== TokenType . RESERVED_BINARY_COMMAND &&
185
+ this . look ( ) . type !== TokenType . EOF &&
186
+ this . look ( ) . type !== TokenType . CLOSE_PAREN &&
187
+ this . look ( ) . type !== TokenType . DELIMITER &&
188
+ ! extraPredicate ( this . look ( ) )
189
+ ) {
190
+ children . push ( this . expression ( ) ) ;
191
+ }
192
+ return children ;
193
+ }
194
+
191
195
// Returns current token without advancing the pointer
192
196
private look ( ahead = 0 ) : Token {
193
197
return this . tokens [ this . index + ahead ] || EOF_TOKEN ;
0 commit comments