conflag 0.1.1

A simple and powreful configuration language, extending JSON with declarative and functional language features.
Documentation
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }

object = {
    "{" ~ "}" |
    "{" ~ pair ~ ("," ~ pair)* ~ ","? ~ "}"
}
pair = { name ~ ":" ~ expression | string ~ ":" ~ expression }

array = {
    "[" ~ "]" |
    "[" ~ expression ~ ("," ~ expression)* ~ ","? ~ "]"
}

expression = _{
    binops
    | lambda
    | atom
    | "(" ~ expression ~ ")"
}

primitive = _{ object | array | string | number | boolean | null }

atom = { (patch_map | patch | primitive | name | "(" ~ expression ~ ")") ~ (atom_attribute | atom_function_call )* }
atom_attribute = {"." ~ (name | string) }
atom_function_call = {"(" ~ expression_list ~ ")"}
expression_list = { expression ~ ("," ~ expression)* ~ ","? }

patch = { "&" ~ atom }
patch_map = { "&&" ~ atom }

lambda = { "(" ~ arg_list ~ ")" ~ "=>" ~ expression }
arg_list = { (name ~ ",")* ~ (name ~ ","?)? }

binops = { atom ~ (binop ~ atom)+ }
binop = { "+" | "-" | "*" | "/" | ">=" | ">" | "<=" | "<" | "==" | "!=" }

name = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }

boolean = { "true" | "false" }

null = { "null" }

string = @{ "\"" ~ string_inner ~ "\"" }
string_inner = ${ char* }
char = {
    !("\"" | "\\") ~ ANY
    | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
    | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}

number = @{
    "-"?
    ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)
    ~ ("." ~ ASCII_DIGIT*)?
    ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
}

/// TODO: allow naked pairs in file
file = _{ SOI ~ expression ~ EOI }