Rust编译器插件库erg_compiler的使用,erg_compiler为Rust语言提供强大的编译时扩展和元编程支持
Rust编译器插件库erg_compiler的使用
erg_compiler为Rust语言提供强大的编译时扩展和元编程支持。以下是关于如何使用它的详细信息:
作为Python库使用
erg_compiler
可以通过pyo3/maturin构建为Python库。
示例代码
import erg_compiler
# 执行模块并获取变量
module = erg_compiler.exec_module(".i = 1")
# 假设有一个foo.er文件:
# .bar = 1
foo = erg_compiler.__import__("foo")
assert module.i == 1
assert foo.bar == 1
import erg_compiler
erg_parser = erg_compiler.erg_parser
erg_ast = erg_compiler.erg_parser.ast
# 解析并修改AST
module = erg_parser.parse(".i = 1")
d = module.pop()
d.sig = erg_ast.VarSignature.new(erg_ast.Identifier.public("j"), None)
module.push(d)
ast = erg_ast.AST.new("test", module)
code = erg_compiler.compile_ast(ast)
exec(code)
assert j == 1
完整示例
# erg_compiler_demo.py
import erg_compiler
def main():
# 示例1: 执行简单模块
module = erg_compiler.exec_module(".greeting = 'Hello, World!'")
print(module.greeting) # 输出: Hello, World!
# 示例2: 解析和修改AST
erg_parser = erg_compiler.erg_parser
erg_ast = erg_compiler.erg_parser.ast
module = erg_parser.parse(".x = 42")
decl = module.pop()
decl.sig = erg_ast.VarSignature.new(erg_ast.Identifier.public("answer"), None)
module.push(decl)
ast = erg_ast.AST.new("demo", module)
code = erg_compiler.compile_ast(ast)
exec(code)
print(answer) # 输出: 42
if __name__ == "__main__":
main()
安装方法
调试安装(使用venv)
python -m venv .venv
source .venv/bin/activate
maturin develop --features pylib_compiler
发布安装
maturin build -i python --release --features pylib_compiler
pip install <输出wheel文件>
作为Rust库使用
安装
cargo add erg_compiler
或在Cargo.toml中添加:
erg_compiler = "0.6.52"
项目信息
- 版本: 0.6.52
- 许可证: MIT OR Apache-2.0
- 大小: 499 KiB
erg_compiler提供了强大的编译时扩展能力,通过Python接口可以方便地进行元编程和AST操作。
完整示例demo
以下是基于erg_compiler的完整使用示例,展示了如何执行模块、解析和修改AST:
# erg_compiler_complete_demo.py
import erg_compiler
from erg_compiler.erg_parser import ast
def execute_simple_module():
"""执行简单模块示例"""
print("=== 执行简单模块 ===")
# 执行包含变量的简单模块
module = erg_compiler.exec_module(".message = 'Hello from Erg'")
print(f"模块变量值: {module.message}") # 输出: Hello from Erg
def parse_and_modify_ast():
"""解析和修改AST示例"""
print("\n=== 解析和修改AST ===")
# 解析原始代码
original_code = ".value = 100"
parsed = erg_compiler.erg_parser.parse(original_code)
# 修改AST节点
decl = parsed.pop()
# 将变量名从value改为count
decl.sig = ast.VarSignature.new(ast.Identifier.public("count"), None)
parsed.push(decl)
# 编译修改后的AST
modified_ast = ast.AST.new("modified", parsed)
compiled_code = erg_compiler.compile_ast(modified_ast)
# 执行编译后的代码
exec(compiled_code)
print(f"修改后的变量值: {count}") # 输出: 100
def import_external_module():
"""导入外部模块示例"""
print("\n=== 导入外部模块 ===")
# 假设有外部模块math.er包含: .pi = 3.1415926
try:
math_mod = erg_compiler.__import__("math")
print(f"导入的PI值: {math_mod.pi}") # 输出: 3.1415926
except Exception as e:
print(f"导入模块失败: {e}")
if __name__ == "__main__":
execute_simple_module()
parse_and_modify_ast()
import_external_module()
这个完整示例展示了erg_compiler的三个主要功能:
- 直接执行Erg模块代码
- 解析和修改抽象语法树(AST)
- 导入外部Erg模块
运行此示例前,请确保已按照前面介绍的安装方法正确安装erg_compiler。
1 回复
Rust编译器插件库erg_compiler使用指南
简介
erg_compiler是一个为Rust语言设计的编译器插件库,它提供了强大的编译时扩展和元编程支持。这个库允许开发者在编译阶段执行自定义逻辑,扩展Rust语言的语法和功能。
主要特性
- 编译时代码生成
- 自定义语法扩展
- 元编程支持
- 类型系统增强
- 编译时验证
安装方法
在Cargo.toml中添加依赖:
[dependencies]
erg_compiler = "0.1" # 请使用最新版本
基本使用方法
1. 定义编译器插件
use erg_compiler::plugin::{CompilerPlugin, PluginResult};
use syn::{ItemFn, parse_macro_input};
#[erg_compiler::compiler_plugin]
fn my_plugin(input: TokenStream) -> TokenStream {
// 解析输入
let input_fn = parse_macro_input!(input as ItemFn);
// 在这里处理AST并生成新的代码
let output = quote! {
#input_fn
// 添加额外的生成代码
fn generated_function() {
println!("This was generated at compile time!");
}
};
output.into()
}
2. 使用自定义属性
#[my_plugin]
fn original_function() {
println!("Original function");
}
// 编译后会生成额外的generated_function
3. 编译时验证示例
use erg_compiler::validator::{CompileTimeValidator, ValidationError};
struct MyValidator;
impl CompileTimeValidator for MyValidator {
fn validate(&self, item: &syn::Item) -> Result<(), ValidationError> {
if let syn::Item::Fn(fn_item) = item {
if fn_item.sig.ident == "unsafe_function" && !fn_item.sig.unsafety.is_some() {
return Err(ValidationError::new(
"Function named 'unsafe_function' must be marked as unsafe"
));
}
}
Ok(())
}
}
#[erg_compiler::register_validator]
static VALIDATOR: MyValidator = MyValidator;
高级用法
1. 语法扩展
use erg_compiler::syntax_extension::{SyntaxExtension, ExtensionResult};
struct DbQueryExtension;
impl SyntaxExtension for DbQueryExtension {
fn extend(&self, input: TokenStream) -> ExtensionResult {
// 解析自定义语法并转换为标准Rust代码
// ...
}
}
#[erg_compiler::register_extension]
static DB_QUERY_EXT: DbQueryExtension = DbQueryExtension;
使用示例:
db_query! {
SELECT * FROM users WHERE age > 18
}
2. 编译时代码生成
use erg_compiler::codegen::{CodeGenerator, CodegenContext};
struct ApiClientGenerator;
impl CodeGenerator for ApiClientGenerator {
fn generate(&self, ctx: &CodegenContext) -> TokenStream {
// 根据上下文生成API客户端代码
// ...
}
}
#[erg_compiler::register_codegen]
static API_CLIENT_GEN: ApiClientGenerator = ApiClientGenerator;
实际应用示例
1. 自动实现trait
#[erg_compiler::auto_derive]
trait JsonSerializable {
fn to_json(&self) -> String;
}
#[derive(JsonSerializable)
struct User {
name: String,
age: u32,
}
// 编译器会自动生成to_json方法的实现
2. 编译时路由注册
#[erg_compiler::web_route(GET, "/users")]
fn get_users() -> Json<Vec<User>> {
// ...
}
完整示例代码
下面是一个完整的示例,展示了如何使用erg_compiler创建自定义属性宏:
use erg_compiler::plugin::{CompilerPlugin, PluginResult};
use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn};
use quote::quote;
// 1. 定义编译器插件
#[erg_compiler::compiler_plugin]
fn benchmark_plugin(input: TokenStream) -> TokenStream {
// 解析输入函数
let input_fn = parse_macro_input!(input as ItemFn);
let fn_name = &input_fn.sig.ident;
// 生成带基准测试的代码
let output = quote! {
#input_fn
#[test]
fn benchmark_#fn_name() {
use std::time::Instant;
let start = Instant::now();
#fn_name();
let duration = start.elapsed();
println!("Function {} took {:?}", stringify!(#fn_name), duration);
}
};
output.into()
}
// 2. 使用自定义属性
#[benchmark_plugin]
fn expensive_operation() {
// 模拟耗时操作
for _ in 0..1_000_000 {
let _ = 1 + 1;
}
}
// 3. 编译时验证
struct BenchmarkValidator;
impl erg_compiler::validator::CompileTimeValidator for BenchmarkValidator {
fn validate(&self, item: &syn::Item) -> Result<(), erg_compiler::validator::ValidationError> {
if let syn::Item::Fn(fn_item) = item {
if fn_item.attrs.iter().any(|attr| attr.path.is_ident("benchmark_plugin")) {
if fn_item.sig.asyncness.is_some() {
return Err(erg_compiler::validator::ValidationError::new(
"Benchmarked functions cannot be async"
));
}
}
}
Ok(())
}
}
#[erg_compiler::register_validator]
static BENCH_VALIDATOR: BenchmarkValidator = BenchmarkValidator;
注意事项
- 编译器插件可能会增加编译时间
- 复杂的元编程可能使代码难以调试
- 确保插件生成的代码符合Rust的安全规则
- 在稳定版Rust中某些功能可能受限
erg_compiler为Rust开发者提供了强大的元编程能力,可以用于创建领域特定语言(DSL)、减少样板代码、实现编译时验证等高级功能。