Skip to main content

ShiftReduceParser

Trait ShiftReduceParser 

Source
pub trait ShiftReduceParser {
    type Action;
    type Token;
    type TimerId;
    type ReduceRecord;

    // Required methods
    fn decide(
        &mut self,
        token: &Self::Token,
    ) -> ParseAction<Self::Action, Self::Token, Self::TimerId, Self::ReduceRecord>;
    fn on_reduce(&mut self, record: Self::ReduceRecord);
}
Expand description

A shift-reduce parser that processes tokens with timer support.

Implement this trait to define your parser’s grammar (action table). The framework provides the main loop via parse().

§Implementing decide

decide is the action table of the parser. It receives a reference to the current token together with whatever state is stored in self, and returns a ParseAction describing what to do next.

Typical skeleton:

use timed_fsm::parser::{ShiftReduceParser, ParseAction};
use timed_fsm::TimerCommand;
use std::time::Duration;

#[derive(Clone, Copy, Debug, PartialEq)]
enum Key { Shift, A, Other }

struct MyParser { pending_shift: bool }

impl ShiftReduceParser for MyParser {
    type Action      = String;
    type Token       = Key;
    type TimerId     = ();
    type ReduceRecord = ();

    fn decide(&mut self, token: &Key)
        -> ParseAction<String, Key, (), ()>
    {
        match (self.pending_shift, token) {
            // Shift key down — buffer and open chord window.
            (false, Key::Shift) => {
                self.pending_shift = true;
                ParseAction::Shift {
                    timers: vec![TimerCommand::Set {
                        id: (),
                        duration: Duration::from_millis(50),
                    }],
                }
            }
            // Shift + A chord recognized.
            (true, Key::A) => {
                self.pending_shift = false;
                ParseAction::Reduce {
                    actions: vec!["ShiftA".to_string()],
                    record: (),
                    timers: vec![TimerCommand::Kill { id: () }],
                }
            }
            // Unrecognized — pass through.
            _ => ParseAction::PassThrough { timers: vec![] },
        }
    }

    fn on_reduce(&mut self, (): ()) { /* update history / stats */ }
}

let mut p = MyParser { pending_shift: false };
let _ = timed_fsm::parse(&mut p, Key::Shift);   // Shift
let r = timed_fsm::parse(&mut p, Key::A);       // Reduce
assert_eq!(r.actions, vec!["ShiftA".to_string()]);

Required Associated Types§

Source

type Action

Output action type.

Source

type Token

Input token type.

Source

type TimerId

Timer ID type.

Source

type ReduceRecord

Metadata attached to each Reduce step (e.g., history tracking).

Use () if no per-reduce bookkeeping is needed.

Required Methods§

Source

fn decide( &mut self, token: &Self::Token, ) -> ParseAction<Self::Action, Self::Token, Self::TimerId, Self::ReduceRecord>

The action table: given the current state and input token, decide what to do.

This method may mutate internal state (e.g., enter a pending state, push a token onto a buffer). It is called once per token (or once per remaining token in a ReduceAndContinue loop iteration) by parse.

Source

fn on_reduce(&mut self, record: Self::ReduceRecord)

Called after each Reduce or ReduceAndContinue to update internal bookkeeping.

Receives the record from the matching ParseAction. Use this to maintain reduce-count statistics, history logs, or any per-reduce state that should not live inside decide.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§