pub struct Terminals { /* private fields */ }
Expand description
A collection of terminals
The terminals are stored in a 128 bit integer where each terminal is stored in a fixed number of bits. The number of bits is determined by the number of terminals to store. The maximum number of terminals when storing MAX_K terminals in 128 bits is: 128 / MAX_K = 128 / 10 = 12.8 => 12 bits The maximum number of terminals that can be stored is 2^12 = 4096. The maximum value of the bit count is therefore 12 and can safely be stored in four bits. We store a mask to more easily extract the terminals from the 128 bits unsigned integer. The mask to extract single terminals from the 128 bit unsigned integer is calculated as 2^bits - 1 that is equivalent to the expression !(!0u128 << bits) at runtime.
Since we use only 120 bits to store the terminals, we have 8 bits left. We use the 8 bits to store the index of the next insertion as well as the bit count used to calculate the mask. Therefore we split the highest 8 bits of the 128 bits unsigned integer as follows:
- The higher 4 bits are used to store the number of bits used per terminal
- The lower 4 bits are used to store the index of the next insertion
Implementations§
source§impl Terminals
impl Terminals
sourcepub fn new(max_terminal_index: usize) -> Self
pub fn new(max_terminal_index: usize) -> Self
Creates a new item
use parol::analysis::k_tuple::Terminals;
use parol::analysis::compiled_terminal::CompiledTerminal;
let t = Terminals::new(1);
assert!(t.is_empty());
assert_eq!(0, t.len(), "len");
assert_eq!(0, t.k_len(5), "k_len");
assert_eq!(None, t.get(0));
assert_eq!(None, t.get(9));
sourcepub fn eps(max_terminal_index: usize) -> Terminals
pub fn eps(max_terminal_index: usize) -> Terminals
Creates a new item with epsilon semantic
use parol::analysis::k_tuple::{Terminals, TerminalMappings};
use parol::analysis::compiled_terminal::CompiledTerminal;
let t = Terminals::eps(1);
assert!(!t.is_empty());
assert_eq!(1, t.len(), "len");
assert_eq!(1, t.k_len(5), "k_len");
assert_eq!(Some(CompiledTerminal::eps()), t.get(0));
assert_eq!(None, t.get(1));
assert_eq!(None, t.get(9));
sourcepub fn end(max_terminal_index: usize) -> Terminals
pub fn end(max_terminal_index: usize) -> Terminals
Creates a new item with end (EOI) semantic Such a terminal can’t be extended, i.e. you can’t append more terminals
use parol::analysis::k_tuple::{Terminals, TerminalMappings};
use parol::analysis::compiled_terminal::CompiledTerminal;
let t = Terminals::end(1);
assert!(!t.is_empty());
assert_eq!(1, t.len());
assert_eq!(1, t.k_len(5));
assert_eq!(Some(CompiledTerminal::end()), t.get(0));
assert_eq!(None, t.get(1));
assert_eq!(None, t.get(9));
sourcepub fn of(k: usize, other: Self) -> Self
pub fn of(k: usize, other: Self) -> Self
Creates a new object with maximum k length from another object
sourcepub fn next_index(&self) -> u8
pub fn next_index(&self) -> u8
Returns the index of the next insertion The highest 8 bits of t are used to store the index of the next insertion in it’s lowest 4 bits.
sourcepub fn bits(&self) -> u8
pub fn bits(&self) -> u8
Returns the bits used per terminal The highest 8 bits of t are used to store the number of bits used per terminal in it’s highest 4 bits.
use parol::analysis::k_tuple::Terminals;
let t = Terminals::eps(1);
assert_eq!(2, t.bits());
sourcepub fn mask(&self) -> u128
pub fn mask(&self) -> u128
Returns the mask used to extract the terminal at position i The mask is calculated as 2^bits - 1 that is equivalent to the expression !(!0u128 << bits).
sourcepub fn is_k_complete(&self, k: usize) -> bool
pub fn is_k_complete(&self, k: usize) -> bool
Checks if the collection is k-complete, i.e. no terminals can be added
use parol::analysis::k_tuple::Terminals;
let t = Terminals::end(1);
assert!(t.is_k_complete(5));
sourcepub fn k_len(&self, k: usize) -> usize
pub fn k_len(&self, k: usize) -> usize
Returns the k-length, i.e. the number of symbols that contributes to lookahead sizes
sourcepub fn k_concat(self, other: &Self, k: usize) -> Self
pub fn k_concat(self, other: &Self, k: usize) -> Self
Concatenates two collections with respect to the rules of k-concatenation
use parol::analysis::k_tuple::{Terminals, TerminalMappings};
use parol::analysis::compiled_terminal::CompiledTerminal;
let t1 = Terminals::eps(1);
let t2 = Terminals::end(1);
let t = t1.k_concat(&t2, 5);
assert!(t.is_k_complete(5));
assert_eq!(1, t.len());
assert_eq!(Some(CompiledTerminal::end()), t.get(0));
let t = t2.k_concat(&t1, 5);
assert!(t.is_k_complete(5));
assert_eq!(1, t.len());
assert_eq!(Some(CompiledTerminal::end()), t.get(0));
let mut t1 = Terminals::new(6);
t1.extend([1, 2, 3].iter().cloned());
let mut t2 = Terminals::new(6);
t2.extend([4, 5, 6].iter().cloned());
let t = t1.k_concat(&t2, 5);
assert!(t.is_k_complete(5));
assert_eq!(5, t.len());
assert_eq!(Some(CompiledTerminal(1)), t.get(0));
assert_eq!(Some(CompiledTerminal(2)), t.get(1));
assert_eq!(Some(CompiledTerminal(3)), t.get(2));
assert_eq!(Some(CompiledTerminal(4)), t.get(3));
assert_eq!(Some(CompiledTerminal(5)), t.get(4));
assert_eq!(None, t.get(5));
sourcepub fn push(&mut self, t: CompiledTerminal) -> Result<(), String>
pub fn push(&mut self, t: CompiledTerminal) -> Result<(), String>
Adds a new terminal to self if max size is not reached yet and if last is not EOI
sourcepub fn get(&self, i: usize) -> Option<CompiledTerminal>
pub fn get(&self, i: usize) -> Option<CompiledTerminal>
Returns the terminal at position i
sourcepub fn set(&mut self, i: usize, t: CompiledTerminal)
pub fn set(&mut self, i: usize, t: CompiledTerminal)
Sets the terminal at position i
Trait Implementations§
source§impl Extend<CompiledTerminal> for Terminals
impl Extend<CompiledTerminal> for Terminals
source§fn extend<I: IntoIterator<Item = CompiledTerminal>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = CompiledTerminal>>(&mut self, iter: I)
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl Extend<u16> for Terminals
impl Extend<u16> for Terminals
source§fn extend<I: IntoIterator<Item = TerminalIndex>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = TerminalIndex>>(&mut self, iter: I)
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl Ord for Terminals
impl Ord for Terminals
source§impl PartialEq for Terminals
impl PartialEq for Terminals
source§impl PartialOrd for Terminals
impl PartialOrd for Terminals
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moreimpl Copy for Terminals
impl Eq for Terminals
impl StructuralPartialEq for Terminals
Auto Trait Implementations§
impl Freeze for Terminals
impl RefUnwindSafe for Terminals
impl Send for Terminals
impl Sync for Terminals
impl Unpin for Terminals
impl UnwindSafe for Terminals
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.