1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! Abstraction for collections of rules.

use symbol::{Symbol, SymbolSource};
use symbol::source::SymbolContainer;

/// Trait for rule and symbol containers.
pub trait RuleContainer {
    /// The type of history carried with the rule.
    type History;

    /// Returns an immutable reference to the grammar's symbol source.
    fn sym_source(&self) -> &SymbolSource;

    /// Returns a mutable reference to the grammar's symbol source.
    fn sym_source_mut(&mut self) -> &mut SymbolSource;

    /// Returns generated symbols.
    fn sym<T>(&mut self) -> T
        where T: SymbolContainer
    {
        self.sym_source_mut().sym()
    }

    /// Generates a new unique symbol.
    fn next_sym(&mut self) -> Symbol {
        self.sym_source_mut().next_sym()
    }

    /// Returns the number of symbols in use.
    fn num_syms(&self) -> usize {
        self.sym_source().num_syms()
    }

    /// Retains only the rules specified by the predicate.
    ///
    /// In other words, removes all rules `rule` for which `f(&rule)` returns false.
    fn retain<F>(&mut self, f: F) where F: FnMut(Symbol, &[Symbol], &Self::History) -> bool;
    /// Inserts a rule with `lhs` and `rhs` on its LHS and RHS. The rule carries `history`.
    fn add_rule(&mut self, lhs: Symbol, rhs: &[Symbol], history: Self::History);
}

/// A trait for creating an empty container.
pub trait EmptyRuleContainer {
    /// Creates a new empty container.
    fn empty(&self) -> Self;
}

impl<'a, D> RuleContainer for &'a mut D
    where D: RuleContainer
{
    type History = D::History;

    fn sym_source(&self) -> &SymbolSource {
        (**self).sym_source()
    }

    fn sym_source_mut(&mut self) -> &mut SymbolSource {
        (**self).sym_source_mut()
    }

    fn retain<F>(&mut self, f: F)
        where F: FnMut(Symbol, &[Symbol], &Self::History) -> bool
    {
        (**self).retain(f);
    }

    fn add_rule(&mut self, lhs: Symbol, rhs: &[Symbol], history: Self::History) {
        (**self).add_rule(lhs, rhs, history);
    }
}