dbml-rs 1.0.1

A DBML parser for Rust.
Documentation
WHITESPACE = _{ " " | "\t" | NEWLINE }
COMMENT = _{ single_line_comment | multi_line_comment }

// comments
single_line_comment = { "//" ~ (!NEWLINE ~ ANY)* }
multi_line_comment = { "/*" ~ (!"*/" ~ ANY)* ~ "*/" }

// literals
double_quoted_value = @{ (!"\"" ~ ANY)* }
double_quoted_string = { "\"" ~ double_quoted_value ~ "\"" }
single_quoted_value = @{ (!"'" ~ ANY)* }
single_quoted_string = { "'" ~ single_quoted_value ~ "'"}
backquoted_quoted_value = @{ (!"`" ~ ANY)* }
backquoted_quoted_string = { "`" ~ backquoted_quoted_value ~ "`" }
triple_quoted_value = @{ (!"'''" ~ ANY)* }
triple_quoted_string = { "'''" ~ triple_quoted_value ~ "'''" }

var = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
spaced_var = @{ ASCII_ALPHA ~ (" "? ~ (ASCII_ALPHANUMERIC | "_"))* }

ident = { var | double_quoted_string }

// attributes and properties
property = { spaced_var ~ ":" ~ (value | spaced_var) }
attribute = { spaced_var ~ (":" ~ (value | spaced_var | double_quoted_string))? }
block_settings = { "[" ~ (attribute ~ ("," ~ attribute)*)? ~ "]" }

// values
string_value = { triple_quoted_string | single_quoted_string }
integer = @{ ASCII_DIGIT+ }
decimal = @{ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT* }
number_value = { decimal | integer }
boolean_value = @{ "true" | "false" | "null" }
hex_value = @{ "#" ~ (ASCII_HEX_DIGIT{3}){1,2} }
value = { string_value | backquoted_quoted_string | boolean_value | number_value | hex_value }

// top-level ident
decl_ident = { ident ~ ("." ~ ident)? }

// ref block
relation = @{ "<>" | "-" | ">" | "<" }
rel_settings = { "[" ~ (attribute ~ ("," ~ attribute)*)? ~ "]" }
ref_composition = { ident | ("(" ~ ident ~ ("," ~ ident)* ~ ")") }
ref_ident = { ident ~ "." ~ (ident ~ ".")? ~ ref_composition }
ref_inline = { "ref" ~ ":" ~ relation ~ ref_ident }
ref_stmt = { ref_ident ~ relation ~ ref_ident ~ rel_settings? }
ref_short = { ^"Ref" ~ ident? ~ ":" ~ ref_stmt }
ref_block = { ^"Ref" ~ ident? ~ "{" ~ ref_stmt ~ "}" }
ref_decl = { ref_block | ref_short }

// note block
note_inline = { "note" ~ ":" ~ string_value }
note_short = { ^"Note" ~ ":" ~ string_value }
note_block = { ^"Note" ~ "{" ~ string_value ~ "}" }
note_decl = { note_short | note_block }

// indexes block
indexes_settings = { "[" ~ (attribute ~ ("," ~ attribute)*)? ~ "]" }
indexes_ident = { ident | backquoted_quoted_string }
indexes_multi = { "(" ~ (indexes_ident ~ ("," ~ indexes_ident)*)? ~ ")" ~ indexes_settings? }
indexes_single = { indexes_ident ~ indexes_settings? }
indexes_block = { "{" ~ (indexes_single | indexes_multi)* ~ "}" }
indexes_decl = { ^"Indexes" ~ indexes_block }

// enum block
enum_settings = { "[" ~ (attribute ~ ("," ~ attribute)*)? ~ "]" }
enum_value = { ident ~ enum_settings? }
enum_block = { "{" ~ enum_value* ~ "}" }
enum_decl = { ^"Enum " ~ decl_ident ~ enum_block }

// table block
col_attribute = { ref_inline | attribute }
col_settings = { "[" ~ (col_attribute ~ ("," ~ col_attribute)*)? ~ "]" }
col_type_arg = { "(" ~ (value ~ ("," ~ value)*)? ~ ")" }
col_type_array = { "[" ~ integer? ~ "]" }
col_type_unquoted = ${ var ~ col_type_arg? ~ col_type_array* }
col_type_quoted = ${ "\"" ~ spaced_var ~ col_type_arg? ~ col_type_array* ~ "\"" ~ col_type_array* }
col_type = ${ (ident ~ ".")? ~ (col_type_quoted | col_type_unquoted ) }
table_col = { ident ~ col_type ~ col_settings? }
table_block = { "{" ~ (table_col | note_decl | indexes_decl)* ~ "}" }
table_alias = { ^"as " ~ ident }
table_decl = { ^"Table " ~ decl_ident ~ table_alias? ~ block_settings?  ~ table_block }

// table group block
table_group_block = { "{" ~ (note_decl | decl_ident)* ~ "}" }
table_group_decl = { ^"TableGroup " ~ ident ~ block_settings? ~ table_group_block }

// project block
project_block = { "{" ~ (note_decl | property)* ~ "}" }
project_decl = { ^"Project " ~ ident ~ project_block }

schema = { SOI ~ (project_decl | table_decl | enum_decl | ref_decl | table_group_decl | note_decl)* ~ EOI }