WHITESPACE = _{ " " | "\t" | "\r\n" | "\n"}
StringLit = _{ StringLitDq | StringLitSq }
StringLitDq = _{ "\"" ~ StringDq ~ "\"" }
StringLitSq = _{ "'" ~ StringSq ~ "'" }
StringDq = { (("\\" ~ ("\"" | "\\")) | (!"\"" ~ ANY))* }
StringSq = { (("\\" ~ ("'" | "\\")) | (!"'" ~ ANY))* }
ElementAccess = _{ ("." ~ Key) | KeyBrackets }
Index = _{ ASCII_DIGIT+ }
Key = _{ (ASCII_ALPHANUMERIC | "_")* }
KeyBrackets = _{ "[" ~ (StringLit | Index) ~ "]" }
SubPath = _{ Key ~ ElementAccess* }
Path = @{ SubPath }
Value = @{ (Null | Boolean | Number | String | Array | Object) }
Boolean = @{ "true" | "false" }
Null = @{ "null" }
String = @{ StringLit }
Number = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) ~ ("." ~ ASCII_DIGIT+)? ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)? }
Array = @{ "[" ~ (Value ~ ("," ~ Value)*)* ~ "]" }
Object = @{ "{" ~ (ObjectInner ~ ("," ~ ObjectInner)*)* ~ "}" }
ObjectKey = { WHITESPACE* ~ StringDq ~ WHITESPACE* }
ObjectInner = { ObjectKey ~ ":" ~ Value }
Statement = { Path ~ "=" ~ Value ~ ";"? }
Statements = _{ SOI ~ Statement* ~ EOI }