lrtable/
mod.rs

1#![allow(clippy::cognitive_complexity)]
2#![allow(clippy::too_many_arguments)]
3#![allow(clippy::type_complexity)]
4#![forbid(unsafe_code)]
5#![deny(unreachable_pub)]
6
7use std::{hash::Hash, mem::size_of};
8
9#[cfg(feature = "bincode")]
10use bincode::{Decode, Encode};
11use num_traits::{AsPrimitive, PrimInt, Unsigned};
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15mod itemset;
16mod pager;
17mod stategraph;
18pub mod statetable;
19
20pub use crate::{
21    stategraph::StateGraph,
22    statetable::{Action, StateTable, StateTableError, StateTableErrorKind},
23};
24use cfgrammar::yacc::YaccGrammar;
25
26macro_rules! IdxNewtype {
27    ($(#[$attr:meta])* $n: ident) => {
28        $(#[$attr])*
29        #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
30        #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
31        #[cfg_attr(feature="bincode", derive(Encode, Decode))]
32        pub struct $n<T>(pub T);
33
34        impl<T: PrimInt + Unsigned> From<$n<T>> for usize {
35            fn from($n(st): $n<T>) -> Self {
36                debug_assert!(size_of::<usize>() >= size_of::<T>());
37                num_traits::cast(st).unwrap()
38            }
39        }
40
41        impl<T: PrimInt + Unsigned> From<$n<T>> for u32 {
42            fn from($n(st): $n<T>) -> Self {
43                debug_assert!(size_of::<u32>() >= size_of::<T>());
44                num_traits::cast(st).unwrap()
45            }
46        }
47
48        impl<T: PrimInt + Unsigned> $n<T> {
49            pub fn as_storaget(&self) -> T {
50                let $n(st) = self;
51                *st
52            }
53        }
54    }
55}
56
57IdxNewtype!(
58    /// A type specifically for state table indices.
59    ///
60    /// It is guaranteed that `StIdx` can be converted, without loss of precision, to `usize` with
61    /// the idiom `usize::from(...)`.
62    StIdx
63);
64
65#[derive(Clone, Copy)]
66pub enum Minimiser {
67    Pager,
68}
69
70pub fn from_yacc<StorageT: 'static + Hash + PrimInt + Unsigned>(
71    grm: &YaccGrammar<StorageT>,
72    m: Minimiser,
73) -> Result<(StateGraph<StorageT>, StateTable<StorageT>), StateTableError<StorageT>>
74where
75    usize: AsPrimitive<StorageT>,
76{
77    match m {
78        Minimiser::Pager => {
79            let sg = pager::pager_stategraph(grm);
80            let st = StateTable::new(grm, &sg)?;
81            Ok((sg, st))
82        }
83    }
84}