#[derive(Debug, Clone, PartialEq)]
pub struct IxmlGrammar {
pub rules: Vec<Rule>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Rule {
pub name: String,
pub mark: Mark,
pub alternatives: Alternatives,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Alternatives {
pub alts: Vec<Sequence>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Sequence {
pub factors: Vec<Factor>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Factor {
pub base: BaseFactor,
pub repetition: Repetition,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BaseFactor {
Literal {
value: String,
insertion: bool, mark: Mark, },
Nonterminal {
name: String,
mark: Mark,
},
CharClass {
content: String,
negated: bool, mark: Mark, },
Group {
alternatives: Box<Alternatives>,
},
}
#[derive(Debug, Clone, PartialEq, Copy, Eq, Hash)]
pub enum Mark {
None, Attribute, Hidden, Promoted, }
#[derive(Debug, Clone, PartialEq)]
pub enum Repetition {
None, ZeroOrMore, OneOrMore, Optional, SeparatedZeroOrMore(Box<Sequence>), SeparatedOneOrMore(Box<Sequence>), }
impl IxmlGrammar {
pub fn new(rules: Vec<Rule>) -> Self {
IxmlGrammar { rules }
}
}
impl Rule {
pub fn new(name: String, mark: Mark, alternatives: Alternatives) -> Self {
Rule {
name,
mark,
alternatives,
}
}
}
impl Alternatives {
pub fn new(alts: Vec<Sequence>) -> Self {
Alternatives { alts }
}
pub fn single(seq: Sequence) -> Self {
Alternatives { alts: vec![seq] }
}
}
impl Sequence {
pub fn new(factors: Vec<Factor>) -> Self {
Sequence { factors }
}
pub fn empty() -> Self {
Sequence { factors: vec![] }
}
}
impl Factor {
pub fn new(base: BaseFactor, repetition: Repetition) -> Self {
Factor { base, repetition }
}
pub fn simple(base: BaseFactor) -> Self {
Factor {
base,
repetition: Repetition::None,
}
}
}
impl BaseFactor {
pub fn literal(value: String) -> Self {
BaseFactor::Literal {
value,
insertion: false,
mark: Mark::None,
}
}
pub fn insertion(value: String) -> Self {
BaseFactor::Literal {
value,
insertion: true,
mark: Mark::None,
}
}
pub fn marked_literal(value: String, mark: Mark) -> Self {
BaseFactor::Literal {
value,
insertion: false,
mark,
}
}
pub fn nonterminal(name: String) -> Self {
BaseFactor::Nonterminal {
name,
mark: Mark::None,
}
}
pub fn marked_nonterminal(name: String, mark: Mark) -> Self {
BaseFactor::Nonterminal { name, mark }
}
pub fn charclass(content: String) -> Self {
BaseFactor::CharClass {
content,
negated: false,
mark: Mark::None,
}
}
pub fn negated_charclass(content: String) -> Self {
BaseFactor::CharClass {
content,
negated: true,
mark: Mark::None,
}
}
pub fn marked_charclass(content: String, negated: bool, mark: Mark) -> Self {
BaseFactor::CharClass {
content,
negated,
mark,
}
}
pub fn group(alternatives: Alternatives) -> Self {
BaseFactor::Group {
alternatives: Box::new(alternatives),
}
}
}