Skip to content

Instantly share code, notes, and snippets.

@kkismd
Last active December 2, 2023 03:43
Show Gist options
  • Save kkismd/3f2db9dce843bd841799cff10da49d35 to your computer and use it in GitHub Desktop.
Save kkismd/3f2db9dce843bd841799cff10da49d35 to your computer and use it in GitHub Desktop.

Q

パーサーの定義の最後にある (input) の文法的な意味を教えてください

A

Rustでは、関数は値を返すことができますが、その返り値は最後に評価された式です。この特性を利用して、関数の本体を括弧で囲むことで、その関数が別の関数に引数として渡されることを可能にします。このパターンは、高階関数(他の関数を引数として取る関数)を使用する際によく見られます。

ここでの (input) は、nom パーサーコンビネータの一部で、これは関数を返します。この関数は、入力文字列(ここでは input)を引数として取り、パース結果を返します。つまり、 (input) はパーサー関数を実行しています。

例えば、以下のコードを見てみましょう:

fn parse_identifier(input: &str) -> IResult<&str, Expr> {
    map(
        recognize(tuple((
            alt((
                preceded(tag("."), parse_alphanumeric_underscore),
                parse_alphanumeric_underscore,
            )),
            many0(alphanumeric1),
        ))),
        |id_str: &str| Expr::Identifier(id_str.to_string()),
    )(input)
}

このコードでは、map 関数は2つの引数を取ります。1つ目はパーサー(recognize 関数によって生成される)、2つ目はクロージャです。そして、 map 関数は新しいパーサー関数を返します。この新しいパーサー関数は、最後の (input) で実行され、入力文字列をパースします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment