token_spec/
token_spec.rs

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}