use std::marker::PhantomData;
use crate::Token;
pub trait ShiftReduceRule : Sized {
type Kind;
type Term;
fn reduce(&self, lhs: Self::Term, rhs: Self::Term) -> Result<Self::Term,()>;
fn shift(&mut self, token: Token<Self::Kind>, stack: &mut Vec<Self::Term>) -> Result<Option<Self::Term>,()>;
fn apply<F:Fn(Self::Term,Self::Term)->Result<Self::Term,()>>(self, rule: F) -> ShiftApplyRule<Self::Kind,F,Self> {
ShiftApplyRule{rule, rest: self, dummy: PhantomData }
}
fn first(self, term: Self::Term) -> ShiftFirstRule<Self::Kind,Self::Term,Self> {
ShiftFirstRule{ term: Some(term), rest: self, dummy: PhantomData }
}
fn terminate<F>(self,kind: Self::Kind, rule: F) -> ShiftTerminalRule<Self::Kind,F,Self>
where F:Fn(Token<Self::Kind>)->Self::Term
{
ShiftTerminalRule{kind, rule, rest: self}
}
fn skip(self,kind: Self::Kind) -> ShiftSkipRule<Self::Kind,Self::Term,Self> {
ShiftSkipRule{kind, dummy: PhantomData, rest: self}
}
fn open(self,kind: Self::Kind, default: Self::Term) -> ShiftOpenRule<Self::Kind,Self::Term,Self> {
ShiftOpenRule{kind, default, rest: self}
}
fn close(self,kind: Self::Kind) -> ShiftCloseRule<Self::Kind,fn(Self::Term)->Self::Term,Self>
{
ShiftCloseRule{kind, rule: |t| t, rest: self}
}
fn close_with<F>(self,kind: Self::Kind, rule: F) -> ShiftCloseRule<Self::Kind,F,Self>
where F:Fn(Self::Term)->Self::Term
{
ShiftCloseRule{kind, rule, rest: self}
}
fn update<F:Fn(Self::Term)->Self::Term>(self, kind: Self::Kind, rule: F) -> ShiftUpdateRule<Self::Kind,F,Self> {
ShiftUpdateRule{kind, rule, rest: self}
}
fn update_with<F:Fn(Self::Term)->Result<(bool,Self::Term),()>>(self, kind: Self::Kind, rule: F) -> ShiftUpdateWithRule<Self::Kind,F,Self> {
ShiftUpdateWithRule{kind, rule, rest: self}
}
fn update_as<F:Fn(&mut Self::Term)->Result<bool,()>>(self, kind: Self::Kind, rule: F) -> ShiftUpdateAsRule<Self::Kind,F,Self> {
ShiftUpdateAsRule{kind, rule, rest: self}
}
fn parse<I>(&mut self, input: I) -> Result<Self::Term,()>
where I: IntoIterator<Item=Token<Self::Kind>>
{
let mut input = input.into_iter();
let mut stack = Vec::new();
while let Some(token) = input.next() {
if let Some(t2) = self.shift(token, &mut stack)? {
match stack.pop() {
None => {
return Ok(t2);
}
Some(t1) => {
let reduction = self.reduce(t1,t2)?;
stack.push(reduction);
}
}
}
}
Err(())
}
}
pub struct ShiftReduceParser<K,T>{
dummy: PhantomData<(K,T)>,
}
impl<K,T> ShiftReduceParser<K,T> {
pub fn new() -> Self {
ShiftReduceParser{ dummy: PhantomData}
}
}
impl<K:PartialEq,T> ShiftReduceRule for ShiftReduceParser<K,T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, _token: Token<K>, _stack: &mut Vec<T>) -> Result<Option<T>,()> {
Err(())
}
fn reduce(&self, _parent: T, _child: T) -> Result<T,()> {
Err(())
}
}
pub struct ShiftApplyRule<K,F,SR> { rule: F, rest: SR, dummy: PhantomData<K> }
impl<K:PartialEq,T,F:Fn(T,T)->Result<T,()>,SR> ShiftReduceRule for ShiftApplyRule<K,F,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
self.rest.shift(token,stack)
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
(self.rule)(parent,child)
}
}
pub struct ShiftFirstRule<K,T,SR> { term: Option<T>, dummy: PhantomData<K>, rest: SR }
impl<K:PartialEq,T,SR> ShiftReduceRule for ShiftFirstRule<K,T,SR>
where SR: ShiftReduceRule<Kind=K,Term=T> {
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if self.term.is_some() { stack.push(self.term.take().unwrap()); }
self.rest.shift(token,stack)
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftTerminalRule<K,F,SR> { kind: K, rule: F, rest: SR }
impl<K:PartialEq,T,F:Fn(Token<K>)->T,SR> ShiftReduceRule for ShiftTerminalRule<K,F,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind {
Ok(Some((self.rule)(token)))
} else {
self.rest.shift(token,stack)
}
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftOpenRule<K,T,SR> { kind: K, default: T, rest: SR }
impl<K:PartialEq,T:Clone,SR> ShiftReduceRule for ShiftOpenRule<K,T,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind {
stack.push(self.default.clone());
Ok(None)
} else {
self.rest.shift(token,stack)
}
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftCloseRule<K,F,SR> { kind: K, rule: F, rest: SR }
impl<K:PartialEq,T,F,SR> ShiftReduceRule for ShiftCloseRule<K,F,SR>
where F:Fn(T)->T,
SR: ShiftReduceRule<Kind=K,Term=T> {
type Kind =K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind && !stack.is_empty() {
let term = stack.pop().unwrap();
let closed = (self.rule)(term);
Ok(Some(closed))
} else {
self.rest.shift(token,stack)
}
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftSkipRule<K,T,SR> { kind: K, dummy: PhantomData<T>, rest: SR }
impl<K:PartialEq,T,SR> ShiftReduceRule for ShiftSkipRule<K,T,SR>
where SR: ShiftReduceRule<Kind=K,Term=T> {
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind {
Ok(None)
} else {
self.rest.shift(token,stack)
}
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftUpdateRule<K,F,SR> { kind: K, rule: F, rest: SR }
impl<K:PartialEq,T,F:Fn(T)->T,SR> ShiftReduceRule for ShiftUpdateRule<K,F,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind && !stack.is_empty(){
let top = stack.pop().unwrap();
stack.push((self.rule)(top));
Ok(None)
} else {
self.rest.shift(token,stack)
}
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftUpdateWithRule<K,F,SR> { kind: K, rule: F, rest: SR }
impl<K:PartialEq,T,F:Fn(T)->Result<(bool,T),()>,SR> ShiftReduceRule for ShiftUpdateWithRule<K,F,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind && !stack.is_empty(){
let top = stack.pop().unwrap();
let (ok,item) = (self.rule)(top)?;
stack.push(item);
if ok { return Ok(None); }
}
self.rest.shift(token,stack)
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}
pub struct ShiftUpdateAsRule<K,F,SR> { kind: K, rule: F, rest: SR }
impl<K:PartialEq,T,F:Fn(&mut T)->Result<bool,()>,SR> ShiftReduceRule for ShiftUpdateAsRule<K,F,SR>
where SR: ShiftReduceRule<Kind=K,Term=T>
{
type Kind = K;
type Term = T;
fn shift(&mut self, token: Token<K>, stack: &mut Vec<T>) -> Result<Option<T>,()> {
if token.kind == self.kind {
match stack.last_mut() {
Some(item) => {
if (self.rule)(item)? {
return Ok(None)
}
}
_ => {}
}
}
self.rest.shift(token,stack)
}
fn reduce(&self, parent: T, child: T) -> Result<T,()> {
self.rest.reduce(parent,child)
}
}