use std::fmt::{Display, Formatter, Error}; #[macro_use] extern crate prattle; use prattle::prelude::*; #[derive(Debug, Clone, PartialEq)] pub enum CToken { Number(String), Ident(String), Add, Sub, Mul, Div, Mod, LParens, RParens } impl Display for CToken { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { write!(f, "{}", match *self { CToken::Number(ref s) => format!("(Number: {})", s), CToken::Ident(ref s) => format!("(Ident: {})", s), CToken::Add => "Add".to_string(), CToken::Sub => "Sub".to_string(), CToken::Mul => "Mul".to_string(), CToken::Div => "Div".to_string(), CToken::Mod => "Mod".to_string(), CToken::LParens => "(".to_string(), CToken::RParens => ")".to_string(), }) } } fn token_spec() -> Result, SpecificationError> { let mut spec = ParserSpec::new(); add_null_assoc!(spec, PrecedenceLevel::Root, (CToken::Number("".to_string()), CToken::Ident("".to_string())) => |_, token: CToken, _| { Ok(Node::Simple(token.clone())) }); add_left_assoc!(spec, PrecedenceLevel::First, (CToken::Add, CToken::Sub) => |parser, token, lbp, node| { Ok(Node::Composite { token: token.clone(), children: vec![node, parser.parse_expr(lbp)?] } ) } ); add_left_assoc!(spec, PrecedenceLevel::Second, (CToken::Mul, CToken::Div, CToken::Mod) => |parser, token, lbp, node| { Ok(Node::Composite { token: token.clone(), children: vec![node, parser.parse_expr(lbp)?] } ) } ); add_null_assoc!(spec, PrecedenceLevel::First, (CToken::LParens) => |parser, _, lbp| { let res = parser.parse_expr(lbp)?; parser.consume(CToken::RParens)?; Ok(res) }); Ok(spec) } fn main() { let tokens = vec![ CToken::Ident("a".to_string()), CToken::Add, CToken::LParens, CToken::Number("10".to_string()), CToken::Mul, CToken::LParens, CToken::Ident("b".to_string()), CToken::Div, CToken::Number("2".to_string()), CToken::RParens, CToken::Mod, CToken::Number("4".to_string()), CToken::RParens, CToken::Sub, CToken::Ident("c".to_string()), ]; let lexer = LexerVec::new(tokens); let spec = token_spec().expect("Should work."); let mut parser = GeneralParser::new(spec, lexer); let res = parser.parse(); println!("{:?}", res); }