@@ -9,6 +9,7 @@ enum TokenType {
9
9
10
10
UNION = 'UNION' ,
11
11
INTERSECT = 'INTERSECT' ,
12
+ GEO_EXPR = 'GEO_EXPR' ,
12
13
TAG_EXPR = 'TAG_EXPR' ,
13
14
NUMERIC = 'NUMERIC' ,
14
15
LBRACE = 'LBRACE' ,
@@ -20,6 +21,7 @@ enum TokenType {
20
21
21
22
PLUS = 'PLUS' ,
22
23
MINUS = 'MINUS' ,
24
+ COMMA = 'COMMA' ,
23
25
24
26
LESS = 'LESS' ,
25
27
GREATER = 'GREATER' ,
@@ -140,6 +142,9 @@ class Lexer {
140
142
case '-' :// TODO: This should be MINUS token
141
143
t = new Token ( TokenType . IDENTIFIER , this . C )
142
144
break
145
+ case ',' :
146
+ t = new Token ( TokenType . COMMA , this . C )
147
+ break
143
148
case '<' :
144
149
let lPeekChar = this . PeekChar ( )
145
150
if ( lPeekChar !== null && lPeekChar === '=' ) {
@@ -175,9 +180,10 @@ class Lexer {
175
180
if ( this . C !== undefined && ( isLetter ( this . C ) || [ '@' , ':' ] . includes ( this . C ) ) ) {
176
181
const literal = this . ReadIdentifier ( )
177
182
let tokenType = KEYWORDS [ literal ] || TokenType . IDENTIFIER
178
-
179
183
if ( literal . startsWith ( 'TAG:' ) ) {
180
184
tokenType = TokenType . TAG_EXPR
185
+ } else if ( literal === 'GEO' ) {
186
+ tokenType = TokenType . GEO_EXPR
181
187
} else if ( literal . startsWith ( '@' ) && literal . endsWith ( ':UNION' ) ) {
182
188
tokenType = TokenType . UNION
183
189
} else if ( literal . startsWith ( '@' ) && literal . endsWith ( ':INTERSECT' ) ) {
@@ -283,6 +289,11 @@ class Expr {
283
289
284
290
if ( this . SubType === EntityType . TAG && this . Info ?. startsWith ( 'TAG:' ) ) {
285
291
snippet = this . Info ?. substr ( 4 )
292
+ } else if ( this . SubType === EntityType . GEO ) {
293
+ snippet = this . Info
294
+ if ( snippet ?. endsWith ( ':' ) ) {
295
+ snippet = snippet ?. slice ( 0 , - 1 )
296
+ }
286
297
}
287
298
288
299
return {
@@ -455,6 +466,8 @@ class Parser {
455
466
Exprs . push ( this . parseIntersectExpr ( ) )
456
467
} else if ( this . CurrentToken . T === TokenType . TAG_EXPR ) {
457
468
Exprs . push ( this . parseTagExpr ( ) )
469
+ } else if ( this . CurrentToken . T === TokenType . GEO_EXPR ) {
470
+ Exprs . push ( this . parseTagExpr ( ) )
458
471
}
459
472
460
473
this . nextToken ( )
@@ -499,6 +512,8 @@ class Parser {
499
512
Exprs . push ( this . parseIntersectExpr ( ) )
500
513
} else if ( this . CurrentToken . T === TokenType . TAG_EXPR ) {
501
514
Exprs . push ( this . parseTagExpr ( ) )
515
+ } else if ( this . CurrentToken . T === TokenType . GEO_EXPR ) {
516
+ Exprs . push ( this . parseTagExpr ( ) )
502
517
}
503
518
504
519
this . nextToken ( )
@@ -521,6 +536,74 @@ class Parser {
521
536
return new Expr ( str , EntityType . TEXT )
522
537
}
523
538
539
+ parseGeoExpr ( ) {
540
+ assertToken ( TokenType . GEO_EXPR , this . CurrentToken . T )
541
+
542
+ let geoData = this . CurrentToken . Data
543
+
544
+ this . nextToken ( )
545
+
546
+ assertToken ( TokenType . IDENTIFIER , this . CurrentToken . T )
547
+
548
+ let identifierData = this . CurrentToken . Data
549
+
550
+ this . nextToken ( )
551
+
552
+ assertToken ( TokenType . LBRACE , this . CurrentToken . T )
553
+
554
+ this . nextToken ( )
555
+
556
+ assertToken ( TokenType . NUMBER , this . CurrentToken . T )
557
+
558
+ let first = this . CurrentToken . Data ;
559
+
560
+ this . nextToken ( )
561
+
562
+ assertToken ( TokenType . COMMA , this . CurrentToken . T )
563
+
564
+ this . nextToken ( )
565
+
566
+ assertToken ( TokenType . NUMBER , this . CurrentToken . T )
567
+
568
+ let second = this . CurrentToken . Data ;
569
+
570
+ this . nextToken ( )
571
+
572
+ assertToken ( TokenType . IDENTIFIER , this . CurrentToken . T )
573
+
574
+ assert ( this . CurrentToken . Data === '-' , "Expected Identifier to be MINUS" )
575
+
576
+ this . nextToken ( )
577
+
578
+ assertToken ( TokenType . IDENTIFIER , this . CurrentToken . T )
579
+
580
+ assert ( this . CurrentToken . Data === '-' , "Expected Identifier to be MINUS" )
581
+
582
+ this . nextToken ( )
583
+
584
+ assertToken ( TokenType . GREATER , this . CurrentToken . T )
585
+
586
+ this . nextToken ( )
587
+
588
+ assertToken ( TokenType . NUMBER , this . CurrentToken . T )
589
+
590
+ let third = this . CurrentToken . Data ;
591
+
592
+ this . nextToken ( )
593
+
594
+ assertToken ( TokenType . IDENTIFIER , this . CurrentToken . T )
595
+
596
+ let metric = this . CurrentToken . Data ;
597
+
598
+ this . nextToken ( )
599
+
600
+ assertToken ( TokenType . RBRACE , this . CurrentToken ?. T )
601
+
602
+ this . nextToken ( )
603
+
604
+ return new Expr ( `${ first } ,${ second } --> ${ third } ${ metric } ` , EntityType . GEO , identifierData )
605
+ }
606
+
524
607
parseTagExpr ( ) {
525
608
assertToken ( TokenType . TAG_EXPR , this . CurrentToken . T )
526
609
@@ -627,6 +710,8 @@ function Parse(data: string): SearchExpr {
627
710
return p . parseUnionExpr ( )
628
711
} else if ( p . CurrentToken . T === TokenType . TAG_EXPR ) {
629
712
return p . parseTagExpr ( )
713
+ } else if ( p . CurrentToken . T === TokenType . GEO_EXPR ) {
714
+ return p . parseGeoExpr ( )
630
715
} else {
631
716
return p . parseExpr ( )
632
717
}
0 commit comments