2016-03-30 7 views
4

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)を使用しています。この記事の執筆時点では


答えて

3

あなたがrecognized!をしたいかのように表示されます。

if the child parser was successful, return the consumed input as produced value

そして例:

#[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!はシーケンシャルパーサを組み合わせる最良の方法であるかどうかわからないんだけど値を気にしますが、この場合は機能します。

+0

ああ、私は誤解していました。ありがとうございました! – troutwine

+0

「<&[u8], &str>」ではなく、「<&str, &str>」があればどうなりますか? 'エラー:現在のスコープ内に\'&str \ '型の\' offset \ 'という名前のメソッドは見つかりませんでした。 – Sergey

関連する問題