1. Qiita
  2. 投稿
  3. mono

例のキヨシチェックを Sprache で書いてみる

  • 2
    いいね
  • 3
    コメント

はじめに

http://qiita.com/beinteractive/items/a2264048a601ee998aca

例の(?)が何だか解らないんですが、こういうのが上がってきたので、パーサの練習がてら書いてみました。

使ったもの

https://github.com/sprache/Sprache

C# の Monadic Parser だそうです。Monadic って Haskell で出てきたモナド的なヤツでしょうか。

できたもの

main.cs
using System;
using System.Collections.Generic;
using System.Text;
using Sprache;
using System.IO;

public class ZundokoGenerator {
  Random _random = new Random();
  public IEnumerator<string> RandomZunDoko() {
    for (;;) {
      yield return _random.Next(0, 2) == 0 ? "ズン" : "ドコ";
    }
  }
}

public static class KiyoshiParser {
  public static readonly Parser<string> zun =
    from txt in Parse.String("ズン").Text()
    select txt;
  public static readonly Parser<string> doko =
    from txt in Parse.String("ドコ").Text()
    select txt;
  public static readonly Parser<string> zzzd =
    from z0 in zun
    from z1 in zun
    from z2 in zun
    from z3 in zun
    from dk in doko
    select "キヨシ";
}

class Program {
  static void Main() {
    var zdg = new ZundokoGenerator().RandomZunDoko();
    var sb = new StringBuilder();
    int count = 0;
    for (;;) {
      sb.Clear();
      for (int i = 0; i < 5; ++i) {
        zdg.MoveNext();
        sb.Append(zdg.Current);
      }
      ++count;
      try {
        var kys = KiyoshiParser.zzzd.Parse(sb.ToString());
        Console.WriteLine(sb.ToString() + kys);
        Console.WriteLine(count + "回ズンドコしました");
        break;
      }
      catch (Sprache.ParseException) {
        Console.WriteLine(sb.ToString());
      }
    }
  }
}

解説

ZundokoGenerator

クラス ZundokoGenerator は元になった記事からパクってきましたが、実は UnityEngine.Random が使われていたので、 System.Random を使うように変更しました。

IEnumerator で、ズン or ドコを延々と返すだけですね。

KiyoshiParser

パーサ本体です。

文法についてはなんとなく見てもらえば解ると思いますが、 LINQ のクエリ構文で繋いでいく感じです。

詳しいところは Sprache のドキュメントをあたってもらった方がいいと思いますが、 bisonyacc でいうパターンを from の羅列で記述し、 select でアクションといった感じです。

注意する点は、 Parse.String() は返値が IEnumerator<char> (だっけ?)になっているので、 string に変換してやる必要があるところです。

Program

メインの処理です。

正しくないズンドコ(?)の際は例外で処理しています。

コンパイル&結果

% mcs main.cs -r:Sprache.dll ; mono main.exe
ドコズンズンズンズン
ズンズンズンズンズン
ドコドコズンドコズン
ドコズンドコズンズン
ドコズンズンドコズン
ドコドコズンドコズン
ズンドコドコズンズン
ドコズンドコドコズン
ズンドコズンズンドコ
ズンドコズンドコドコ
ズンドコドコズンズン
ドコドコズンドコズン
ズンドコドコズンドコ
ドコドコズンズンズン
ドコズンドコズンドコ
ドコズンズンズンズン
ズンドコドコドコズン
ズンズンズンズンドコキヨシ
18回ズンドコしました

簡単ですね('ω`)

Comments Loading...