WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }
object = {
"{"
~ object_value*
~ "}"
}
object_value = _{
pair | spread
}
spread = {
".." ~ input
}
array = {
"["
~ array_value*
~ "]"
}
array_value = _{
value | spread
}
pair = { path ~ "=" ~ value }
path = ${
path_seg
~ ( "." ~ path_seg )*
}
path_seg = _{
integer | quoted_path_seg | regular_path_seg
}
quoted_path_seg = ${ "'" ~ quoted_path_val ~ "'" }
quoted_path_val = ${ quoted_path_char + }
quoted_path_char = _{
!("'" | "\\") ~ ANY
| "\\" ~ "'"
}
regular_path_seg = ${ path_char + }
path_char = _{ !( WHITESPACE | "=" | "." ) ~ ANY }
value = _{ object | array | input | string | float | integer | boolean | null }
boolean = { "true" | "false" }
null = { "null" }
string = ${
"\"" ~ string_val ~ "\""
}
string_val = ${ (input | char)* }
char = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "n" | "r" | "t" | "$")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
integer = ${
hex_integer | decimal_integer
}
decimal_integer = @{
"-"?
~ ("0" | ASCII_NONZERO_DIGIT ~ ("_"? ~ ASCII_DIGIT)*)
}
hex_integer = @{
"0x" ~ ASCII_HEX_DIGIT+
}
float = @{
"-"?
~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)
~ ("." ~ ASCII_DIGIT*)
~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
}
input = ${ !"\\" ~ "$" ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")+ }
assignment = { input ~ "=" ~ value }
assign_block = { "let" ~ "{" ~ assignment* ~ "}" ~ "in" }
config = _{ SOI ~ assign_block? ~ object ~ EOI }