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 }