use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt::Debug;
use std::fmt::Display;
use crate::token::Token;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum ReduceType {
Left,
Right,
}
impl Display for ReduceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReduceType::Left => write!(f, "Left"),
ReduceType::Right => write!(f, "Right"),
}
}
}
#[derive(Clone)]
pub struct ProductionRule<Term, NonTerm> {
pub name: NonTerm,
pub rule: Vec<Token<Term, NonTerm>>,
}
impl<Term: Display, NonTerm: Display> Display for ProductionRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} -> ", self.name)?;
for (id, token) in self.rule.iter().enumerate() {
write!(f, "{}", token)?;
if id < self.rule.len() - 1 {
write!(f, " ")?;
}
}
Ok(())
}
}
impl<Term: Debug, NonTerm: Debug> Debug for ProductionRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} -> ", self.name)?;
for (id, token) in self.rule.iter().enumerate() {
write!(f, "{:?}", token)?;
if id < self.rule.len() - 1 {
write!(f, " ")?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
pub struct ShiftedRuleRef {
pub rule: usize,
pub shifted: usize,
}
#[derive(Clone)]
pub(crate) struct ShiftedRuleRef2<'a, Term, NonTerm> {
pub rule: &'a ProductionRule<Term, NonTerm>,
pub shifted: usize,
}
impl<'a, Term: Display, NonTerm: Display> Display for ShiftedRuleRef2<'a, Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} -> ", self.rule.name)?;
for (id, token) in self.rule.rule.iter().enumerate() {
if id == self.shifted {
write!(f, "• ")?;
}
write!(f, "{}", token)?;
if id < self.rule.rule.len() - 1 {
write!(f, " ")?;
}
}
if self.shifted == self.rule.rule.len() {
write!(f, " •")?;
}
Ok(())
}
}
impl<'a, Term: Debug, NonTerm: Debug> Debug for ShiftedRuleRef2<'a, Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} -> ", self.rule.name)?;
for (id, token) in self.rule.rule.iter().enumerate() {
if id == self.shifted {
write!(f, "• ")?;
}
write!(f, "{:?}", token)?;
if id < self.rule.rule.len() - 1 {
write!(f, " ")?;
}
}
if self.shifted == self.rule.rule.len() {
write!(f, " •")?;
}
Ok(())
}
}
#[derive(Clone)]
pub struct ShiftedRule<Term, NonTerm> {
pub rule: ProductionRule<Term, NonTerm>,
pub shifted: usize,
}
impl<Term: Display, NonTerm: Display> Display for ShiftedRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} -> ", self.rule.name)?;
for (id, token) in self.rule.rule.iter().enumerate() {
if id == self.shifted {
write!(f, "• ")?;
}
write!(f, "{}", token)?;
if id < self.rule.rule.len() - 1 {
write!(f, " ")?;
}
}
if self.shifted == self.rule.rule.len() {
write!(f, " •")?;
}
Ok(())
}
}
impl<Term: Debug, NonTerm: Debug> Debug for ShiftedRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} -> ", self.rule.name)?;
for (id, token) in self.rule.rule.iter().enumerate() {
if id == self.shifted {
write!(f, "• ")?;
}
write!(f, "{:?}", token)?;
if id < self.rule.rule.len() - 1 {
write!(f, " ")?;
}
}
if self.shifted == self.rule.rule.len() {
write!(f, " •")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct LookaheadRuleRef<Term> {
pub rule: ShiftedRuleRef,
pub lookaheads: BTreeSet<Term>,
}
#[derive(Clone)]
pub struct LookaheadRule<Term, NonTerm> {
pub rule: ShiftedRule<Term, NonTerm>,
pub lookaheads: BTreeSet<Term>,
}
impl<Term: Display, NonTerm: Display> Display for LookaheadRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} / ", self.rule)?;
for (id, lookahead) in self.lookaheads.iter().enumerate() {
write!(f, "{}", lookahead)?;
if id < self.lookaheads.len() - 1 {
write!(f, ", ")?;
}
}
Ok(())
}
}
impl<Term: Debug, NonTerm: Debug> Debug for LookaheadRule<Term, NonTerm> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} / ", self.rule)?;
for (id, lookahead) in self.lookaheads.iter().enumerate() {
write!(f, "{:?}", lookahead)?;
if id < self.lookaheads.len() - 1 {
write!(f, ", ")?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct LookaheadRuleRefSet<Term> {
pub rules: BTreeMap<ShiftedRuleRef, BTreeSet<Term>>,
}
impl<Term> LookaheadRuleRefSet<Term> {
pub fn new() -> Self {
LookaheadRuleRefSet {
rules: BTreeMap::new(),
}
}
pub fn add(&mut self, rule: ShiftedRuleRef, mut lookaheads: BTreeSet<Term>) -> bool
where
Term: Ord,
{
let mut changed = false;
let set = self.rules.entry(rule).or_insert_with(|| {
changed = true;
BTreeSet::new()
});
let old = set.len();
set.append(&mut lookaheads);
changed || old != set.len()
}
}