I have a lexical analyzer modeled after what Rob Pike described doing in Go. It uses function pointers to represent the states, and the finite state machine simply invokes functions, gets the next function as a return value, and loops until it gets nil. In Go this is easy, but Rust is a bit trickier.
struct StateFn(fn(&mut Lexer) -> Option<StateFn>);
pub fn lex(name: &str, input: &str) -> Receiver<Token> {
// code for setting up the channel...
thread::spawn(move || {
let mut lexer = Lexer::new(thread_name, sanitized, thread_tx);
let mut state = lex_start as fn(&mut Lexer) -> Option<StateFn>;
loop {
match state(&mut lexer) {
Some(next) => {
let StateFn(state_fn) = next;
state = state_fn;
},
None => break
}
}
});
// return the receiver end of the channel...
}
fn lex_start(l: &mut Lexer) -> Option<StateFn> {
lex_some_other_func
}
// more state functions...
This has compiled without warning and been working for some time, but with the latest build (27901849e 2015-03-25) it is now telling me that the cast on the "let mut state = ..." line is trivial. However, I can't figure out how to take it away and still have it compile. Any advice?
Thanks
Full source: shiranui/lexer.rs at master · nlfiedler/shiranui · GitHub (see line 389)