5 个版本
0.0.5 | 2023年11月4日 |
---|---|
0.0.4 | 2023年10月22日 |
0.0.3 | 2023年8月8日 |
0.0.2 | 2023年7月5日 |
0.0.1 | 2023年7月5日 |
#1080 在 解析器实现
89 每月下载量
165KB
5.5K SLoC
ruast
此包提供可打印并可修改的 Rust AST。
基本用法
Hello world
use ruast::*;
let mut krate = Crate::new();
let def = Fn::main(
None,
Block::from(Path::single("println").mac_call(vec![Token::lit("Hello, world!")])),
);
krate.add_item(def);
println!("{krate}");
krate.dump("test.rs")?;
krate.remove_item_by_id("main");
assert!(krate.is_empty());
这相当于
use ruast::*;
let mut krate = Crate::new();
krate.add_item(Fn {
ident: "main".to_string(),
generics: vec![],
fn_decl: FnDecl::new(vec![], None),
body: Some(Block::from(
Stmt::Expr(Expr::new(MacCall {
path: Path::single("println!"),
args: DelimArgs::from(vec![Token::lit("Hello, world!")]),
})),
)),
});
println!("{krate}");
krate.dump("test.rs")?;
krate.remove_item_by_id("main");
assert!(krate.is_empty());
构建结构体、枚举和 impl
use ruast::*;
let mut krate = Crate::new();
let def = StructDef::empty("Foo")
.with_field(FieldDef::inherited("foo", Type::from("u32")))
.with_field(FieldDef::inherited("bar", Type::from("u32")));
krate.add_item(def);
let imp = Impl::empty("Foo")
.with_item(Fn::empty_method("test", Pat::ref_self()));
krate.add_item(imp);
println!("{krate}");
use ruast::*;
let mut krate = Crate::new();
let def = EnumDef::empty("Foo")
.with_variant(Variant::empty("Bar"))
.with_variant(Variant::tuple("Baz", vec![FieldDef::anonymous("u32")]));
krate.add_item(def);
let imp = Impl::empty("Foo")
.with_item(Fn::empty_method("test", Pat::ref_self()));
krate.add_item(imp);
println!("{krate}");
转换为 proc_macro2::TokenStream
通过启用功能 tokenize
,您可以转换 ruast
AST 到 proc_macro2::TokenStream
。
您可以在不使用 syn
或 quote
宏的情况下系统地构建 AST。
use ruast::*;
let mut krate = Crate::new();
let def = Fn::main(
None,
Block::from(Path::single("println").mac_call(vec![Token::lit("Hello, world!")])),
);
krate.add_item(def);
let tokens = krate.to_token_stream();
println!("{krate}");
println!("{tokens}");
为什么需要这个?
Rust 项目 有一个名为 rustc_ast
的子模块,该子模块定义了一个 AST,但它没有在 crates.io 上发布,并且需要构建一个巨大的 rust
自身。此外,rustc_ast
不是为第三方手动构建 AST 而设计的。
有一个 codegen
包用于 Rust 代码生成,但这个包已经有一段时间没有维护,并且仅支持基本语法元素。
还有一个 syn
包可以将 proc_macro::TokenStream
解析为 AST,但它的 AST 元素没有实现 Display
特性,并且不是为直接构建和修改而设计的。
目标
本项目目标是提供一个简单且易于携带的 Rust AST 构建/Rust 代码生成库。
非目标
此库与 Rust 编译器 AST 没有直接关系,并且使用此库构建的 AST 不能直接作为编译器的输入。
许可证
本项目许可受 Apache 许可证 2.0 版 或 MIT 许可证 之一约束,由您选择。