You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust过程宏中解析任意自定义令牌?

Rust DSL解析器自定义字面量解决方案

由于syn、quote和proc-macro2严格遵循Rust语法规则,你的自定义单引号字符串、date'2023-02-26'这类字面量不符合Rust token规范,无法直接通过这些工具解析。按你的需求,只需按空格拆分提取令牌,可按以下步骤实现:

1. 手动实现DSL令牌拆分函数

核心是识别单引号边界,确保带单引号的内容被作为单个令牌,不会被空格拆分。示例代码:

fn split_dsl_tokens(input: &str) -> Vec<&str> {
    let mut tokens = Vec::new();
    let mut start = 0;
    let mut in_quote = false;
    let chars = input.chars().collect::<Vec<_>>();
    
    for (i, c) in chars.iter().enumerate() {
        match c {
            '\'' => in_quote = !in_quote,
            ' ' if !in_quote => {
                if start < i {
                    tokens.push(&input[start..i]);
                }
                start = i + 1;
            }
            _ => {}
        }
    }
    
    if start < chars.len() {
        tokens.push(&input[start..]);
    }
    
    tokens
}

这个函数会将'single quoted' date'2023-02-26'拆分为["'single quoted'", "date'2023-02-26'"]这样的令牌列表。

2. 自定义令牌解析逻辑

拿到拆分后的令牌后,可根据格式自行解析:

let dsl_input = "'single quoted' date'2023-02-26'";
for token in split_dsl_tokens(dsl_input) {
    // 处理单引号字符串
    if token.starts_with('\'') && token.ends_with('\'') {
        let content = &token[1..token.len()-1];
        // 这里添加你的字符串处理逻辑
        println!("String literal: {}", content);
    }
    // 处理日期字面量
    else if token.starts_with("date'") && token.ends_with('\'') {
        let date_str = &token[5..token.len()-1];
        // 这里添加你的日期解析逻辑
        println!("Date literal: {}", date_str);
    }
    // 其他类型令牌处理
    else {
        println!("Other token: {}", token);
    }
}

3. 配合syn/proc-macro2生成代码

如果需要将解析后的内容转换为Rust代码,可在处理完令牌后,将合法的Rust语法片段传入quote!或syn进行处理,避免直接将自定义字面量传入这些工具。

内容的提问来源于stack exchange,提问作者Konrad Koschel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:02:51