use crate::Lexicon;
use std::any::TypeId;
use std::collections::BTreeMap;
mod builder;
pub use builder::*;
mod set;
pub use set::*;
#[derive(Debug, Default)]
pub struct First<L: Lexicon> {
map: BTreeMap<TypeId, FirstSet<L>>,
empty: FirstSet<L>,
}
impl<L: Lexicon> First<L> {
pub fn new(map: BTreeMap<TypeId, FirstSet<L>>) -> Self {
Self {
map,
empty: FirstSet::default(),
}
}
#[inline]
pub fn get(&self, ty: &TypeId) -> &FirstSet<L> {
self.map.get(ty).unwrap_or(&self.empty)
}
}
#[doc(hidden)]
pub struct DebugFirst<'a, 'b, L: Lexicon>(pub &'a First<L>, pub &'b BTreeMap<TypeId, String>);
impl<L: Lexicon> std::fmt::Debug for DebugFirst<'_, '_, L> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("First");
for (ty, first_set) in &self.0.map {
let name = self.1.get(ty).map(|x| x.as_str()).unwrap_or("<unknown>");
fmt.field(name, first_set);
}
fmt.finish()
}
}
#[macro_export]
macro_rules! first_set {
($($x:tt)*) => {
$crate::syntax::FirstSet::from($crate::terminal_set!($($x)*))
};
}