Skip to content

Instantly share code, notes, and snippets.

@springcomp
Last active April 10, 2023 10:19
Show Gist options
  • Save springcomp/cf7d8daa93f93f045bbc266c49ebe797 to your computer and use it in GitHub Desktop.
Save springcomp/cf7d8daa93f93f045bbc266c49ebe797 to your computer and use it in GitHub Desktop.
EBNF grammar for JMESPath
<expression> ::= <sub_expression>
| <index_expression>
| <comparator_expression>
| <list_filter_expression>
| <or_expression>
| <identifier>
| <and_expression>
| <not_expression>
| <paren_expression>
| <multi_select_list>
| <multi_select_hash>
| <literal>
| <function_expression>
| <pipe_expression>
| <raw_string>
| <current_node>
| <hash_wildcard_expression>
| <arithmetic_expression>
<sub_expression> ::= <expression> "." ( <identifier> | <multi_select_list> | <multi_select_hash> | <function_expression> | <hash_wildcard_expression> )
<comparator_expression> ::= <expression> <comparator> <expression>
<list_filter_expression> ::= "[?" <expression> "]"
<or_expression> ::= <expression> "||" <expression>
<and_expression> ::= <expression> "&&" <expression>
<identifier> ::= <unquoted_string> | <quoted_string>
<not_expression> ::= "!" <expression>
<paren_expression> ::= "(" <expression> ")"
<pipe_expression> ::= <expression> "|" <expression>
<current_node> ::= "@"
<hash_wildcard_expression> ::= "*"
<index_expression> ::= <expression> <bracket_specifier>
| <bracket_specifier>
<bracket_specifier> ::= "[" ( <number> | <slice_expression> ) "]"
| <flatten_expression>
| <list_filter_expression>
| <list_wildcard_expression>
<flatten_expression> ::= "[]"
<list_wildcard_expression> ::= "[*]"
<slice_expression> ::= <number>? ":" <number>? ( ":" <number>? )?
<number> ::= "-"? <digit>+
<literal> ::= "`" <json_value> "`"
<comparator> ::= ">" | ">=" | "==" | "!=" | "<" | "<="
<function_expression> ::= <unquoted_string> ( <no_args> | <one_or_more_args> )
<no_args> ::= "(" ")"
<one_or_more_args> ::= "(" <function_arg> ( "," <function_arg> )* ")"
<function_arg> ::= <expression> | <expression_type>
<expression_type> ::= "&" <expression>
<multi_select_list> ::= "[" <expression> ( "," <expression> )* "]"
<multi_select_hash> ::= "{" <keyval_expression> ("," <keyval_expression> )* "}"
<keyval_expression> ::= <identifier> ":" <expression>
<arithmetic_expression> ::= ( "+" | "-" ) <expression>
| <expression> ( "+" | "-" | "*" | "/" | "%" | "//" ) <expression>
<raw_string> ::= "'" ( <raw_string_char> | <raw_string_preserved_escape> | <raw_string_escape> )* "'"
<unquoted_string> ::= <letter> ( <letter> | <digit> )*
<raw_string_char> ::= <digit> | <letter> | <quote> | " " | "!" | "#" | "$" | "%" | "&" | "(" | ")" | "*+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~"
<raw_string_escape> ::= <escape> ( "'" | <escape> )
<raw_string_preserved_escape> ::= <escape> <raw_string_char>
<quoted_string> ::= <quote> ( <unescaped_char> | <escaped_char> )+ <quote>
<escaped_char> ::= <escape> ( "\"" | "/" | "b" | "f" | "n" | "r" | "t" | <unicode> | <escape> )
<escaped_literal> ::= <escaped_char> | <escape> "`"
<unescaped_char> ::= <digit> | <letter> | " " | "!" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~"
<unescaped_literal> ::= <digit> | <letter> | " " | "!" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "{" | "|" | "}" | "~"
<unicode> ::= "u" <digit> <digit> <digit> <digit>
<escape> ::= "\\"
<digit> ::= [0-9]
<letter> ::= [A-Z] | [a-z] | "_"
<quote> ::= "\""
/* The ``json-value`` is any valid JSON value with the one exception that the */
/* ``%x60`` character must be escaped. While it's encouraged that implementations */
/* use any existing JSON parser for this grammar rule (after handling the escaped */
/* literal characters), the grammar rule is shown below for completeness:: */
<json_value> ::= <json_array>
| <json_boolean>
| <json_null>
| <json_number>
| <json_object>
| <json_string>
<json_null> ::= "null"
<json_boolean> ::= "true" | "false"
<json_number> ::= "-"? ( "0" | [1-9] [0-9]* ) ( "." [0-9]+ )? ( "e" ( "-" | "+" ) [0-9]+ )?
<json_array> ::= <ws> "[" ( <ws> <json_value> <ws> ( "," <ws> <json_value> <ws> )* )? "]" <ws>
<json_object> ::= <ws> "{" <ws> ( <member> <ws> ( "," <ws> <member> <ws> )* )? "}" <ws>
<json_string> ::= <quote> ( <unescaped_literal> | <escaped_literal> )* <quote>
<member> ::= <quoted_string> <ws> ":" <ws> <json_value>
<ws> ::= " "*
// JMESPath PEG grammar
// for use with pest
// https://pest.rs/book/
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
expression = {
identifier
}
identifier
/* This a simplified version of the grammar that takes little time to compile */
/* It is mostly complete, except the `literal` rule which is simplified */
<expression> ::= <sub_expression>
| <index_expression>
| <comparator_expression>
| <list_filter_expression>
| <or_expression>
| <identifier>
| <and_expression>
| <not_expression>
| <paren_expression>
| <multi_select_list>
| <multi_select_hash>
| <literal>
| <function_expression>
| <pipe_expression>
| <raw_string>
| <current_node>
| <hash_wildcard_expression>
| <arithmetic_expression>
<sub_expression> ::= <expression> "." ( <identifier> | <multi_select_list> | <multi_select_hash> | <function_expression> | <hash_wildcard_expression> )
<comparator_expression> ::= <expression> <comparator> <expression>
<list_filter_expression> ::= "[?" <expression> "]"
<or_expression> ::= <expression> "||" <expression>
<and_expression> ::= <expression> "&&" <expression>
<identifier> ::= <unquoted_string> | <quoted_string>
<not_expression> ::= "!" <expression>
<paren_expression> ::= "(" <expression> ")"
<pipe_expression> ::= <expression> "|" <expression>
<current_node> ::= "@"
<hash_wildcard_expression> ::= "*"
<index_expression> ::= <expression> <bracket_specifier>
| <bracket_specifier>
<bracket_specifier> ::= "[" ( <number> | <slice_expression> ) "]"
| <flatten_expression>
| <list_filter_expression>
| <list_wildcard_expression>
<flatten_expression> ::= "[]"
<list_wildcard_expression> ::= "[*]"
<slice_expression> ::= <number>? ":" <number>? ( ":" <number>? )?
<number> ::= "-"? <digit>+
<literal> ::= "`" <letter> "`"
<comparator> ::= ">" | ">=" | "==" | "!=" | "<" | "<="
<function_expression> ::= <unquoted_string> ( <no_args> | <one_or_more_args> )
<no_args> ::= "(" ")"
<one_or_more_args> ::= "(" <function_arg> ( "," <function_arg> )* ")"
<function_arg> ::= <expression> | <expression_type>
<expression_type> ::= "&" <expression>
<multi_select_list> ::= "[" <expression> ( "," <expression> )* "]"
<multi_select_hash> ::= "{" <keyval_expression> ("," <keyval_expression> )* "}"
<keyval_expression> ::= <identifier> ":" <expression>
<arithmetic_expression> ::= ( "+" | "-" ) <expression>
| <expression> ( "+" | "-" | "*" | "/" | "%" | "//" ) <expression>
<raw_string> ::= "'" ( <raw_string_char> | <raw_string_preserved_escape> | <raw_string_escape> )* "'"
<unquoted_string> ::= <letter> ( <letter> | <digit> )*
<raw_string_char> ::= <digit> | <letter> | <quote> | " " | "!" | "#" | "$" | "%" | "&" | "(" | ")" | "*+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~"
<raw_string_escape> ::= <escape> ( "'" | <escape> )
<raw_string_preserved_escape> ::= <escape> <raw_string_char>
<quoted_string> ::= <quote> ( <unescaped_char> | <escaped_char> )+ <quote>
<escaped_char> ::= <escape> ( "\"" | "/" | "b" | "f" | "n" | "r" | "t" | <unicode> | <escape> )
<unescaped_char> ::= <digit> | <letter> | " " | "!" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~"
<unicode> ::= "u" <digit> <digit> <digit> <digit>
<escape> ::= "\\"
<digit> ::= [0-9]
<letter> ::= [A-Z] | [a-z] | "_"
<quote> ::= "\""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment