// Copyright (c) 2018 Fabian Schuiki #![allow(unused_variables)] #![allow(dead_code)] extern crate perplex_runtime; use std::iter::Peekable; #[derive(Debug, Copy, Clone)] enum Token { A, B, C, D, E, Eof, } #[derive(Debug)] enum NodeS { NodeS0(Token, NodeA, Token), NodeS1(Token, NodeB, Token), } #[derive(Debug)] struct NodeA(Token); #[derive(Debug)] struct NodeB(Token); trait Parser { fn peek(&mut self) -> Token; fn shift(&mut self, state_fn: fn(&mut Self), reduced_fn: fn(&mut Self, Nonterminal)); fn goto( &mut self, nonterminal: Nonterminal, state_fn: fn(&mut Self), reduced_fn: fn(&mut Self, Nonterminal), ); fn reduce) -> Nonterminal>(&mut self, length: usize, f: F); fn accept(&mut self); } struct IterParser> { result: Option, input: Peekable, stack: Vec>, } enum Symbol { Terminal(Token), Nonterminal(Nonterminal), } impl Symbol { fn unwrap_terminal(self) -> Token { match self { Symbol::Terminal(t) => t, _ => panic!("symbol is not a token"), } } fn unwrap_nonterminal(self) -> Nonterminal { match self { Symbol::Nonterminal(t) => t, _ => panic!("symbol is not a nonterminal"), } } } struct StackEntry> { symbol: Symbol, state_fn: fn(&mut IterParser), reduced_fn: fn(&mut IterParser, Nonterminal), } impl> IterParser { fn new(input: I) -> IterParser { IterParser { result: None, input: input.peekable(), stack: Vec::new(), } } fn step(&mut self) { if self.result.is_some() { return; } let state_fn = self.stack.last().map(|e| e.state_fn).unwrap_or(state_0); state_fn(self); print!("stack:"); for e in &self.stack { match e.symbol { Symbol::Terminal(ref t) => print!(" {:?}", t), Symbol::Nonterminal(ref t) => print!(" {:?}", t), } } println!(""); } fn run(mut self) -> NodeS { println!("running parser"); while self.result.is_none() { self.step() } self.result.unwrap() } } impl> Parser for IterParser { fn peek(&mut self) -> Token { let token = self.input.peek().map(|&t| t).unwrap_or(Token::Eof); println!("peeking {:?}", token); token } fn shift(&mut self, state_fn: fn(&mut Self), reduced_fn: fn(&mut Self, Nonterminal)) { let token = self.input.next().unwrap_or(Token::Eof); println!("shifting {:?}", token); self.stack.push(StackEntry { symbol: Symbol::Terminal(token), state_fn: state_fn, reduced_fn: reduced_fn, }); } fn goto( &mut self, nonterminal: Nonterminal, state_fn: fn(&mut Self), reduced_fn: fn(&mut Self, Nonterminal), ) { println!("goto called"); self.stack.push(StackEntry { symbol: Symbol::Nonterminal(nonterminal), state_fn: state_fn, reduced_fn: reduced_fn, }); } fn reduce) -> Nonterminal>(&mut self, length: usize, f: F) { println!("reduce {} symbols", length); let at = self.stack.len() - length; let args = self.stack.drain(at..).map(|e| e.symbol).collect(); let reduced_fn = self.stack.last().map(|e| e.reduced_fn).unwrap_or(reduced_0); let nonterminal = f(args); reduced_fn(self, nonterminal); } fn accept(&mut self) { println!("accept"); self.result = Some( self.stack .pop() .unwrap() .symbol .unwrap_nonterminal() .unwrap_nt0(), ); } } include!("generated/tribble1_parser.rs"); fn reduce_rule_0(a: Token, nta: NodeA, d: Token) -> NodeS { println!("reduced S -> a A d"); NodeS::NodeS0(a, nta, d) } fn reduce_rule_1(a: Token, ntb: NodeB, e: Token) -> NodeS { println!("reduced S -> a B e"); NodeS::NodeS1(a, ntb, e) } fn reduce_rule_2(b: Token, nta: NodeA, e: Token) -> NodeS { println!("reduced S -> b A e"); NodeS::NodeS0(b, nta, e) } fn reduce_rule_3(b: Token, ntb: NodeB, d: Token) -> NodeS { println!("reduced S -> b B d"); NodeS::NodeS1(b, ntb, d) } fn reduce_rule_4(tkn: Token) -> NodeA { println!("reduced A"); NodeA(tkn) } fn reduce_rule_5(tkn: Token) -> NodeB { println!("reduced B"); NodeB(tkn) } #[test] fn simple1() { // Parse the sequence "a c d". use Token::*; let seq = [A, C, D]; let res = IterParser::new(seq.into_iter().cloned()).run(); assert_eq!(format!("{:?}", res), "NodeS0(A, NodeA(C), D)"); } #[test] fn simple2() { // Parse the sequence "a c e". use Token::*; let seq = [A, C, E]; let res = IterParser::new(seq.into_iter().cloned()).run(); assert_eq!(format!("{:?}", res), "NodeS1(A, NodeB(C), E)"); } #[test] fn simple3() { // Parse the sequence "b c e". use Token::*; let seq = [B, C, E]; let res = IterParser::new(seq.into_iter().cloned()).run(); assert_eq!(format!("{:?}", res), "NodeS0(B, NodeA(C), E)"); } #[test] fn simple4() { // Parse the sequence "b c d". use Token::*; let seq = [B, C, D]; let res = IterParser::new(seq.into_iter().cloned()).run(); assert_eq!(format!("{:?}", res), "NodeS1(B, NodeB(C), D)"); }