使用 nom 捕获整个连续匹配的输入

tro*_*ine 5 parser-combinators rust

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

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

在哪里

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

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

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

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


在撰写本文时,我正在使用 nom1.2.2和 rustc 1.9.0-nightly (a1e29daf1 2016-03-25)

She*_*ter 5

看起来好像您想要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,
    }
}
Run Code Online (Sandbox Code Playgroud)

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