1use std::fmt::{Display, Formatter, Error};
2
3#[macro_use] extern crate prattle;
4
5use prattle::prelude::*;
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum CToken {
9 Number(String),
10 Ident(String),
11 Add, Sub,
12 Mul, Div, Mod,
13 LParens, RParens
14}
15
16impl Display for CToken {
17 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
18 write!(f, "{}", match *self {
19 CToken::Number(ref s) => format!("(Number: {})", s),
20 CToken::Ident(ref s) => format!("(Ident: {})", s),
21 CToken::Add => "Add".to_string(),
22 CToken::Sub => "Sub".to_string(),
23 CToken::Mul => "Mul".to_string(),
24 CToken::Div => "Div".to_string(),
25 CToken::Mod => "Mod".to_string(),
26 CToken::LParens => "(".to_string(),
27 CToken::RParens => ")".to_string(),
28 })
29 }
30}
31
32fn token_spec() -> Result<ParserSpec<CToken>, SpecificationError<CToken>> {
33 let mut spec = ParserSpec::new();
34 add_null_assoc!(spec, PrecedenceLevel::Root, (CToken::Number("".to_string()), CToken::Ident("".to_string())) => |_, token: CToken, _| {
35 Ok(Node::Simple(token.clone()))
36 });
37 add_left_assoc!(spec, PrecedenceLevel::First, (CToken::Add, CToken::Sub) => |parser, token, lbp, node| {
38 Ok(Node::Composite { token: token.clone(), children: vec![node, parser.parse_expr(lbp)?] } )
39 } );
40 add_left_assoc!(spec, PrecedenceLevel::Second, (CToken::Mul, CToken::Div, CToken::Mod) => |parser, token, lbp, node| {
41 Ok(Node::Composite { token: token.clone(), children: vec![node, parser.parse_expr(lbp)?] } )
42 } );
43 add_null_assoc!(spec, PrecedenceLevel::First, (CToken::LParens) => |parser, _, lbp| {
44 let res = parser.parse_expr(lbp)?;
45 parser.consume(CToken::RParens)?;
46 Ok(res)
47 });
48 Ok(spec)
49}
50
51fn main() {
52 let tokens = vec![
53 CToken::Ident("a".to_string()),
54 CToken::Add,
55 CToken::LParens,
56 CToken::Number("10".to_string()),
57 CToken::Mul,
58 CToken::LParens,
59 CToken::Ident("b".to_string()),
60 CToken::Div,
61 CToken::Number("2".to_string()),
62 CToken::RParens,
63 CToken::Mod,
64 CToken::Number("4".to_string()),
65 CToken::RParens,
66 CToken::Sub,
67 CToken::Ident("c".to_string()),
68 ];
69 let lexer = LexerVec::new(tokens);
70 let spec = token_spec().expect("Should work.");
71 let mut parser = GeneralParser::new(spec, lexer);
72 let res = parser.parse();
73 println!("{:?}", res);
74}