bevy_htn 0.0.1

A bevy hierarchical task network, using bevy_behave trees as operators
Documentation
EOL = _{("\n" | EOI)}
WHITESPACE = _{ " " | "\t" | "\r" }
COMMENT = _{ ("//"|"#") ~ (!"\n" ~ ANY)* ~ EOL }

schema                 =  { EOL? ~ "schema" ~ "{" ~ EOL? ~ (COMMENT | schema_version_statement)+ ~ "}" ~ EOL }
primitive_task         =  { EOL? ~ "primitive_task" ~ STRING ~ "{" ~ EOL? ~ (COMMENT | operator_statement | effects_statement | expected_effects_statement | preconditions_statement)* ~ "}" ~ EOL }
compound_task          =  { EOL? ~ "compound_task" ~ STRING ~ "{" ~ EOL? ~ (method ~ EOL?)* ~ "}" ~ EOL }
method                 =  { 
    EOL? ~ "method" ~ (STRING)? ~ "{" ~ EOL? ~ 
    (COMMENT | preconditions_statement | subtasks_statement)* ~ 
    "}" ~ EOL? 
}
subtasks_statement     =  { 
    "subtasks:" ~ "[" ~ EOL? ~ 
    COMMENT? ~
    (identifier ~ ("," ~ EOL? ~ identifier)* ~ ","? ~ EOL? ~ COMMENT?)? ~ 
    "]" ~ EOL 
}

SEMVER = @{ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+){2} }

schema_version_statement = { "version:" ~ SEMVER ~ EOL }

operator_statement =  { "operator:" ~ operator_def ~ EOL  }
operator_def       =  { identifier ~ ("(" ~ operator_param* ~ ")")? }
operator_param     = @{ identifier }

condition  = { identifier ~ operator ~ (value | identifier) }

operator   = _{ op_gte  | op_gt | op_lte | op_lt | op_eq | op_neq }
op_gte = {">="}
op_gt  = {">"}
op_lte = {"<="}
op_lt  = {"<"}
op_eq  = {"=="}
op_neq = {"!="}

// effect_operator = _{ op_assign | op_assign_inc | op_assign_dec }
//op_assign = {"="}
//op_assign_inc = {"+="}
//op_assign_dec = {"-="}

op_is  = {"is"}

//optcond_none = @{ "None" }
//optcond_some = @{ "Some" }
//optcond_val = _{ optcond_none | optcond_some }

//option_condition = { identifier ~ op_is ~ optcond_val }

effect     = { set_effect_literal | set_effect_identifier | set_effect_inc_literal | set_effect_dec_literal }

set_effect_literal = { identifier ~ "=" ~ value }
set_effect_identifier = { identifier ~ "=" ~ identifier }
set_effect_inc_literal = { identifier ~ "+=" ~ value }
set_effect_dec_literal = { identifier ~ "-=" ~ value }

identifier = @{ (ASCII_ALPHANUMERIC | "_")+ }

// greedy parser, so check for enum_value first otherwise identifier is found before the ::
// similarly, check for float_value before value
value      = _{ enum_value | float_value | int_value | bool_value | none_value }

enum_value = @{ identifier ~ "::" ~ identifier }
float_value = @{ "-"? ~ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ }
int_value = @{ "-"? ~ ASCII_DIGIT+ }
bool_value = @{ "true" | "false" }
none_value = @{ "None" }

STRING     = @{ "\"" ~ ((!"\"" ~ ANY))* ~ "\"" }



preconditions_statement = { 
    "preconditions:" ~ "[" ~ EOL? ~
    (condition ~ ("," ~ EOL? ~ condition)* ~ ","? ~ EOL?)? ~
    "]" ~ EOL 
}

effects_statement = { 
    "effects:" ~ "[" ~ EOL? ~
    COMMENT? ~
    (effect ~ ("," ~ EOL? ~ effect)* ~ ","? ~ EOL?)? ~
    "]" ~ EOL 
}

expected_effects_statement = { 
    "expected_effects:" ~ "[" ~ EOL? ~
    COMMENT? ~
    (effect ~ ("," ~ EOL? ~ effect)* ~ ","? ~ EOL?)? ~
    "]" ~ EOL 
}

domain = { SOI ~ WHITESPACE* ~ schema ~ (primitive_task | compound_task)+ ~ WHITESPACE* ~ EOI }