【D言語】ctpgの演算子たち【ctpg】

D言語erの皆さん、こんにちは。 今回は、D言語の話題に戻って、ctpgの演算子を少し紹介します。

AND述語


前置演算子で、「&」です。 任意のパーサで先読みをします。 掛かっているパーサがマッチしたら自身もマッチします。 先読みなので、入力は消費しません。 型は、Tuple!()になるので、連結したりしたら消えてくれます。


import ctpg;

mixin(generateParsers(q{
    string hoge = &"hoge" "ho";
}));

void main(){
    auto result = "hoge".parse!hoge();
    assert(result.match);
    assert(result.value == "ho");
    assert(result.next.source == "ge");

    result = "ho".parse!hoge();
    assert(!result.match)
}

上の例だと、一度"hoge"を先読みしてから、"ho"でパースしています。 2つ目は、"hoge"の先読みに失敗するので、全体として失敗しています。

NOT述語


前置演算子で、「^」です。この部分だけ、PEGと違うので気をつけて下さい。 任意のパーサで先読みをします。 掛かっているパーサがマッチしなかったら、自身がマッチします。 AND述語の逆ということですね。 AND述語と同じく先読みなので、入力は消費しません。 型は、Tuple!()になるので、連結したりしたら消えてくれます。


import ctpg;

mixin(generateParsers(q{
    string hoge = ^"a" parseAnyChar;
}));

void main(){
    auto result = "hoge".parse!hoge();
    assert(result.match);
    assert(result.value == "h");

    result = "ahoge".parse!hoge();
    assert(!result.match)
}

上の例だと、一度"a"を先読みしてから、parseAnyCharでパースしています。 2つ目は、"a"の先読みに成功してしまうので、全体として失敗しています。 NOT述語はparseAnyCharと一緒に、「〜以外の任意の文字」を実現するためによく使われます。

まとめ


ctpgの一部の演算子について見てきました。 先読みはとても便利なので、ぜひ使ってみて下さい。

ところで、今D言語 Advent Calendarという企画が行われています。 そちらの方で、ctpgに関する記事を二つ書いたので、そちらも見てみて下さい。

担当:美馬(ctpgのドキュメントを書いてなくて、本当に申し訳 of the world)