Rust宏规则中的S-表达式
我正在编写自己的语言编译器,我想用宏将AST描述为S表达式 下面是不起作用的最小示例代码Rust宏规则中的S-表达式,rust,Rust,我正在编写自己的语言编译器,我想用宏将AST描述为S表达式 下面是不起作用的最小示例代码 #[派生(调试,部分Q)] 发布枚举表达式{ BinOP(盒子,OP,盒子), 编号(f64), } #[派生(调试,部分Q)] 发布枚举操作{ 添加 } 宏规则!ast{ (+$left:tt$right:tt)=>{ 表达式::BinOP(Box::new(ast!($left)),OP::Add,Box::new(ast!($right))) }; ($其他:tt)=>{ 表达式::from($oth
#[派生(调试,部分Q)]
发布枚举表达式{
BinOP(盒子,OP,盒子),
编号(f64),
}
#[派生(调试,部分Q)]
发布枚举操作{
添加
}
宏规则!ast{
(+$left:tt$right:tt)=>{
表达式::BinOP(Box::new(ast!($left)),OP::Add,Box::new(ast!($right)))
};
($其他:tt)=>{
表达式::from($other)
};
}
用于表达式的impl From{
fn from(u:usize)->Self{
表达式::编号(u为f64)
}
}
fn main(){
dbg!(ast!(+12));//这很有效。
dbg!(ast!(+(+3 4)2));//错误:应为表达式,已找到`+`
//^预期表达式
}
您需要一个单独的宏来解析参数。请尝试以下代码:
#[derive(Debug, PartialEq)]
pub enum Expression {
BinOP(Box<Expression>, OP, Box<Expression>),
Number(f64),
}
#[derive(Debug, PartialEq)]
pub enum OP {
Add,
}
macro_rules! ast {
(+ $left:tt $right:tt) => {
Expression::BinOP(Box::new(ast_arg!($left)), OP::Add, Box::new(ast_arg!($right)))
};
}
#[macro_export]
macro_rules! ast_arg {
( ( $e:tt ) ) => (ast!($e));
( ( $($e:tt)* ) ) => ( ast!( $($e)* ) );
($e:expr) => (Expression::from($e));
}
impl From<usize> for Expression {
fn from(u: usize) -> Self {
Expression::Number(u as f64)
}
}
fn main() {
dbg!(ast!(+ 1 2)); // this works
dbg!(ast!(+ (+ 3 4) 2)); // also works now
}
#[派生(调试,部分Q)]
发布枚举表达式{
BinOP(盒子,OP,盒子),
编号(f64),
}
#[派生(调试,部分Q)]
发布枚举操作{
添加
}
宏规则!ast{
(+$left:tt$right:tt)=>{
表达式::BinOP(Box::new(ast_arg!($left)),OP::Add,Box::new(ast_arg!($right)))
};
}
#[宏_导出]
宏规则!阿斯特阿格{
($e:tt))=>(ast!($e));
($($e:tt)*)=>(ast!($($e)*);
($e:expr)=>(表达式::from($e));
}
用于表达式的impl From{
fn from(u:usize)->Self{
表达式::编号(u为f64)
}
}
fn main(){
dbg!(ast!(+12));//这很有效
dbg!(ast!(+(+34)2));//现在也可以工作了
}
游乐场连接:
如果您想用宏创建类似Lisp的语言,请检查此项目:谢谢您的回答!你的代码运行良好!我有一个小问题,
($e:tt))=>(ast!($e))代码>,是否需要此行?没有这个看起来很好。是的,你完全正确,第一条规则是不必要的,因为第二条规则涵盖了这种情况。