*** empty log message ***
authorhanda <handa>
Thu, 13 Aug 2009 01:41:35 +0000 (01:41 +0000)
committerhanda <handa>
Thu, 13 Aug 2009 01:41:35 +0000 (01:41 +0000)
peg.cs [new file with mode: 0644]

diff --git a/peg.cs b/peg.cs
new file mode 100644 (file)
index 0000000..4064434
--- /dev/null
+++ b/peg.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+public class Pair<A, B> {
+  public A _1 { get; private set; }
+  public B _2 { get; private set; }
+  public Pair(A _1, B _2) {
+    this._1 = _1;
+    this._2 = _2;
+  }
+  public override string ToString() { 
+    return string.Format("({0}, {1})", _1, _2);
+  }
+}
+public class ParseResult<A> {
+  public A Item { get; private set; }
+  public string Rest { get; private set; }
+  public ParseResult(A item, string rest) {
+    Item = item;
+    Rest = rest;
+  }
+  public override string ToString() { 
+    return string.Format("(value = {0}, rest = {1})", Item, Rest);
+  }
+}
+public class Parser<A> {
+  public Func<string, ParseResult<A>> Target { get; set; }
+  public Parser(Func<string, ParseResult<A>> target) {
+    Target = target;
+  }
+  public ParseResult<A> Parse(string input) {
+    return Target(input);
+  }
+  public static Parser<A> Make(Func<string, ParseResult<A>> target) {
+    return new Parser<A>(target);
+  }
+  public static implicit operator Parser<object>(Parser<A> p) {
+    return Parser<object>.Make((input) => {
+      var r = p.Parse(input);
+      return r != null ? new ParseResult<object>(r.Item, r.Rest) : null;
+    });
+  }
+  public Parser<A> Or(Parser<A> p2) {
+    return Make((input) => {
+      var r = Parse(input);
+      return r != null ? r : p2.Parse(input);
+    });
+  }
+  public Parser<Pair<A, B>> Seq<B>(Parser<B> p2) {
+    return Parser<Pair<A, B>>.Make((input) => {
+      var r1 = Parse(input);
+      if(r1 == null) return null;
+      var r2 = p2.Parse(r1.Rest);
+      if(r2 == null) return null;
+      return new ParseResult<Pair<A, B>>(
+        new Pair<A, B>(r1.Item, r2.Item), r2.Rest
+      );
+    });
+  }
+  public static Parser<object> operator!(Parser<A> p) {
+    return p.Not();
+  }
+  public static Parser<Object> operator~(Parser<A> p) {
+    return p.And();
+  }
+  public Parser<object> Not() {
+    return Parser<object>.Make((input) => {
+      var r = Parse(input);
+      return r == null ? new ParseResult<object>(null, input) : null;
+    });
+  }
+  public Parser<object> And() {
+    return this.Not().Not();
+  }
+  public Parser<A> Opt() {
+    return Or(BasicOperations.Str("").Apply<A>((p) => default(A)));
+  }
+  public Parser<B> Apply<B>(Func<A, B> f) {
+    return Parser<B>.Make((input) => {
+      var r1 = Parse(input);
+      return r1 != null ? new ParseResult<B>(f(r1.Item), r1.Rest) : null;
+    });
+  }
+  public Parser<List<A>> Rep() {
+    return Parser<List<A>>.Make((input) => {
+      var rs = new List<A>();
+      ParseResult<A> r;
+      while((r = Parse(input)) != null) {
+        rs.Add(r.Item);
+        input = r.Rest;
+      }
+      return new ParseResult<List<A>>(rs, input);
+    });
+  }
+  public Parser<List<A>> Rep1() {
+    return this.Seq(this.Rep()).Apply((p) => {
+      p._2.Add(p._1);
+      return p._2;
+    });
+  }
+}
+public class BasicOperations {
+  public static Parser<string> Any = Parser<string>.Make((input) => {
+    return input.Length > 0 ?
+    new ParseResult<string>(input.Substring(0, 1), input.Substring(1)) : null;
+  });
+  public static Parser<string> Str(string param) {
+    return Parser<string>.Make((input) => {
+      return input.StartsWith(param) ?
+      new ParseResult<string>(param, input.Substring(param.Length)) : null;
+    });
+  }
+  public static Parser<A> Rule<A>(Func<Parser<A>> f) {
+    return Parser<A>.Make((input) => f().Parse(input));
+  }
+}
+public class User : BasicOperations {
+  public static Parser<object> S = Rule(() => 
+    (~A.Seq(!Str("b"))).Seq(Str("a").Rep1()).Seq(B).Seq(!Str("c"))
+  );
+  public static Parser<object> A = Rule(() =>
+    Str("a").Seq(A.Opt()).Seq(Str("b"))
+  );
+  public static Parser<object> B = Rule(() =>
+    Str("b").Seq(B.Opt()).Seq(Str("c"))
+  );
+  static void Main(string[] args) {
+    Console.WriteLine("{0}", S.Parse(args[0]));
+  }
+}