I have a fork of Ragel that supports Rust, which you can find here:
https://github.com/erickt/ragel. I just updated it to support rust
incoming. It performs pretty well too, the url example can parse urls
roughly 2-3 times faster than the hand written parser in the standard
library. I'll try to push my ragel patches upstream one rust 0.6 lands.

For those of you that haven't heard of Ragel, it's part way between regular
expressions and a full parser generator. It builds state machines, and
allows you to manipulate state transitions to parse more complex grammars.
It's pretty neat. For example, here is a simple reverse polish notation
calculator:

https://github.com/erickt/ragel/blob/rust/examples/rust/rpn.rl

%% machine rpn;
%% write data;

fn rpn(data: &str) -> Result<int, ~str> {

    let mut cs = 0;
    let mut p = 0;
    let mut pe = data.len();
    let mut mark = 0;
    let mut st = ~[];

    %%{
        action mark { mark = p; }

        action push {
            let s = data.slice(mark, p);

            match int::from_str(s) {
              None => return Err(fmt!("invalid integer %s", s)),

              Some(i) => st.push(i),
            }

        }
        action add  { let y = st.pop(); let x = st.pop(); st.push(x + y); }

        action sub  { let y = st.pop(); let x = st.pop(); st.push(x - y); }
        action mul  { let y = st.pop(); let x = st.pop(); st.push(x * y); }
        action div  { let y = st.pop(); let x = st.pop(); st.push(x / y); }

        action abs  { let x = st.pop(); st.push(int::abs(x));             }
        action abba { st.push(666); }

        stuff  = digit+ >mark %push
               | '+' @add
               | '-' @sub
               | '*' @mul
               | '/' @div
               | 'abs' %abs
               | 'add' %add
               | 'abba' %abba
               ;


        main := ( space | stuff space )* ;

        write init;
        write exec;
    }%%

    if cs < rpn_first_final {
        if p == pe {
            Err(~"unexpected eof")
        } else {
            Err(fmt!("error at position %u", p))

        }
    } else if st.is_empty() {
        Err(~"rpn stack empty on result")
    } else {
        Ok(st.pop())

    }
}
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to