//
// Generated from the ABNF at https://awslabs.github.io/smithy/1.0/spec/core/selectors.html
//
input =
{ SOI ~ selector ~ EOI }
selector =
{ selector_expression+ }
selector_expression =
{ selector_shape_types
| selector_attr
| selector_scoped_attr
| selector_function // <-- this was `selector_function_args` which was bad
| selector_forward_directed_neighbor
| selector_reverse_directed_neighbor
| selector_forward_undirected_neighbor
| selector_reverse_undirected_neighbor
| selector_forward_recursive_neighbor
| selector_variable_set
| selector_variable_get }
selector_shape_types =
{ "*" | identifier }
selector_forward_undirected_neighbor =
{ ">" }
selector_reverse_undirected_neighbor =
{ "<" }
selector_forward_directed_neighbor =
{ "-[" ~ selector_directed_relationships ~ "]->" }
selector_reverse_directed_neighbor =
{ "<-[" ~ selector_directed_relationships ~ "]-" }
selector_directed_relationships =
{ identifier ~ ("," ~ identifier)* }
selector_forward_recursive_neighbor =
{ "~>" }
selector_attr =
{ "[" ~ selector_key ~ selector_attr_comparison? ~ "]" }
selector_attr_comparison =
{ selector_comparator ~ selector_attr_values ~ case_comparison_suffix? }
case_comparison_suffix = { "i" }
selector_key =
{ identifier ~ ("|" ~ selector_path)? }
selector_path =
{ selector_path_segment ~ ("|" ~selector_path_segment)* }
selector_path_segment =
{ selector_value | selector_function_property }
selector_value =
{ selector_text | number | root_shape_id }
selector_function_property =
{ "(" ~ identifier ~ ")" }
selector_attr_values =
{ selector_value ~ ("," ~ selector_value)* }
selector_comparator =
{ selector_string_comparator
| selector_numeric_comparator
| selector_projection_comparator }
selector_string_comparator =
{ comparator_string_eq
| comparator_string_neq
| comparator_string_starts
| comparator_string_ends
| comparator_string_in
| comparator_string_exist }
comparator_string_eq = { "=" }
comparator_string_neq = { "!=" }
comparator_string_starts = { "^=" }
comparator_string_ends = { "$=" }
comparator_string_in = { "*=" }
comparator_string_exist = { "?=" }
selector_numeric_comparator =
{ comparator_number_gt
| comparator_number_gte
| comparator_number_lt
| comparator_number_lte }
comparator_number_gt = { ">" }
comparator_number_gte = { ">=" }
comparator_number_lt = { "<" }
comparator_number_lte = { "<=" }
selector_projection_comparator =
{ comparator_projection_eq
| comparator_projection_neq
| comparator_projection_subset
| comparator_projection_proper }
comparator_projection_eq = { "{=}" }
comparator_projection_neq = { "{!=}" }
comparator_projection_subset = { "{<}" }
comparator_projection_proper = { "{<<}" }
selector_scoped_attr =
{ "[@" ~ selector_key? ~ ":" ~ selector_scoped_assertions ~"]" }
selector_scoped_assertions =
{ selector_scoped_assertion ~ ("&&" ~ selector_scoped_assertion)* }
// | ---^
// = Was missing any cardinality constraint
selector_scoped_assertion =
{ selector_scoped_value ~ selector_comparator ~ selector_scoped_values ~ case_comparison_suffix? }
selector_scoped_value =
{ selector_value | selector_context_value }
selector_context_value =
{ "@{" ~ selector_path ~ "}" }
selector_scoped_values =
{ selector_scoped_value ~ ("," ~ selector_scoped_value)* }
selector_function =
{ ":" ~ identifier ~ "(" ~ selector_function_args ~ ")" }
selector_function_args =
{ selector ~ ("," ~ selector)* }
// ^--- renamed from simply `selector` to avoid SOI/EOI
selector_text =
{ selector_single_quoted_text | selector_double_quoted_text }
selector_single_quoted_text =
@{ "'" ~ selector_single_quoted_char+ ~ "'" }
selector_double_quoted_text =
@{ "\"" ~ selector_double_quoted_char+ ~ "\""}
selector_single_quoted_char =
{ '\u{20}'..'\u{26}' | '\u{28}'..'\u{5B}' | '\u{5D}'..'\u{10FFFF}' }
selector_double_quoted_char =
{ '\u{20}'..'\u{21}' | '\u{23}'..'\u{5B}' | '\u{5D}'..'\u{10FFFF}' }
selector_variable_set =
{ "$" ~ identifier ~ "(" ~ selector ~ ")" }
selector_variable_get =
{ "${" ~ identifier ~ "}" }
// ------------------------------------------------------------------------------------------------
// Copied over from Smithy.pest
// ------------------------------------------------------------------------------------------------
identifier =
@{ ( ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* )
| ( "_" ~ ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_")*) }
namespace =
@{ identifier ~ ("." ~ identifier)* }
root_shape_id =
{ absolute_root_shape_id | identifier }
absolute_root_shape_id =
@{ namespace ~ "#" ~ identifier }
number =
@{ minus? ~ int ~ fraction? ~ exp?}
decimal_point =
{ "." }
e =
{ "e" | "E" }
exp =
{ e ~ (minus | plus)? ~ ASCII_DIGIT+ }
fraction =
{ decimal_point ~ ASCII_DIGIT+ }
int =
{ zero | (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) }
minus =
{ "-" }
plus =
{ "+" }
zero =
{ "0" }
// ------------------------------------------------------------------------------------------------
// Allows default whitespace handling
// ------------------------------------------------------------------------------------------------
WHITESPACE = _{ " " | "\t" | "\n" }