forked from gentoo-utils/gentoo-utils
62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
use mon::{DebugTracer, Parser, ParserResult, input::InputIter, mode::Emit, tag, whitespace1};
|
|
|
|
use crate::{
|
|
atom,
|
|
depend::{Conditional, Expr},
|
|
useflag,
|
|
};
|
|
|
|
fn expr(it: InputIter<&str>) -> ParserResult<&str, Expr> {
|
|
let all_of = expr
|
|
.separated_list1(whitespace1())
|
|
.delimited_by(tag("(").followed_by(whitespace1()), tag(")"))
|
|
.map(|exprs| Expr::AllOf(exprs));
|
|
|
|
let any_of = expr
|
|
.separated_list1(whitespace1())
|
|
.delimited_by(tag("(").followed_by(whitespace1()), tag(")"))
|
|
.preceded_by(tag("||").followed_by(whitespace1()))
|
|
.map(|exprs| Expr::AnyOf(exprs));
|
|
|
|
let one_of = expr
|
|
.separated_list1(whitespace1())
|
|
.delimited_by(tag("(").followed_by(whitespace1()), tag(")"))
|
|
.preceded_by(tag("^^").followed_by(whitespace1()))
|
|
.map(|exprs| Expr::OneOf(exprs));
|
|
|
|
atom::parsers::atom()
|
|
.map(|atom| Expr::Atom(atom))
|
|
.or(conditional().map(|conditional| Expr::Conditional(conditional)))
|
|
.or(any_of)
|
|
.or(all_of)
|
|
.or(one_of)
|
|
.parse(it)
|
|
}
|
|
|
|
fn conditional<'a>() -> impl Parser<&'a str, Output = Conditional> {
|
|
useflag::parsers::useflag()
|
|
.preceded_by(tag("!"))
|
|
.followed_by(tag("?"))
|
|
.map(|flag| Conditional::Negative(flag))
|
|
.or(useflag::parsers::useflag()
|
|
.followed_by(tag("?"))
|
|
.map(|flag| Conditional::Positive(flag)))
|
|
}
|
|
|
|
pub fn exprs<'a>() -> impl Parser<&'a str, Output = Vec<Expr>> {
|
|
expr.separated_list1(whitespace1())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_expr() {
|
|
let it = InputIter::new("flag? ( || ( foo/bar foo/bar ) )");
|
|
|
|
exprs().check_finished(it).unwrap();
|
|
}
|
|
}
|