簡體   English   中英

Rust 中的 S 表達式 macro_rules

[英]S-expression in Rust macro_rules

我正在編寫自己的語言編譯器,我想用我的宏將 AST 描述為 S 表達式。

以下是不起作用的最小示例代碼。

#[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!($left)), OP::Add, Box::new(ast!($right)))
    };
    ($other:tt) => {
        Expression::from($other)
    };
}

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)); // error: expected expression, found `+`
              // ^ expected expression
}

您需要一個單獨的宏來解析 arguments。 試試這個代碼:

#[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
}

游樂場鏈接: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e35fcd9aa7b126cd34aea6b33857e6c9

如果你想用宏創建類似 Lisp 的語言,請檢查這個項目: https://github.com/JunSuzukiJapan/macro-lisp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM