topdown-rs 0.2.0

A top-down parsing library
docs.rs failed to build topdown-rs-0.2.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: topdown-rs-0.3.3

topdown-rs

A top-down parsing library for Rust.

Example

#![allow(unused_variables)]
#![feature(phase)]
extern crate topdown;
#[phase(plugin)]
extern crate topdown;
use topdown::{CharSeq, skip, Parser, wrap, choice, ParserResult, re, chainl};
use topdown::ParserResult::{Succ, Error, Fail};

fn op1<'a>(cs: &mut CharSeq) -> ParserResult<|int, int|:'a->int> {
    return run_parser!(
        cs >> &re("\\+|-") -> |o|
            match o.as_slice() {
                "+" => |a:int, b:int| a+b,
                "-" => |a:int, b:int| a-b,
                _ => panic!(o)
            }
        )
}

fn op2<'a>(cs: &mut CharSeq) -> ParserResult<|int, int|:'a->int> {
    return run_parser!(
        cs >> &re("\\*|/|%") -> |o| 
        match o.as_slice() {
            "*" => |a:int, b:int| a*b,
            "/" => |a:int, b:int| a/b,
            "%" => |a:int, b:int| a%b,
            _ => panic!(o)
        }
    )
}

fn digit(cs: &mut CharSeq) -> ParserResult<int> {
    run_parser!(
        cs >> &re("-?[1-9][0-9]*") -> |x| x.as_slice().parse().unwrap())
}

#[allow(unused_variables)]
fn factor(cs: &mut CharSeq) -> ParserResult<int> {
    run_parser!(
        cs >> &"(" -> |i|
        &wrap(expr) ->|e|
        &")" -> |i2| e
    )
}

fn term(cs: &mut CharSeq) -> ParserResult<int> {
    let f = wrap(factor);
    let d = wrap(digit);
    let l = [&d as &Parser<int>, &f as &Parser<int>];
    let c = choice(&l);
    let o = wrap(op2);
    let cl = chainl(&c, &o, false);
    cs.accept(&cl)
}

fn expr(cs: &mut CharSeq) -> ParserResult<int> {
    let t = wrap(term);
    let o = wrap(op1);
    let cl = chainl(&t, &o, false);
    return cs.accept(&cl);
}

fn calc(e: &str) {
    let mut cs = CharSeq::new(e, "");
    let skip = skip(" ");
    cs.add_hook(&skip);
    match cs.accept(&wrap(expr)) {
        Succ(x) => {
            if !cs.eof() {
                println!("error: {}", e);
            } else {
                println!("{}={}", e, x)
            }
        },
        Fail(m, l) => println!("error: {}", e),
        Error(m, l) => println!("error: {}", e)
    }
}

fn main() {
    calc("1 + 2 - 3 * 4");
    calc("1 + (2 - 3) * 4");
    calc("1 + (2 - 3)) * 4");
    calc("1 + (2 - 3 * 4");
}

License

MIT