// online parser: [https://pest.rs/](https://pest.rs/)
start = _{ SOI ~ declaration* ~ EOI}
identifier = @{ (ASCII_ALPHA | ASCII_ALPHANUMERIC | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
declaration = {
normal_rule |
layer_rule
}
// package is a container of file and classes
// file is a container of classes and functions
// classes is a container of functions and field
normal_rule = {
rule_level ~ ("(" ~ scope ~ ")")? ~ (use_symbol ~ expression)? ~ should? ~ only? ~ operator ~ assert ~ ";"?
}
rule_level = {
"package" |
"class" |
"struct" |
"function" |
"file"
}
layer_rule = {
"layer" ~ "(" ~ layer_type ~ ")" ~ (use_symbol ~ layer_expression)* ~ ";"?
}
// use property
use_symbol = {
"::" |
"->"
}
layer_type = {
string
}
layer_expression = {
identifier ~ "(" ~ string ~ (comma ~ string)* ~ ")"
}
scope = {
path_scope |
impl_scope |
extend_scope |
assignable_scope |
match_scope
}
path_scope = {
string
}
match_scope = {
"match" ~ "(" ~ string ~ ")"
}
assignable_scope = {
"assignable" ~ string
}
extend_scope = {
"extends" ~ string
}
impl_scope = {
"implementation" ~ string
}
expression = {
fn_call
}
fn_call = {
identifier ~ (dot ~ identifier )*
}
assert = {
leveled |
stringed |
array_stringed |
sized
}
array_stringed = {
"(" ~ "[" ~ string ~ ("," ~ string)* ~ "]" ~ ")"
}
stringed = {
"("? ~ string ~ ")"?
}
leveled = {
rule_level ~ "(" ~ string ~ ")"
}
sized = {
int
}
operator = {
op_not ~ operator |
op_not_symbol ~ operator |
op_lte |
op_gte |
op_lt |
op_gt |
op_eq |
op_contains |
op_endsWith |
op_startsWith |
op_resideIn |
op_inside |
op_accessed |
op_dependBy
}
// todo: change to strings operations method
op_contains = { "contains" }
op_endsWith = { "endsWith" }
op_startsWith = { "startsWith" }
// todo: thinking in define packages ops
op_inside = { "inside" }
op_resideIn = { "resideIn" }
op_accessed = { "accessed" }
op_dependBy = { "dependBy" }
op_not = @{ "not" }
op_not_symbol = @{ "!" }
// todo: move to comparison;
op_lte = { "<=" }
op_gte = { ">=" }
op_lt = { "<" }
op_gt = { ">" }
op_eq = { "=" }
op_ineq = { "!=" }
should = { "should" }
only = { "only" }
double_quoted_string = @{ "\"" ~ (!("\"") ~ ANY)* ~ "\""}
single_quoted_string = @{ "\'" ~ (!("\'") ~ ANY)* ~ "\'"}
string = @{
double_quoted_string |
single_quoted_string
}
number = @{ '0'..'9'+ }
int = @{ number | "-" ~ "0"* ~ '1'..'9' ~ number? }
dot = { "." }
comma = { "," }
semicolon = { ";" }
opening_paren = { "(" }
closing_paren = { ")" }
newline = _{ "\n" | "\r\n" }
WHITESPACE = _{ " " | "\t" | newline }
block_comment = _{ "/*" ~ (block_comment | !"*/" ~ ANY)* ~ "*/" }
COMMENT = _{ block_comment | ("//" ~ (!newline ~ ANY)*) }