簡體   English   中英

Rust中的程序宏解析怪異

[英]Procedural macro parsing weirdness in Rust

我正在嘗試解析與此宏類似的宏:

annoying!({
    hello({
        // some stuff
    });
})

嘗試使用類似於以下內容的過程宏定義來執行此操作,但是我遇到了意外的行為,並且不確定自己是否在做我不應該做的事情,或者發現了錯誤。 在下面的示例中,我試圖找到每個塊所在的行,對於第一個塊(正好在里面的那個煩人!),它報告正確的行,但是對於內部塊,當我嘗試打印它們時,它總是1,無論代碼在哪里等等

#![crate_type="dylib"]
#![feature(macro_rules, plugin_registrar)]

extern crate syntax;
extern crate rustc;

use macro_result::MacroResult;
use rustc::plugin::Registry;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::ext::quote::rt::ToTokens;
use syntax::codemap::Span;
use syntax::ast;
use syntax::parse::tts_to_parser;

mod macro_result;

#[plugin_registrar]
pub fn plugin_registrar(registry: &mut Registry) {
    registry.register_macro("annoying", macro_annoying);
}

pub fn macro_annoying(cx: &mut ExtCtxt, _: Span, tts: &[ast::TokenTree]) -> Box<MacResult> {
    let mut parser = cx.new_parser_from_tts(tts);

    let lo = cx.codemap().lookup_char_pos(parser.span.lo);
    let hi = cx.codemap().lookup_char_pos(parser.span.hi);

    println!("FIRST LO {}", lo.line); // real line for annoying! all cool
    println!("FIRST HI {}", hi.line); // real line for annoying! all cool

    let block_tokens = parser.parse_block().to_tokens(cx);
    let mut block_parser = tts_to_parser(cx.parse_sess(), block_tokens, cx.cfg());

    block_parser.bump(); // skip {
    block_parser.parse_ident(); // hello
    block_parser.bump(); // skip (

    // block lines
    let lo = cx.codemap().lookup_char_pos(block_parser.span.lo);
    let hi = cx.codemap().lookup_char_pos(block_parser.span.hi);

    println!("INNER LO {}", lo.line); // line 1? wtf?
    println!("INNER HI {}", hi.line); // line 1? wtf?

    MacroResult::new(vec![])
}

我認為問題可能是因為我正在創建第二個解析器來解析內部塊,並且可能使其中的Span類型變得瘋狂,但是我不確定這是問題所在還是如何避免這里。 我創建第二個解析器的原因是,我可以遞歸地解析每個塊中的內容,我可能正在做我不應該做的事情,在這種情況下,將歡迎更好的建議。

我相信這是#15962 (和#16472 ), to_tokens具有普遍可怕的實現。 具體來說,任何不平凡的事情都使用ToSource ,它只是將代碼轉換為字符串,然后重新標記(是的,一點都不好!)。

在解決這些問題之前,您應該盡可能直接直接處理原始的tts 您可以使用已解析塊的.span來近似正確的跨度(即parse_block返回值),這至少會將用戶的注意力集中在正確的區域上。

暫無
暫無

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

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