@@ -9,6 +9,7 @@ enum TokenType {
9
9
10
10
UNION = 'UNION' ,
11
11
INTERSECT = 'INTERSECT' ,
12
+ TAG_EXPR = 'TAG_EXPR' ,
12
13
NUMERIC = 'NUMERIC' ,
13
14
LBRACE = 'LBRACE' ,
14
15
RBRACE = 'RBRACE' ,
@@ -46,6 +47,7 @@ const KEYWORDS = {
46
47
[ TokenType . ILLEGAL . toString ( ) ] : TokenType . ILLEGAL ,
47
48
48
49
[ TokenType . UNION . toString ( ) ] : TokenType . UNION ,
50
+ [ TokenType . TAG_EXPR . toString ( ) ] : TokenType . TAG_EXPR ,
49
51
[ TokenType . INTERSECT . toString ( ) ] : TokenType . INTERSECT ,
50
52
[ TokenType . NUMERIC . toString ( ) ] : TokenType . NUMERIC ,
51
53
@@ -94,7 +96,7 @@ class Lexer {
94
96
ReadIdentifier ( ) : string {
95
97
let str = ''
96
98
97
- while ( this . C !== undefined && isLetter ( this . C ) ) {
99
+ while ( this . C !== undefined && ( isLetter ( this . C ) || [ '@' , ':' ] . includes ( this . C ) ) ) {
98
100
str = str + this . C
99
101
this . ReadChar ( )
100
102
}
@@ -138,9 +140,6 @@ class Lexer {
138
140
case '-' :// TODO: This should be MINUS token
139
141
t = new Token ( TokenType . IDENTIFIER , this . C )
140
142
break
141
- case '@' :
142
- t = new Token ( TokenType . IDENTIFIER , this . C )
143
- break
144
143
case '<' :
145
144
let lPeekChar = this . PeekChar ( )
146
145
if ( lPeekChar !== null && lPeekChar === '=' ) {
@@ -173,9 +172,17 @@ class Lexer {
173
172
t = new Token ( TokenType . EOF , '' )
174
173
break
175
174
default :
176
- if ( this . C !== undefined && isLetter ( this . C ) ) {
175
+ if ( this . C !== undefined && ( isLetter ( this . C ) || [ '@' , ':' ] . includes ( this . C ) ) ) {
177
176
const literal = this . ReadIdentifier ( )
178
177
let tokenType = KEYWORDS [ literal ] || TokenType . IDENTIFIER
178
+
179
+ if ( literal . startsWith ( 'TAG:' ) ) {
180
+ tokenType = TokenType . TAG_EXPR
181
+ } else if ( literal . startsWith ( '@' ) && literal . endsWith ( ':UNION' ) ) {
182
+ tokenType = TokenType . UNION
183
+ } else if ( literal . startsWith ( '@' ) && literal . endsWith ( ':INTERSECT' ) ) {
184
+ tokenType = TokenType . INTERSECT
185
+ }
179
186
t = new Token ( tokenType , literal )
180
187
return t
181
188
} else if ( this . C !== undefined && isDigit ( this . C ) ) {
@@ -214,13 +221,15 @@ export enum EntityType {
214
221
export interface EntityInfo {
215
222
id : string
216
223
type : EntityType ,
224
+ subType ?: EntityType ,
217
225
data ?: string
218
226
snippet ?: string
219
227
children : EntityInfo [ ]
220
228
time ?: string
221
229
counter ?: string
222
230
size ?: string
223
231
parentId ?: string
232
+ parentSnippet ?: string
224
233
level ?: number
225
234
recordsProduced ?: string
226
235
}
@@ -257,19 +266,32 @@ export function GetAncestors(info: EntityInfo, searchId: string, a: IAncestors):
257
266
258
267
class Expr {
259
268
Core : string
260
- Type ?: string
269
+ Type : EntityType
270
+ SubType : EntityType
261
271
Time ?: string
272
+ Info ?: string
262
273
263
- constructor ( expr : string ) {
274
+ constructor ( expr : string , subType : EntityType , info : string | undefined = undefined ) {
264
275
this . Core = expr
276
+ this . SubType = subType
277
+ this . Info = info
265
278
}
266
279
267
280
toJSON ( ) : EntityInfo {
281
+
282
+ let snippet : string | undefined ;
283
+
284
+ if ( this . SubType === EntityType . TAG && this . Info ?. startsWith ( 'TAG:' ) ) {
285
+ snippet = this . Info ?. substr ( 4 )
286
+ }
287
+
268
288
return {
269
289
id : uuidv4 ( ) ,
270
290
// data: 'Expr',
271
291
// snippet: this.Core,
272
292
type : EntityType . Expr ,
293
+ subType : this . SubType ,
294
+ snippet : snippet ,
273
295
data : this . Core ,
274
296
children : [ ] ,
275
297
time : this . Time ,
@@ -312,34 +334,54 @@ type ExprTuple2 = SearchExpr[]
312
334
313
335
class IntersectExpr {
314
336
Core : ExprTuple2
337
+ Info ?: string
315
338
316
- constructor ( e : ExprTuple2 ) {
339
+ constructor ( e : ExprTuple2 , info ?: string ) {
317
340
this . Core = e
341
+ this . Info = info
318
342
}
319
343
320
344
toJSON ( ) : EntityInfo {
321
345
const id = uuidv4 ( )
346
+
347
+ let snippet : string | undefined ;
348
+
349
+ if ( ! this . Info ?. startsWith ( 'INTERSECT' ) ) {
350
+ snippet = this . Info ?. substring ( 0 , this . Info . indexOf ( ':INTERSECT' ) )
351
+ }
352
+
322
353
return {
323
354
id,
324
355
type : EntityType . INTERSECT ,
325
- children : this . Core . map ( x => x . toJSON ( ) ) . map ( ( d : EntityInfo ) => ( { ...d , parentId : id } ) ) ,
356
+ snippet,
357
+ children : this . Core . map ( x => x . toJSON ( ) ) . map ( ( d : EntityInfo ) => ( { ...d , parentId : id , parentSnippet : snippet } ) ) ,
326
358
}
327
359
}
328
360
}
329
361
330
362
class UnionExpr {
363
+ Info ?: string
331
364
Core : ExprTuple2
332
365
333
- constructor ( e : ExprTuple2 ) {
366
+ constructor ( e : ExprTuple2 , info ?: string ) {
334
367
this . Core = e
368
+ this . Info = info
335
369
}
336
370
337
371
toJSON ( ) : EntityInfo {
338
372
const id = uuidv4 ( )
373
+
374
+ let snippet : string | undefined ;
375
+
376
+ if ( ! this . Info ?. startsWith ( 'UNION' ) ) {
377
+ snippet = this . Info ?. substring ( 0 , this . Info . indexOf ( ':UNION' ) )
378
+ }
379
+
339
380
return {
340
381
id,
341
382
type : EntityType . UNION ,
342
- children : this . Core . map ( x => x . toJSON ( ) ) . map ( ( d : EntityInfo ) => ( { ...d , parentId : id } ) )
383
+ snippet,
384
+ children : this . Core . map ( x => x . toJSON ( ) ) . map ( ( d : EntityInfo ) => ( { ...d , parentId : id , parentSnippet : snippet } ) )
343
385
}
344
386
}
345
387
}
@@ -374,6 +416,8 @@ class Parser {
374
416
this . CurrentToken = this . PeekToken
375
417
this . PeekToken = this . L . NextToken ( )
376
418
419
+ console . log ( "NEXT TOKEN" , this . CurrentToken )
420
+
377
421
if ( this . CurrentToken . T === TokenType . EOF ) {
378
422
throw new Error ( "Didn't expect EOF token" )
379
423
}
@@ -383,6 +427,8 @@ class Parser {
383
427
384
428
assertToken ( TokenType . INTERSECT , this . CurrentToken ?. T )
385
429
430
+ let intersectData = this . CurrentToken . Data
431
+
386
432
this . nextToken ( )
387
433
388
434
assertToken ( TokenType . LBRACE , this . CurrentToken ?. T )
@@ -409,19 +455,23 @@ class Parser {
409
455
Exprs . push ( this . parseUnionExpr ( ) )
410
456
} else if ( this . CurrentToken . T === TokenType . INTERSECT ) {
411
457
Exprs . push ( this . parseIntersectExpr ( ) )
458
+ } else if ( this . CurrentToken . T === TokenType . TAG_EXPR ) {
459
+ Exprs . push ( this . parseTagExpr ( ) )
412
460
}
413
461
414
462
this . nextToken ( )
415
463
}
416
464
417
- return new IntersectExpr ( Exprs )
465
+ return new IntersectExpr ( Exprs , intersectData )
418
466
}
419
467
420
468
421
469
parseUnionExpr ( ) : UnionExpr {
422
470
423
471
assertToken ( TokenType . UNION , this . CurrentToken ?. T )
424
472
473
+ let unionData = this . CurrentToken . Data
474
+
425
475
this . nextToken ( )
426
476
427
477
assertToken ( TokenType . LBRACE , this . CurrentToken . T )
@@ -449,12 +499,14 @@ class Parser {
449
499
Exprs . push ( this . parseUnionExpr ( ) )
450
500
} else if ( this . CurrentToken . T === TokenType . INTERSECT ) {
451
501
Exprs . push ( this . parseIntersectExpr ( ) )
502
+ } else if ( this . CurrentToken . T === TokenType . TAG_EXPR ) {
503
+ Exprs . push ( this . parseTagExpr ( ) )
452
504
}
453
505
454
506
this . nextToken ( )
455
507
}
456
508
457
- return new UnionExpr ( Exprs )
509
+ return new UnionExpr ( Exprs , unionData )
458
510
}
459
511
460
512
parseExpr ( ) {
@@ -468,7 +520,40 @@ class Parser {
468
520
this . nextToken ( )
469
521
}
470
522
471
- return new Expr ( str )
523
+ return new Expr ( str , EntityType . TEXT )
524
+ }
525
+
526
+ parseTagExpr ( ) {
527
+ assertToken ( TokenType . TAG_EXPR , this . CurrentToken . T )
528
+
529
+ let tagData = this . CurrentToken . Data
530
+
531
+ this . nextToken ( )
532
+
533
+ assertToken ( TokenType . LBRACE , this . CurrentToken . T )
534
+
535
+ this . nextToken ( )
536
+
537
+ assertToken ( TokenType . NEW_LINE , this . CurrentToken ?. T )
538
+
539
+ this . nextToken ( )
540
+
541
+ assertToken ( TokenType . IDENTIFIER , this . CurrentToken ?. T )
542
+
543
+ let identifier = this . CurrentToken . Data
544
+
545
+ this . nextToken ( )
546
+
547
+ assertToken ( TokenType . NEW_LINE , this . CurrentToken ?. T )
548
+
549
+ this . nextToken ( )
550
+
551
+ assertToken ( TokenType . RBRACE , this . CurrentToken ?. T )
552
+
553
+ this . nextToken ( )
554
+
555
+ return new Expr ( identifier , EntityType . TAG , tagData )
556
+
472
557
}
473
558
474
559
parseNumericExpr ( ) {
@@ -489,7 +574,7 @@ class Parser {
489
574
let lsign = this . CurrentToken // TODO: Check sign
490
575
491
576
this . nextToken ( )
492
-
577
+
493
578
assertToken ( TokenType . IDENTIFIER , this . CurrentToken ?. T )
494
579
495
580
let identifier = this . CurrentToken
@@ -524,8 +609,6 @@ class Parser {
524
609
525
610
return new NumericExpr ( left !== 'inf' ? parseFloat ( left ) : Infinity , lsign , identifier , rsign , right !== 'inf' ? parseFloat ( right ) : Infinity )
526
611
}
527
-
528
-
529
612
}
530
613
531
614
@@ -540,6 +623,8 @@ function Parse(data: string): SearchExpr {
540
623
return p . parseNumericExpr ( )
541
624
} else if ( p . CurrentToken . T === TokenType . UNION ) {
542
625
return p . parseUnionExpr ( )
626
+ } else if ( p . CurrentToken . T === TokenType . TAG_EXPR ) {
627
+ return p . parseTagExpr ( )
543
628
} else {
544
629
return p . parseExpr ( )
545
630
}
0 commit comments