atelier_smithy 0.2.7

Rust native Smithy language format for the AWS Smithy IDL.
Documentation
idl =
    { SOI ~ ws ~ control_section ~ metadata_section ~ shape_section ~ EOI }

ws =
    _{ (sp | NEWLINE | (!("///") ~ line_comment | ",") )* }

sp =
    _{ " " | "\t" }

br =
    _{ ws ~ EOI? }

line_comment =
    _{ "//" ~ ("\t" | '\u{20}'..'\u{10FFF}')* ~ NEWLINE }

documentation_comment =
    _{ ws ~ "///" ~ documentation_text ~ NEWLINE }

documentation_text =
    { ("\t" | '\u{20}'..'\u{10FFF}')* }

control_section =
    { control_statement* }

control_statement =
    { "$" ~ ws ~ node_object_key ~ ws ~ ":" ~ ws ~ node_value ~ ws }

version_string =
    { ASCII_DIGIT+ ~ ( "." ~ ASCII_DIGIT+ )? }

shape_id =
    @{ root_shape_id ~ shape_id_member? }

root_shape_id =
    { absolute_root_shape_id | identifier }

absolute_root_shape_id =
    { namespace ~ "#" ~ identifier }

namespace =
    @{ identifier ~ ("." ~ identifier)* }

identifier =
    @{ ( ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* )
    |  ( "_" ~ ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_")*) }

shape_id_member =
    { "$" ~ identifier }

node_value =
    { node_array | node_object | number | node_keywords | shape_id | text_block | quoted_text }

node_array =
    { "[" ~ ws ~ (node_value ~ ws)* ~ "]" }
//    { empty_node_array | populated_node_array }
//
// empty_node_array =
//     { "[" ~ ws ~ "]" }
//
// populated_node_array =
//     { "[" ~ ws ~ node_value ~ ws ~ (comma ~ node_value ~ ws)* ~ trailing_comma ~ "]" }

trailing_comma =
    _{ comma? }

comma =
    _{ "," ~ ws }

node_object =
    { "{" ~ ws ~ (node_object_kvp ~ ws)*  ~ "}" }
//    _{ empty_node_object | populated_node_object }
//
// empty_node_object =
//     { "{" ~ ws ~ "}" }
//
// populated_node_object =
//     { "{" ~ ws ~ node_object_kvp ~  ws ~ (comma ~ node_object_kvp ~ ws)* ~ trailing_comma ~ "}" }

node_object_kvp =
    { node_object_key ~ ws ~ ":" ~ ws ~ node_value }

node_object_key =
    _{ quoted_text | identifier }

number =
    { minus? ~ int ~ frac? ~ exp?}

decimal_point =
    { "."}

e =
    { "e" | "E" }

exp =
    { e ~ (minus | plus)? ~ ASCII_DIGIT+ }

frac =
    { decimal_point ~ ASCII_DIGIT+ }

int =
    { zero | (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) }

minus =
    { "-" }

plus =
    { "+" }

zero =
    { "0" }

node_keywords =
    _{ kw_true | kw_false | kw_null }

kw_true = { "true" }

kw_false = { "false" }

kw_null = { "null" }

quoted_text =
    { DQUOTE ~ quoted_chars ~ DQUOTE }

quoted_chars =
    @{ ('\u{20}'..'\u{21}' | '\u{23}'..'\u{5B}' | '\u{5D}'..'\u{10FFF}' | escaped_char | preserved_double)* }

escaped_char =
    {escape ~ (escape | "'" | DQUOTE | "b" | "f" | "n" | "r" | "t" | "/" | unicode_escape) }

unicode_escape =
    { "u" ~ ASCII_HEX_DIGIT ~ ASCII_HEX_DIGIT ~ ASCII_HEX_DIGIT ~ ASCII_HEX_DIGIT }

preserved_double =
    { escape ~ ('\u{20}'..'\u{21}' | '\u{23}'..'\u{5B}' | '\u{5D}'..'\u{10FFF}') }

escape =
    { "\\" }

text_block =
    { DQUOTE{3} ~ br ~ block_quoted_chars ~ DQUOTE{3} }

// three_dquotes =
//     _{ DQUOTE ~ DQUOTE ~ DQUOTE }

block_quoted_chars =
    @{ ( !("\"\"\"") ~ DQUOTE | sp | NEWLINE | '\u{20}'..'\u{21}' | '\u{23}'..'\u{5B}' | '\u{5D}'..'\u{10FFF}' | escaped_char | preserved_double)* }

DQUOTE =
    _{ "\"" }

shape_section =
    { ( namespace_statement ~ (use_section)? ~ (shape_statements)? )? }

namespace_statement =
    { "namespace" ~ ws ~ namespace ~ ws }

use_section =
    { use_statement+ }

use_statement =
    { "use" ~ ws ~ absolute_root_shape_id ~ ws }

shape_statements =
    { (shape_statement | apply_statement)+ }

shape_statement =
    { documentation_comment* ~ ws ~ trait_statements ~ shape_body ~ ws}

shape_body =
    _{ simple_shape_statement | list_statement | set_statement | map_statement | structure_statement
    |  union_statement | service_statement | operation_statement | resource_statement }

simple_shape_statement =
    { simple_type_name ~ ws ~ identifier }

simple_type_name =
    _{ type_blob | type_boolean | type_document | type_string | type_byte | type_short | type_integer | type_long
    | type_float | type_double | type_big_integer | type_big_decimal | type_timestamp }

type_blob = { "blob" }

type_boolean = {"boolean"}

type_document = {"document"}

type_string = {"string"}

type_byte = {"byte"}

type_short = {"short"}

type_integer = {"integer"}

type_long = {"long"}

type_float = {"float"}

type_double = {"double"}

type_big_integer = {"bigInteger"}

type_big_decimal = {"bigDecimal"}

type_timestamp = {"timestamp"}

shape_members =
    { "{" ~ ws ~ (shape_member_kvp ~ ws)* ~ "}" }
//    _{ empty_shape_members | populated_shape_members }
//
// empty_shape_members =
//     { "{" ~ ws ~ "}" }
//
// populated_shape_members =
//     { "{" ~ ws ~ shape_member_kvp ~ ws ~ (comma ~ shape_member_kvp ~ ws)* ~ trailing_comma ~ ws ~ "}" }

shape_member_kvp =
    { documentation_comment* ~ ws ~ trait_statements ~ identifier ~ ws ~ ":" ~ ws ~ shape_id }

list_statement =
    { "list" ~ ws ~ identifier ~ ws ~ shape_members }

set_statement =
    { "set" ~ ws ~ identifier ~ ws ~ shape_members }

map_statement =
    { "map" ~ ws ~ identifier ~ ws ~ shape_members }

structure_statement =
    { "structure" ~ ws ~ identifier ~ ws ~ shape_members }

union_statement =
    { "union" ~ ws ~ identifier ~ ws ~ shape_members }

service_statement =
    { "service" ~ ws ~ identifier ~ ws ~ node_object }

operation_statement =
    {"operation" ~ ws ~ identifier ~ ws ~ node_object}

resource_statement =
    { "resource" ~ ws ~ identifier ~ ws ~ node_object }

apply_statement =
    { "apply" ~ ws ~ shape_id ~ ws ~ a_trait ~ ws}

trait_statements =
     { (ws ~ a_trait)* ~ ws }

a_trait =
    { "@" ~ shape_id ~ trait_body? }

trait_body =
//     _{ empty_trait_body | populated_trait_body }
//
// empty_trait_body =
//     _{ "(" ~ ws ~  ")" }
//
// populated_trait_body =
    _{ "(" ~ ws ~ (trait_body_value ~ ws)* ~ ")" }

trait_body_value =
    _{ trait_structure | node_value }

trait_structure =
    _{ trait_structure_kvp ~ (ws ~ trait_structure_kvp)* }

trait_structure_kvp =
    { node_object_key ~ ws ~ ":" ~ ws ~ node_value }

metadata_section =
    { metadata_statement* }

metadata_statement =
    { "metadata" ~ ws ~ node_object_key ~ ws ~ "=" ~ ws ~ node_value ~ ws }