taco-parser 0.1.0

A crate containing parsers to parse threshold automata and ELTL specifications from ByMC and TLA+ specification files. This crate is part of the TACO toolsuite.
Documentation
//! This file specifies a pest grammar for the specification format introduced
//! by BYMC (https://github.com/konnov/bymc).
//!
//! A formal grammar can be found here
//! https://github.com/konnov/bymc/blob/266366f738bce9dbd5d04336fd9123d85ae2bca1/bymc/doc/ta-format.md?plain=1#L7
//!
//! This grammar is more permissive as some benchmarks do not follow the
//! original grammar.

// Syntax of a complete ByMC specification (`.ta`) file
bymc_spec = _{
    SOI ~ ("thresholdAutomaton" | "threshAuto" | "TA" | "ta" | "skel") ~ identifier ~ "{" ~ local_variables* ~ shared_variables* ~ parameters* ~ define_statement* ~ assumption_list? ~ location_list ~ initial_condition_list? ~ rule_list ~ specification_list? ~ "}" ~ EOI
}

// set of local variables
local_variables = { "local" ~ identifier_list ~ ";" }

// set of shared variables
shared_variables = { "shared" ~ identifier_list ~ ";" }

// set of parameters
parameters = { "parameters" ~ identifier_list ~ ";" }

define_statement = { "define" ~ identifier ~ "==" ~ integer_expr ~ ";" }

// assumptions / resilience conditions
assumption_list = {
    ("assumptions" | "assume") ~ "(" ~ integer_const ~ ")" ~ "{" ~ boolean_expr_list ~ "}"
}

// list of locations / states of the TA
location      = { identifier ~ ":" ~ "[" ~ integer_const ~ (";" ~ integer_const)* ~ "]" ~ ";" }
location_list = {
    "locations" ~ "(" ~ integer_const ~ ")" ~ "{" ~ location* ~ "}"
}

// list of initial conditions
initial_condition_list = {
    "inits" ~ "(" ~ integer_const ~ ")" ~ "{" ~ boolean_expr_list ~ "}"
}

// Rule syntax
rule = {
    integer_const ~ ":" ~ identifier ~ "->" ~ identifier ~ "when" ~ "(" ~ boolean_expr ~ ")" ~ "do" ~ "{" ~ action_list ~ "}" ~ ";"
}
// list of rules
rule_list = {
    "rules" ~ "(" ~ integer_const ~ ")" ~ "{" ~ rule* ~ "}"
}

// specification
specification = { identifier ~ ":" ~ ltl_expr }
// specifications list
specification_list = {
    ("specifications" | "spec") ~ "(" ~ integer_const ~ ")" ~ "{" ~ specification? ~ (";" ~ specification)* ~ ";"? ~ "}"
}

// UPDATES

unchanged_expr  = { "unchanged(" ~ identifier_list ~ ")" }
reset_expr      = { "reset(" ~ identifier_list ~ ")" }
assignment_expr = { identifier ~ "'" ~ ("==" | ":=") ~ integer_expr }

// syntax of updates / actions  in rules
action_expr = { unchanged_expr | reset_expr | assignment_expr }
action_list = { (action_expr ~ (";" ~ action_expr)* ~ ";"?)? }

// INTEGER EXPRESSIONS

integer_const = @{ ASCII_DIGIT+ }

add = { "+" }
sub = { "-" }
mul = { "*" }
div = { "/" }

integer_binary_op = _{ add | sub | mul | div }

negation         =  { "-" }
integer_unary_op = _{ negation }

integer_atom = { integer_const | identifier | "(" ~ integer_expr ~ ")" }

integer_expr = { integer_unary_op? ~ integer_atom ~ (integer_binary_op ~ (integer_unary_op? ~ integer_atom))* }

// BOOLEAN EXPRESSIONS

bool_true  = @{ "true" | "1" }
bool_false = @{ "false" | "0" }
bool_const =  { bool_true | bool_false }

and                =  { "&&" }
or                 =  { "||" }
boolean_connective = _{ and | or }

not              =  { "!" }
boolean_unary_op = _{ not }

// comparisons
equal           =  { "==" }
n_equal         =  { "!=" | "=!" }
less_eq         =  { "<=" }
less            =  { "<" }
greater_eq      =  { ">=" }
greater         =  { ">" }
comparison_op   = _{ equal | n_equal | less_eq | less | greater_eq | greater }
comparison_expr =  { integer_expr ~ comparison_op ~ integer_expr }

boolean_atom = { bool_const | "(" ~ boolean_expr ~ ")" | comparison_expr }

// full boolean expressions
boolean_expr      = { boolean_unary_op? ~ boolean_atom ~ (boolean_connective ~ (boolean_unary_op? ~ boolean_atom))* }
boolean_expr_list = { (boolean_expr ~ (";" ~ boolean_expr)* ~ ";"?)? }

// LTL

eventually  = { "<>" }
globally    = { "[]" }
implication = { "->" }

ltl_binary_op = _{ implication | boolean_connective }
ltl_unary_op  =  { not | eventually | globally }

ltl_atom = { comparison_expr | "(" ~ ltl_expr ~ ")" | ltl_unary_op ~ ltl_atom | bool_const }
ltl_expr = { ltl_atom ~ (ltl_binary_op ~ ltl_atom)* }

// Identifier:
// - starts with a letter or with "_" followed by at least on letter
// - can then contain letters, digits and "_"
identifier = @{ ("_")* ~ ASCII_ALPHA+ ~ (ASCII_ALPHA | "_" | ASCII_DIGIT)* }
// list of identifiers
identifier_list = { identifier ~ ("," ~ identifier)* }

// comments: // for single line comments and /* */ for multiline
COMMENT    = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!("\n") ~ ANY)* ~ "\n"?) }
WHITESPACE = _{ " " | "\n" | "\t" }