2017-03-14 2 views
5

私はRustのパーサを実装しています。空白は、matchパターンで再利用したい一般的なパターンです。Rustの変数にパターンを保存するにはどうしたらいいですか?

このコードは動作します:

let ch = ' '; 

match ch { 
    ' ' | '\n' | '\t' | '\r' => println!("whitespace"), 
    _ => println!("token"), 
} 

私は空白のパターンを毎回指定するに保つために必要がある場合は、これは本当に繰り返しになるだろう。私はそれを一度定義して再利用したいと思います。私は次のようなことをしたい:

let whitespace = ' ' | '\n' | '\t' | '\r'; 

let ch = ' '; 

match ch { 
    whitespace => println!("whitespace"), 
    _   => println!("token"), 
} 

コンパイラはws割り当てが気に入らない。これは、代替の代わりに|をバイナリ操作として解釈します。

パターンは何らかの形で変数に格納できますか?これを行うにはより良い方法や慣用的な方法がありますか?

+0

これはマクロのための良い候補のように見えますが、マクロがRustに行く方法であるのかどうか疑問です... – turbulencetoo

+0

@ turbulencetoo興味深い考えです。 Cでは、マクロは低レベルのテキスト操作であり、結果としてソースコードが無効になる可能性があります。 Rustでは、マクロを呼び出すことができる場所の数は限られており、拡張は構文的に有効でなければなりません。私はパターンが有効な場所のセットにあるとは思わない。しかし、あなたはいつでも有効な錆のコードになるようなテキストファイルを生成するためのビルドスクリプトを作成することができます。 – Shepmaster

答えて

10

パターンは何らかの形で変数に格納できますか?

いいえパターンはコンパイル時の構造であり、変数は実行時の概念を保持します。

これを行うには、より良い方法や慣用的な方法がありますか?

コードを繰り返すのを避けるために、関数またはメソッドを作成することは、常に良い解決策です。

fn is_whitespace(c: char) -> bool { 
    match c { 
     ' ' | '\n' | '\t' | '\r' => true, 
     _ => false, 
    } 
} 

fn main() { 
    let ch = ' '; 

    match ch { 
     x if is_whitespace(x) => println!("whitespace"), 
     _ => println!("token"), 
    } 
} 

私も強くof which there are a multitude、既存のパーサを使用することをお勧めしたい、誰もが何らかの理由で、解析することが彼らの錆の「Hello World」を望んでいます。右側に

sequence!(pm, pt, { 
    _   = literal("if"); 
    ws   = whitespace; 
    _   = literal("let"); 
    ws   = append_whitespace(ws); 
    pattern = pattern; 
    ws   = optional_whitespace(ws); 
    _   = literal("="); 
    ws   = optional_whitespace(ws); 
    expression = expression; 
}, |_, _| /* do something with pieces */); 

物事の各されています

私が使用して解析するライブラリがwhitespaceは空白の有効なタイプを解析する方法を知っている機能である、これに似たコードを書くことができます特定のものを解析する方法を知っている個々の機能は依然としてあります。

関連する問題