impl DEPEND parser

This commit is contained in:
John Turner
2025-10-25 02:02:07 -04:00
parent f854e97577
commit f05c1e92ad
5 changed files with 114 additions and 0 deletions

View File

@@ -348,4 +348,11 @@ mod test {
assert!(atom().check_finished(it).is_err());
}
#[test]
fn test_atom_with_trailing_dash_and_letter() {
let it = InputIter::new("dev-db/mysql-connector-c");
atom().check_finished(it).unwrap();
}
}

18
src/depend/mod.rs Normal file
View File

@@ -0,0 +1,18 @@
use crate::{atom::Atom, useflag::UseFlag};
pub mod parsers;
#[derive(Clone, Debug)]
pub enum Conditional {
Negative(UseFlag),
Positive(UseFlag),
}
#[derive(Clone, Debug)]
pub enum Expr {
Atom(Atom),
Conditional(Conditional),
AllOf(Vec<Expr>),
AnyOf(Vec<Expr>),
OneOf(Vec<Expr>),
}

61
src/depend/parsers.rs Normal file
View File

@@ -0,0 +1,61 @@
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();
}
}

View File

@@ -2,4 +2,5 @@
#![allow(dead_code)]
pub mod atom;
pub mod depend;
pub mod useflag;