using System; using System.Collections.Generic; public class Pair { 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 { 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 { public Func> Target { get; set; } public Parser(Func> target) { Target = target; } public ParseResult Parse(string input) { return Target(input); } public static Parser Make(Func> target) { return new Parser(target); } public static implicit operator Parser(Parser p) { return Parser.Make((input) => { var r = p.Parse(input); return r != null ? new ParseResult(r.Item, r.Rest) : null; }); } public Parser Or(Parser p2) { return Make((input) => { var r = Parse(input); return r != null ? r : p2.Parse(input); }); } public Parser> Seq(Parser p2) { return Parser>.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>( new Pair(r1.Item, r2.Item), r2.Rest ); }); } public static Parser operator!(Parser p) { return p.Not(); } public static Parser operator~(Parser p) { return p.And(); } public Parser Not() { return Parser.Make((input) => { var r = Parse(input); return r == null ? new ParseResult(null, input) : null; }); } public Parser And() { return this.Not().Not(); } public Parser Opt() { return Or(BasicOperations.Str("").Apply((p) => default(A))); } public Parser Apply(Func f) { return Parser.Make((input) => { var r1 = Parse(input); return r1 != null ? new ParseResult(f(r1.Item), r1.Rest) : null; }); } public Parser> Rep() { return Parser>.Make((input) => { var rs = new List(); ParseResult r; while((r = Parse(input)) != null) { rs.Add(r.Item); input = r.Rest; } return new ParseResult>(rs, input); }); } public Parser> Rep1() { return this.Seq(this.Rep()).Apply((p) => { p._2.Add(p._1); return p._2; }); } } public class BasicOperations { public static Parser Any = Parser.Make((input) => { return input.Length > 0 ? new ParseResult(input.Substring(0, 1), input.Substring(1)) : null; }); public static Parser Str(string param) { return Parser.Make((input) => { return input.StartsWith(param) ? new ParseResult(param, input.Substring(param.Length)) : null; }); } public static Parser Rule(Func> f) { return Parser.Make((input) => f().Parse(input)); } } public class User : BasicOperations { public static Parser S = Rule(() => (~A.Seq(!Str("b"))).Seq(Str("a").Rep1()).Seq(B).Seq(!Str("c")) ); public static Parser A = Rule(() => Str("a").Seq(A.Opt()).Seq(Str("b")) ); public static Parser B = Rule(() => Str("b").Seq(B.Opt()).Seq(Str("c")) ); static void Main(string[] args) { Console.WriteLine("{0}", S.Parse(args[0])); } }