use combine_proc_macro::{Ident, Literal};
#[derive(Debug)]
pub struct Grammar {
pub name: Ident,
pub rules: Vec<Rule>,
}
#[derive(Debug)]
pub struct Rule {
pub name: Ident,
pub pattern: Pattern,
pub attributes: Vec<Attribute>,
}
#[derive(Debug)]
pub enum Attribute {
Word(Ident), Group(Ident, Vec<Attribute>), }
#[derive(Debug)]
pub enum Pattern {
Empty,
Ident(Ident),
Literal(Literal),
Series(Vec<Pattern>),
Choice(Vec<Pattern>),
Repeat { pattern: Box<Pattern>, repeat: Repeat },
Predicate { pred: Box<Pattern>, expr: Box<Pattern> },
}
impl Pattern {
pub fn is_empty(&self) -> bool {
std::mem::discriminant(self) == std::mem::discriminant(&Pattern::Empty)
}
pub fn flatten_once(mut self) -> Pattern {
match self {
Pattern::Choice(ref mut p) if p.len() == 0 => Pattern::Empty,
Pattern::Choice(ref mut p) if p.len() == 1 => p.drain(0..1).next().unwrap(),
Pattern::Series(ref mut p) if p.len() == 0 => Pattern::Empty,
Pattern::Series(ref mut p) if p.len() == 1 => p.drain(0..1).next().unwrap(),
Pattern::Repeat { ref pattern, .. } if pattern.is_empty() => Pattern::Empty,
Pattern::Predicate { pred, expr } => {
if pred.is_empty() {
*expr
} else {
Pattern::Predicate { pred, expr }
}
}
_ => self,
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum Repeat {
ZeroOrOne,
ZeroOrMore,
OneOrMore,
}