【问题标题】:Capture the entire contiguous matched input with nom使用 nom 捕获整个连续匹配的输入
【发布时间】:2016-03-30 05:25:58
【问题描述】:

我希望应用一系列 nom 解析器并返回匹配的完整 &str。我想匹配a+bc+ 形式的字符串。使用现有的chain! macro 我可以非常接近:

named!(aaabccc <&[u8], &str>,
   map_res!(
       chain!(
           a: take_while!(is_a) ~
               tag!("b") ~
               take_while!(is_c) ,
           || {a}
           ),
       from_utf8
   ));

在哪里

fn is_a(l: u8) -> bool {
   match l {
       b'a' => true,
       _ => false,
   }
}

fn is_c(l: u8) -> bool {
    match l {
        b'c' => true,
        _ => false,
    }
}

假设我们有“aaabccc”作为输入。上面的解析器将匹配输入,但只会返回“aaa”。我想做的是返回原始输入“aaabccc”。

chain! 不是正确的宏,但没有另一个看起来更正确的宏。最好的方法是什么?


在撰写本文时,我使用的是 nom 1.2.2 和 rustc 1.9.0-nightly (a1e29daf1 2016-03-25)

【问题讨论】:

    标签: rust parser-combinators


    【解决方案1】:

    看起来好像你想要recognized!

    如果子解析器成功,则将消耗的输入作为生成值返回

    还有一个例子:

    #[macro_use]
    extern crate nom;
    
    use nom::IResult;
    
    fn main() {
        assert_eq!(aaabccc(b"aaabcccddd"), IResult::Done(&b"ddd"[..], "aaabccc"));
    }
    
    named!(aaabccc <&[u8], &str>,
       map_res!(
           recognize!(
               chain!(
                   take_while!(is_a) ~
                   tag!("b") ~
                   take_while!(is_c),
                   || {}
               )
           ),
           std::str::from_utf8
       )
    );
    
    fn is_a(l: u8) -> bool {
       match l {
           b'a' => true,
           _ => false,
       }
    }
    
    fn is_c(l: u8) -> bool {
        match l {
            b'c' => true,
            _ => false,
        }
    }
    

    如果您不关心这些值,我不确定chain! 是否是组合顺序解析器的最佳方式,但它在这种情况下有效。

    【讨论】:

    • 啊,我误会了recognize!。谢谢!
    • 如果我有&lt;&amp;str, &amp;str&gt;,而不是&lt;&amp;[u8], &amp;str&gt;,该怎么办?我得到error: no method named `offset` found for type `&amp;str` in the current scope
    猜你喜欢
    • 1970-01-01
    • 2020-05-17
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    相关资源
    最近更新 更多