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 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}