@@ -52,7 +52,8 @@ expression =/ or-expression / identifier
52
52
expression =/ and-expression / not-expression / paren-expression
53
53
expression =/ multi-select-list / multi-select-hash / literal
54
54
expression =/ function-expression / pipe-expression / raw-string
55
- expression =/ current-node
55
+ expression =/ root-node / current-node
56
+ expression =/ arithmetic-expression
56
57
sub-expression = expression " ." ( identifier / multi-select-list / multi-select-hash / function-expression / " *" ) ; ; # Sub-expressions
57
58
; ; A sub-expression is a combination of two expressions separated by the '.' char. A sub-expression is evaluated as follows:
58
59
; ;
@@ -200,6 +201,58 @@ not-expression = "!" expression ;; # Not Expressions
200
201
; ; search(!EmptyList, {"EmptyList": []}) -> true
201
202
; ; ```
202
203
204
+ arithmetic-expression =/ " +" expression ; + %x43 ;; # Arithmetic Expressions \
205
+ arithmetic-expression =/ ( " -" / " –" ) expression ; - %x45 – %x2212 \
206
+ arithmetic-expression = expression " %" expression ; % %x37 \
207
+ arithmetic-expression =/ expression ( " *" / " ×" ) expression ; * %x42 × %xD7 \
208
+ arithmetic-expression =/ expression " +" expression ; + %x43 \
209
+ arithmetic-expression =/ expression ( " -" / " –" ) expression ; - %x45 – %x2212 \
210
+ arithmetic-expression =/ expression ( " /" / " ÷" ) expression ; / %x47 ÷
211
+ ; ; An `arithmetic-expression` enables simple computations using the four basic operations,
212
+ ; ; as well as the modulo and integer-division operations.
213
+ ; ;
214
+ ; ; To support arithmetic operations, the following operators are available:
215
+ ; ;
216
+ ; ; - `+` addition operator
217
+ ; ; - `-` subtraction operator
218
+ ; ; - `*` multiplication operator
219
+ ; ; - `/` division operator
220
+ ; ; - `%` modulo operator
221
+ ; ; - `//` integer division operator
222
+ ; ;
223
+ ; ; Proper mathematical operators are also supported using the following UNICODE characters:
224
+ ; ;
225
+ ; ; - `–` (U+2212 MINUS SIGN)
226
+ ; ; - `÷` (U+00F7 DIVISION SIGN)
227
+ ; ; - `×` (U+00D7 MULTIPLY SIGN)
228
+ ; ;
229
+ ; ; Arithmetic operations adhere to the usual precedence rules, from lowest to highest:
230
+ ; ;
231
+ ; ; - `-` subtraction operator and `+` addition operator
232
+ ; ; - `/` division, `*` multiplication, `%` modulo and `//` integer division operators
233
+ ; ;
234
+ ; ; In the absence of parentheses, operators of the same level of precedence are evaluated from left to right.
235
+ ; ; Arithmetic operators have higher precedence than comparison operators and lower precedence than the `.` "dot" `sub-expression` token separator.
236
+ ; ;
237
+ ; ; ## Examples
238
+ ; ;
239
+ ; ; ```
240
+ ; ; search(a + b, {"a": 1, "b": 2}) -> 3
241
+ ; ; search(a - b, {"a": 1, "b": 2}) -> -1
242
+ ; ; search(a * b, {"a": 2, "b": 4}) -> 8
243
+ ; ; search(a / b, {"a": 2, "b": 3}) -> 0.666666666666667
244
+ ; ; search(a % b, {"a": 10, "b": 3} -> 1
245
+ ; ; search(a // b, {"a": 10, "b": 3} -> -3
246
+ ; ; search(a.b + cd, {"a": {"b": 1}, "c": {"d": 2}}) -> 3
247
+ ; ; ```
248
+ ; ;
249
+ ; ; Since `arithmetic-expression` is not valid on the right-hand-side of a `sub-expression`, a `pipe-expression` can be used instead:
250
+ ; ;
251
+ ; ; ```
252
+ ; ; search({ab: a.b, cd: c.d} | ab + cd, {"a": {"b": 1}, "c": {"d": 2}}) -> 3
253
+ ; ; ```
254
+ ; ;
255
+
203
256
paren-expression = " (" expression " )" ; ; # Parenthetical Expressions
204
257
; ; A paren-expression allows a user to override the precedence order of an expression, e.g. (a || b) && c.
205
258
; ;
@@ -451,6 +504,7 @@ no-args = "(" ")" ;; \
451
504
one-or-more-args = " (" ( function-arg * ( " ," function-arg ) ) " )" ; ; \
452
505
function-arg = expression / expression-type ; ; \
453
506
current-node = " @" ; ; \
507
+ root-node = " $" ; ; \
454
508
expression-type = " &" expression
455
509
; ; Functions allow users to easily transform and filter data in JMESPath expressions.
456
510
; ;
@@ -490,6 +544,39 @@ expression-type = "&" expression
490
544
; ; being evaluated. When in a projection, the current node value must be changed to the node currently being evaluated
491
545
; ; by the projection.
492
546
; ;
547
+ ; ;
548
+ ; ; ## root-node
549
+ ; ;
550
+ ; ; The `root-node` token can be used to represent the original input JSON document.
551
+ ; ;
552
+ ; ; As a JMESPath expression is being evaluated, the current scope changes.
553
+ ; ; Given a simple sub expression such as `foo.bar`, first the `foo` expression is evaluated
554
+ ; ; with the starting input JSON document, and the result of that expression is then used as
555
+ ; ; the current scope when the `bar` element is evaluated.
556
+ ; ;
557
+ ; ; Once we’ve drilled down to a specific scope, the `root-node` token can be used
558
+ ; ; to refer to the original JSON document.
559
+ ; ;
560
+ ; ; ### Example
561
+ ; ;
562
+ ; ; Given a JSON document:
563
+ ; ;
564
+ ; ; ```json
565
+ ; ; {
566
+ ; ; "first_choice": "WA",
567
+ ; ; "states": [
568
+ ; ; {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]},
569
+ ; ; {"name": "CA", "cities": ["Los Angeles", "San Francisco"]},
570
+ ; ; {"name": "NY", "cities": ["New York City", "Albany"]}
571
+ ; ; ]
572
+ ; ; }
573
+ ; ; ```
574
+ ; ; We can retrieve the list of cities of the state corresponding to the `first_choice` key
575
+ ; ; using the following expression:
576
+ ; ;
577
+ ; ; ` states[? name == $.first_choice ].cities[] `
578
+ ; ;
579
+ ; ;
493
580
; ; # Function Evaluation
494
581
; ;
495
582
; ; Functions are evaluated in applicative order. Each argument must be an expression, each argument expression must be
@@ -522,7 +609,6 @@ expression-type = "&" expression
522
609
; ;
523
610
; ; This provides a simple mechanism to explicitly convert types when needed.
524
611
525
-
526
612
raw-string = " '" * raw-string-char " '" ; ; # Raw String Literals \
527
613
raw-string-char = (%x 20 -26 / %x 28 -5B / %x 5D -10FFFF ) / preserved-escape / raw-string-escape ; ; \
528
614
preserved-escape = escape (%x 20 -26 / %x 28 -5B / %x 5D -10FFFF ) ; ; \
@@ -657,95 +743,3 @@ int = zero / ( digit1-9 *digit )
657
743
minus = %x 2D ; -
658
744
plus = %x 2B ; +
659
745
zero = %x 30 ; 0
660
-
661
- expression =/ arithmetic-expression ; ; ## Arithmetic Expressions
662
-
663
- arithmetic-expression =/ " +" expression ; + %x43
664
- arithmetic-expression =/ ( " -" / " –" ) expression ; - %x45 – %x2212
665
-
666
- arithmetic-expression = expression " %" expression ; % %x37
667
- arithmetic-expression =/ expression ( " *" / " ×" ) expression ; * %x42 × %xD7
668
- arithmetic-expression =/ expression " +" expression ; + %x43
669
- arithmetic-expression =/ expression ( " -" / " –" ) expression ; - %x45 – %x2212
670
- arithmetic-expression =/ expression ( " /" / " ÷" ) expression ; / %x47 ÷
671
-
672
- ; ; An `arithmetic-expression` enables simple computations using the four basic operations,
673
- ; ; as well as the modulo and integer-division operations.
674
- ; ;
675
- ; ; To support arithmetic operations, the following operators are available:
676
- ; ;
677
- ; ; - `+` addition operator
678
- ; ; - `-` subtraction operator
679
- ; ; - `*` multiplication operator
680
- ; ; - `/` division operator
681
- ; ; - `%` modulo operator
682
- ; ; - `//` integer division operator
683
- ; ;
684
- ; ; Proper mathematical operators are also supported using the following UNICODE characters:
685
- ; ;
686
- ; ; - `–` (U+2212 MINUS SIGN)
687
- ; ; - `÷` (U+00F7 DIVISION SIGN)
688
- ; ; - `×` (U+00D7 MULTIPLY SIGN)
689
- ; ;
690
- ; ; Arithmetic operations adhere to the usual precedence rules, from lowest to highest:
691
- ; ;
692
- ; ; - `-` subtraction operator and `+` addition operator
693
- ; ; - `/` division, `*` multiplication, `%` modulo and `//` integer division operators
694
- ; ;
695
- ; ; In the absence of parentheses, operators of the same level of precedence are evaluated from left to right.
696
- ; ; Arithmetic operators have higher precedence than comparison operators and lower precedence than the `.` "dot" `sub-expression` token separator.
697
- ; ;
698
- ; ; ## Examples
699
- ; ;
700
- ; ; ```
701
- ; ; search(a + b, {"a": 1, "b": 2}) -> 3
702
- ; ; search(a - b, {"a": 1, "b": 2}) -> -1
703
- ; ; search(a * b, {"a": 2, "b": 4}) -> 8
704
- ; ; search(a / b, {"a": 2, "b": 3}) -> 0.666666666666667
705
- ; ; search(a % b, {"a": 10, "b": 3} -> 1
706
- ; ; search(a // b, {"a": 10, "b": 3} -> -3
707
- ; ; search(a.b + cd, {"a": {"b": 1}, "c": {"d": 2}}) -> 3
708
- ; ; ```
709
- ; ;
710
- ; ; Since `arithmetic-expression` is not valid on the right-hand-side of a `sub-expression`, a `pipe-expression` can be used instead:
711
- ; ;
712
- ; ; ```
713
- ; ; search({ab: a.b, cd: c.d} | ab + cd, {"a": {"b": 1}, "c": {"d": 2}}) -> 3
714
- ; ; ```
715
- ; ;
716
-
717
- expression =/ root-node ; ; ## Root Reference
718
-
719
- root-node = " $"
720
-
721
- ; ; ## root-node
722
- ; ;
723
- ; ; The `root-node` token can be used to represent the original input JSON document.
724
- ; ;
725
- ; ; As a JMESPath expression is being evaluated, the current scope changes.
726
- ; ; Given a simple sub expression such as `foo.bar`, first the `foo` expression is evaluated
727
- ; ; with the starting input JSON document, and the result of that expression is then used as
728
- ; ; the current scope when the `bar` element is evaluated.
729
- ; ;
730
- ; ; Once we’ve drilled down to a specific scope, the `root-node` token can be used
731
- ; ; to refer to the original JSON document.
732
- ; ;
733
- ; ; Example
734
- ; ;
735
- ; ; Given a JSON document:
736
- ; ;
737
- ; ; ```json
738
- ; ; {
739
- ; ; "first_choice": "WA",
740
- ; ; "states": [
741
- ; ; {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]},
742
- ; ; {"name": "CA", "cities": ["Los Angeles", "San Francisco"]},
743
- ; ; {"name": "NY", "cities": ["New York City", "Albany"]}
744
- ; ; ]
745
- ; ; }
746
- ; ; ```
747
- ; ; We can retrieve the list of cities of the state corresponding to the `first_choice` key
748
- ; ; using the following expression:
749
- ; ;
750
- ; ; ` states[? name == $.first_choice ].cities[] `
751
- ; ;
0 commit comments