Skip to content

Commit d21a9fc

Browse files
committed
Converted existing proposals to markdown.
1 parent ec06ced commit d21a9fc

11 files changed

+3514
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# Nested Expressions
2+
3+
|||
4+
|---|---
5+
| **JEP** | 1
6+
| **Author** | Michael Dowling
7+
| **Status** | accepted
8+
| **Created**| 27-Nov-2013
9+
10+
## Abstract
11+
12+
This document proposes modifying the [JMESPath grammar](https://jmespath.readthedocs.org/en/latest/specification.html#grammar)
13+
to support arbitrarily nested expressions within `multi-select-list` and
14+
`multi-select-hash` expressions.
15+
16+
## Motivation
17+
18+
This JMESPath grammar currently does not allow arbitrarily nested expressions
19+
within `multi-select-list` and `multi-select-hash` expressions. This
20+
prevents nested branching expressions, nested `multi-select-list` expressions
21+
within other multi expressions, and nested `or-expressions` within any
22+
multi-expression.
23+
24+
By allowing any expression to be nested within a `multi-select-list` and
25+
`multi-select-hash` expression, we can trim down several grammar rules and
26+
provide customers with a much more flexible expression DSL.
27+
28+
Supporting arbitrarily nested expressions within other expressions requires:
29+
30+
31+
* Updating the grammar to remove `non-branched-expr`
32+
33+
34+
* Updating compliance tests to add various permutations of the grammar to
35+
ensure implementations are compliant.
36+
37+
38+
* Updating the JMESPath documentation to reflect the ability to arbitrarily
39+
nest expressions.
40+
41+
## Nested Expression Examples
42+
43+
### Nested branch expressions
44+
45+
Given:
46+
47+
```json
48+
{
49+
"foo": {
50+
"baz": [
51+
{
52+
"bar": "abc"
53+
}, {
54+
"bar": "def"
55+
}
56+
],
57+
"qux": ["zero"]
58+
}
59+
}
60+
```
61+
62+
With: `foo.[baz[\*].bar, qux[0]]`
63+
64+
Result:
65+
66+
```json
67+
[
68+
[
69+
"abc",
70+
"def"
71+
],
72+
"zero"
73+
]
74+
```
75+
76+
### Nested branch expressions with nested mutli-select
77+
78+
Given:
79+
80+
```json
81+
{
82+
"foo": {
83+
"baz": [
84+
{
85+
"bar": "a",
86+
"bam": "b",
87+
"boo": "c"
88+
}, {
89+
"bar": "d",
90+
"bam": "e",
91+
"boo": "f"
92+
}
93+
],
94+
"qux": ["zero"]
95+
}
96+
}
97+
```
98+
99+
With: `foo.[baz[\*].[bar, boo], qux[0]]`
100+
101+
Result:
102+
103+
```json
104+
[
105+
[
106+
[
107+
"a",
108+
"c"
109+
],
110+
[
111+
"d",
112+
"f"
113+
]
114+
],
115+
"zero"
116+
]
117+
```
118+
119+
### Nested or expressions
120+
121+
Given:
122+
123+
```json
124+
{
125+
"foo": {
126+
"baz": [
127+
{
128+
"bar": "a",
129+
"bam": "b",
130+
"boo": "c"
131+
}, {
132+
"bar": "d",
133+
"bam": "e",
134+
"boo": "f"
135+
}
136+
],
137+
"qux": ["zero"]
138+
}
139+
}
140+
```
141+
142+
With: `foo.[baz[\*].not_there || baz[\*].bar, qux[0]]`
143+
144+
Result:
145+
146+
```json
147+
[
148+
[
149+
"a",
150+
"d"
151+
],
152+
"zero"
153+
]
154+
```
155+
156+
### No breaking changes
157+
158+
Because there are no breaking changes from this modification, existing
159+
multi-select expressions will still work unchanged:
160+
161+
Given:
162+
163+
```json
164+
{
165+
"foo": {
166+
"baz": {
167+
"abc": 123,
168+
"bar": 456
169+
}
170+
}
171+
}
172+
```
173+
174+
With: `foo.[baz, baz.bar]`
175+
176+
Result:
177+
178+
```json
179+
[
180+
{
181+
"abc": 123,
182+
"bar": 456
183+
},
184+
456
185+
]
186+
```
187+
188+
## Modified Grammar
189+
190+
The following modified JMESPath grammar supports arbitrarily nested expressions
191+
and is specified using ABNF, as described in [RFC4234](https://tools.ietf.org/html/rfc4234)
192+
193+
```
194+
expression = sub-expression / index-expression / or-expression / identifier / "*"
195+
expression =/ multi-select-list / multi-select-hash
196+
sub-expression = expression "." expression
197+
or-expression = expression "||" expression
198+
index-expression = expression bracket-specifier / bracket-specifier
199+
multi-select-list = "[" ( expression *( "," expression ) ) "]"
200+
multi-select-hash = "{" ( keyval-expr *( "," keyval-expr ) ) "}"
201+
keyval-expr = identifier ":" expression
202+
bracket-specifier = "[" (number / "*") "]"
203+
number = [-]1*digit
204+
digit = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / "0"
205+
identifier = 1*char
206+
identifier =/ quote 1*(unescaped-char / escaped-quote) quote
207+
escaped-quote = escape quote
208+
unescaped-char = %x30-10FFFF
209+
escape = %x5C ; Back slash: \
210+
quote = %x22 ; Double quote: '"'
211+
char = %x30-39 / ; 0-9
212+
%x41-5A / ; A-Z
213+
%x5F / ; _
214+
%x61-7A / ; a-z
215+
%x7F-10FFFF
216+
```

0 commit comments

Comments
 (0)