You can use syntex to parse Rust, so you don't need to use unstable Rust.
Here is a simple example:
// Tested against syntex_syntax v0.33 extern crate syntex_syntax as syntax; use std::rc::Rc; use syntax::codemap::{CodeMap}; use syntax::errors::{Handler}; use syntax::errors::emitter::{ColorConfig}; use syntax::parse::{self, ParseSess}; fn main() { let codemap = Rc::new(CodeMap::new()); let tty_handler = Handler::with_tty_emitter(ColorConfig::Auto, None, true, false, codemap.clone()); let parse_session = ParseSess::with_span_handler(tty_handler, codemap.clone()); let src = "fn foo(x: i64) { let y = x + 1; return y; }".to_owned(); let result = parse::parse_crate_from_source_str(String::new(), src, Vec::new(), &parse_session); println!("parse result: {:?}", result); }
This prints the entire AST:
parse result: Ok(Crate { module: Mod { inner: Span { lo: BytePos(0), hi: BytePos(43), expn_id: ExpnId(4294967295) }, items: [Item { ident: foo#0, attrs: [], id: 4294967295, node: Fn(FnDecl { inputs: [Arg { ty: type(i64), pat: pat(4294967295: x), id: 4294967295 }], output: Default(Span { lo: BytePos(15), hi: BytePos(15), expn_id: ExpnId(4294967295) }), variadic: false }, Normal, NotConst, Rust, Generics { lifetimes: [], ty_params: [], where_clause: WhereClause { id: 4294967295, predicates: [] } }, Block { stmts: [stmt(4294967295: let y = x + 1;), stmt(4294967295: return y;)], expr: None, id: 4294967295, rules: Default, span: Span { lo: BytePos(15), hi: BytePos(43), expn_id: ExpnId(4294967295) } }), vis: Inherited, span: Span { lo: BytePos(0), hi: BytePos(43), expn_id: ExpnId(4294967295) } }] }, attrs: [], config: [], span: Span { lo: BytePos(0), hi: BytePos(42), expn_id: ExpnId(4294967295) }, exported_macros: [] })