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
