#[macro_export]
macro_rules! delimited_slice {
($left:expr, $body:expr, $right:expr) => {
choice((
choice((just("\\").ignore_then($right), $right))
.not()
.rewind(),
just("\\").ignore_then($right.rewind()).ignored(),
))
.ignore_then($body)
.repeated()
.at_least(1)
.to_slice()
.delimited_by($left, $right)
.try_map(|s: &str, span| {
if $crate::parser::functions::is_blank(s) {
Err(Simple::new(None, span))
} else {
Ok(s)
}
})
};
($left:expr, $right:expr) => {
delimited_slice!($left, any(), $right)
};
($token:expr) => {
delimited_slice!($token, $token)
};
}
#[macro_export]
macro_rules! delimited_string {
($left:expr, $body:expr, $right:expr) => {
choice((
$body.and_is(choice((just('\\').ignore_then($right), $right)).not()),
just('\\').ignore_then($body),
))
.repeated()
.at_least(1)
.collect::<String>()
.delimited_by($left, $right)
};
($left:expr, $right:expr) => {
delimited_string!($left, any(), $right)
};
($token:expr) => {
delimited_string!($token, $token)
};
}
#[macro_export]
macro_rules! lls {
($expr:expr) => {
{
let sol = choice((
regex(r"^").ignored(),
newline(),
));
let esc_nl = just('\\').ignore_then(newline());
let not_nl = choice((esc_nl, newline().not().rewind())).ignore_then(any());
let line_text = not_nl.repeated().at_least(1).to_slice();
let iws_linetext = inline_whitespace().at_least(1).ignore_then(line_text);
sol.ignore_then($expr).ignore_then(iws_linetext)
}
};
($left:expr, $($right:expr),+) => {
lls!(choice(($left, $($right),+)))
};
}