yamis 1.2.0

Task runner for teams and individuals.
Documentation
WHITESPACE = _{ " " }
RANGE_SEPARATOR = _{ ":" }

// Parses positional arg inside tag and functions
digits = @{ ASCII_DIGIT+}
integer = @{ ("+" | "-")? ~ digits }

// Modifiers that can be applied to args, kwargs and env_var
optional = { "?" }

index = { integer }
range_from = { integer }
range_to = { integer }
range = { range_from? ~ RANGE_SEPARATOR ~ range_to? }

slice = { "[" ~ (range | index) ~ "]"}

// Positonal arg, i.e. $1 $2
arg = ${"$" ~ digits }
// Star inside tag, i.e. * or *?
all_args = ${ "$@" }

// Parses named arguments inside tag and functions
kwarg_name = { ( "_" | ASCII_ALPHA ) ~ ("_" | "-" | ASCII_ALPHANUMERIC )* }
kwarg = ${ kwarg_name }

// Parses env var inside tag
env_var_name = @{ ( "_" | ASCII_ALPHA ) ~ ( "_" | "-" | ASCII_ALPHANUMERIC )*}
env_var = ${ "$" ~ env_var_name }


// Parses fun inside tag
fun_name = @{ ( "_" | ASCII_ALPHA ) ~ ( "_" | ASCII_ALPHANUMERIC )* }
expression_inner = ${ all_args | fun | kwarg | arg | env_var | string }
expression = { expression_inner ~ slice* ~ optional? }
fun_params = { expression ~ (WHITESPACE* ~ "," ~ WHITESPACE* ~ expression)* }
fun = ${ fun_name ~ "(" ~ WHITESPACE* ~ fun_params? ~ WHITESPACE* ~ ")" }

// Tag, that can contain either a fun, arg, kwarg, end_var or star
tag = { "{" ~ WHITESPACE* ~ expression ~ WHITESPACE* ~ "}" }

// Escape values inside string
special_val = { "n" | "r" | "t" | "\\" | "0" | "'" | "\"" }
escape     = { "\\" ~ special_val }

// Parses string inside tag
string_content = { (!("\\" | PEEK | NEWLINE ) ~ ANY)+ }
string = ${ PUSH("'" | "\"") ~ (string_content | escape)* ~ POP }

// Escape open and close brackets in literal
esc_ob = { "{{" }
esc_cb = { "}}" }

literal_content = {(!("{" | "}") ~ ANY)+}
// values outside tag
literal = { literal_content | ( esc_ob | esc_cb )}

// Multiline comment outside tag
comment = _{ "{/" ~ (!"/}" ~ ANY)* ~ "/}" }

// Parses the whole string, empty strings allowed
all = ${ SOI ~ (comment | tag | literal)* ~ EOI }

// Matches a task argument, which can be either a task or literal, or empty
task_arg = ${ SOI ~ (tag | literal+)? ~ EOI }