Benutzer:Dirk Huenniger/csmon

Aus Wikibooks
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.IO;

public delegate TResult Func<T,TResult>(
	T arg
);

public delegate TResult Func<T,T2,TResult>(
	T arg, T2 arg2
);

public delegate TResult Func<T,T2,T3,TResult>(
	T arg, T2 arg2, T3 arg3
);

abstract class MaybeConsumed<A>
{
	public A a;
	public abstract string getinfo() ;
}

class Consumed<A>:MaybeConsumed<A>
{
	public Consumed(A a) {
		this.a=a;
	}
	public override string getinfo() {
		return "Consumed";
	} 
}

class Empty<A>:MaybeConsumed<A>
{
	public Empty(A a) {
		this.a=a;
	}
	public override string getinfo() {
		return "Empty";
	}
}

abstract class Reply<TOK,ST,A> {
	public ParseError error;
	public abstract string getinfo();

}

class Ok<TOK,ST,A>:Reply<TOK,ST,A> {
	public A a;
	public State<TOK,ST> state;
	public Ok(A a, State<TOK,ST> state, ParseError error) {
		this.state=state;
		this.a=a;
		this.error=error;	
	}
	public override string getinfo() {
		return "Ok";
	}
}

class Error<TOK,ST,A>:Reply<TOK,ST,A> {
	public Error(ParseError error) {
		this.error=error;	
	}
	public override string getinfo() {
		return "Error";
	}
}

class ParseError{
 	public SourcePos pos;
	public List<ParserMessage> messages;
	public static ParseError newErrorUnknown(SourcePos pos) {
		return new ParseError(pos);
	}
	public static ParseError newErrorMessage(ParserMessage msg,SourcePos pos) {
		return new ParseError( pos,msg);
	}

	public static ParseError unknownError<TOK,ST>(State<TOK,ST> st) {
		return newErrorUnknown(st.pos);
	}

	public ParseError(SourcePos pos) {
		this.messages=new List<ParserMessage>();
		this.pos=pos;
	}
	public ParseError(SourcePos pos,ParserMessage msg) {
		this.messages=new List<ParserMessage>();
		this.messages.Add(msg);
		this.pos=pos;
	}
	public ParseError(SourcePos pos,List<ParserMessage> msgs) {
		this.messages=msgs;
		this.pos=pos;
	}
	public ParseError(SourcePos pos,ParseError pe) {
		this.messages=pe.messages;
		this.pos=pos;
	}


	public static ParseError addErrorMessage(ParserMessage msg, ParseError error) {
		List<ParserMessage> l=new List<ParserMessage> (error.messages.Count);
		error.messages.ForEach((item)=>{l.Add(item);});
		l.Add(msg);
		return new ParseError(error.pos,l);
	}
	public static ParseError sysUnExpectError(string msg,SourcePos pos) { 
		return newErrorMessage (new SysUnExpect (msg),pos);
	}
	public static ParseError setErrorMessage(ParserMessage msg,ParseError error) {
		List<ParserMessage> l=Functional.filter(error.messages, x=> {return !x.Eq(msg);});		
		l.Add(msg);		
		return new ParseError(error.pos,l);
	}
	public static ParseError setExpectErrors(ParseError error, List<string> messages) {
		if (messages.Count==0) {
			return setErrorMessage(new Expect(""),error);
		} else if (messages.Count==1) {
			return setErrorMessage(new Expect(messages[0]),error);			
		} else {
			List<string> l=new List<string> (messages.Count);
			messages.ForEach((item)=>{l.Add(item);});
			l.Reverse();
			return Functional.foldl<string,ParseError>(
				(msg,err)=> {return addErrorMessage (new Expect( msg), err);},
				setErrorMessage(
					new Expect(messages[0]),error
				),
				l
			);
		}
	}
	public static bool errorIsUnknown(ParseError error) {
		return (error.messages.Count==0);
	}
	public static Reply<TOK,ST,A> mergeErrorReply<TOK,ST,A>(ParseError err1,Reply<TOK,ST,A> reply) {
		if (reply is Ok<TOK,ST,A>){
			Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
			return new Ok<TOK,ST,A>(ok.a,ok.state,mergeError(err1,ok.error) );
		}
		else {
			Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
			return new Error<TOK,ST,A>(mergeError(err1,error.error) );	
		}
	}
	public static ParseError mergeError(ParseError err1,ParseError err2) {
		List<ParserMessage> l=new List<ParserMessage> (err1.messages);
		err1.messages.ForEach((item)=>{l.Add(item);});
		err2.messages.ForEach((item)=>{l.Add(item);});
		return new ParseError(err1.pos,l);
	}
}




/*
mergeErrorReply err1 reply
  = case reply of
      Ok x state err2 -> Ok x state (mergeError err1 err2)
      Error err2      -> Error (mergeError err1 err2)
*/

abstract class ParserMessage : IComparable  {
	public string msg;
	abstract public int num();
	public  int CompareTo(object a)
	{
		ParserMessage p = (ParserMessage)a;
		return Math.Sign(p.num()  -  this.num());
	}
	public bool Eq(object a) {
		return this.CompareTo(a)==0;
	}	
}



class SysUnExpect: ParserMessage {
	public SysUnExpect( string msg) {
		this.msg=msg;
	}
	public override int num(){
		return 0;
	}
}
class UnExpect: ParserMessage {
	public UnExpect( string msg) {
		this.msg=msg;
	}
	public override int num(){
		return 1;
	}
}
class Expect: ParserMessage {
	public Expect( string msg) {
		this.msg=msg;
	}
	public override int num(){
		return 2;
	}
}
class Message: ParserMessage {
	public override int num(){
		return 3;
	}
}

delegate MaybeConsumed<Reply<TOK,ST,A>> GenParser<TOK,ST,A> (State<TOK,ST> st); 

static class ParserMonad {
/*
	public static GenParser<TOK,ST,A> Where<TOK,ST,A>(
			this GenParser<TOK,ST,A> parser,
			Func<A,bool> pred) {
		return x => { throw new System.Exception(); };
	}
	public static GenParser<TOK,ST,B> Select<TOK,ST,A,B>(
			this GenParser<TOK,ST,A> parser,
			Func<A,B> func) {
		return x => {
			MaybeConsumed<Reply<TOK,ST,A>> result=parser(x);
			if (result is Consumed <Reply<TOK,ST,A>>) {			
				Reply<TOK,ST,A> reply = ((Consumed<Reply<TOK,ST,A>>) result).a;
 				if (reply is Ok<TOK,ST,A>) {
					Ok<TOK,ST,A> r=(Ok<TOK,ST,A>) reply;
					return new Consumed<Reply<TOK,ST,B>> (new Ok<TOK,ST,B>(func(r.a),r.state, ParseError.newErrorUnknown( r.state.pos) ));				
				}
				else {
					Error<TOK,ST,A> e=(Error<TOK,ST,A>) reply;
					return new Consumed<Reply<TOK,ST,B>> ( new Error<TOK,ST,B>(e.error));
				}
			}
			else {
				throw new System.Exception();
			}
		};
	}
*/
	public static GenParser<TOK,ST,C> SelectMany<TOK,ST,A,B,C>(
			this GenParser<TOK,ST,A> parser,
			Func<A,GenParser<TOK,ST,B> > func,
			Func<A,B,C> trans
			) {
		return x => {
			MaybeConsumed<Reply<TOK,ST,A>> result=parser(x);
			if (result is Consumed <Reply<TOK,ST,A>>) {			
				Reply<TOK,ST,A> reply = ((Consumed<Reply<TOK,ST,A>>) result).a;
 				if (reply is Ok<TOK,ST,A>) {
					Ok<TOK,ST,A> r=(Ok<TOK,ST,A>) reply;
					MaybeConsumed<Reply<TOK,ST,B>> result2 =func(r.a)(r.state);  // run parser from a->M b case M a Consumed
					if (result2 is Consumed <Reply<TOK,ST,B>>) {			//Consumed from (run parser from a->M b case M a Consumed)
						Reply<TOK,ST,B> reply2 = ((Consumed<Reply<TOK,ST,B>>) result2).a;
 						if (reply2 is Ok<TOK,ST,B>) {
							Ok<TOK,ST,B> r2=(Ok<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> (new Ok<TOK,ST,C>(trans(r.a,r2.a),r2.state,ParseError.newErrorUnknown( r2.state.pos) ));				
						}
						else {
							Error<TOK,ST,B> e=(Error<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(e.error));
						}
					} 
					else { //Empty from (run parser from a->M b case M a Consumed)
						Reply<TOK,ST,B> reply2 = ((Empty<Reply<TOK,ST,B>>) result2).a;
						reply2 =ParseError.mergeErrorReply(r.error,reply2);
 						if (reply2 is Ok<TOK,ST,B>) {
							Ok<TOK,ST,B> r2=(Ok<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> (new Ok<TOK,ST,C>(trans(r.a,r2.a),r2.state,reply2.error ));				
						}
						else {
							return new Consumed<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(reply2.error));
						}
					}		
				}
				else {
					Error<TOK,ST,A> e=(Error<TOK,ST,A>) reply;
					return new Consumed<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(e.error));
				}
			}
			else {
				Reply<TOK,ST,A> reply = ((Empty<Reply<TOK,ST,A>>) result).a;
 				if (reply is Ok<TOK,ST,A>) {
					Ok<TOK,ST,A> r=(Ok<TOK,ST,A>) reply;
					MaybeConsumed<Reply<TOK,ST,B>> result2 =func(r.a)(r.state);  // run parser from a->M b case M a Empty
					if (result2 is Consumed <Reply<TOK,ST,B>>) {			//Consumed from (run parser from a->M b case M a  Empty)
						Reply<TOK,ST,B> reply2 = ((Consumed<Reply<TOK,ST,B>>) result2).a;
 						if (reply2 is Ok<TOK,ST,B>) {
							Ok<TOK,ST,B> r2=(Ok<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> (new Ok<TOK,ST,C>(trans(r.a,r2.a),r2.state,ParseError.newErrorUnknown( r2.state.pos) ));				
						}
						else {
							Error<TOK,ST,B> e=(Error<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(e.error));
						}
					} 
					else { //Empty from (run parser from a->M b case M a  Empty)
						Reply<TOK,ST,B> reply2 = ((Empty<Reply<TOK,ST,B>>) result2).a;
						reply2 =ParseError.mergeErrorReply(r.error,reply2);
 						if (reply2 is Ok<TOK,ST,B>) {
							Ok<TOK,ST,B> r2=(Ok<TOK,ST,B>) reply2;
							return new Consumed<Reply<TOK,ST,C>> (new Ok<TOK,ST,C>(trans(r.a,r2.a),r2.state,reply2.error ));				
						}
						else {
							return new Consumed<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(reply2.error));
						}
					}		
				}
				else {
					Error<TOK,ST,A> e=(Error<TOK,ST,A>) reply;
					return new Empty<Reply<TOK,ST,C>> ( new Error<TOK,ST,C>(e.error));
				}
			}

		};
	}
	public static GenParser<TOK,ST,A> parsecReturn<TOK,ST,A>(A a) {
		return state => {
			return new Empty<Reply<TOK,ST,A>>(new Ok<TOK,ST,A>(a,state,ParseError.unknownError(state)));
		};
	}

}
/*
parsecReturn :: a -> GenParser tok st a
parsecReturn x
  = Parser (\state -> Empty (Ok x state (unknownError state)))   
*/

class State<TOK,ST> {
	public List<TOK> input;
	public SourcePos pos;
	public ST userState;
	public State(List<TOK> input, SourcePos pos, ST userState) {
		this.input=input;
		this.pos=pos;
		this.userState=userState;
	}
	public State(State<TOK,ST> st) {
		this.input=st.input;
		this.pos=st.pos;
		this.userState=st.userState;
	}

}

class SourcePos {
	public int line;
	public int column;
	public string name;
	public SourcePos(int line,int column,string name) {
		this.line=line;
		this.column=column;
		this.name=name;
	}
	public SourcePos(string name) {
		this.line=0;
		this.column=0;
		this.name=name;
	}
}

class NullType{
	public NullType() {}
}

class Maybe<A> {
	
}

class Just<A>:Maybe<A> {
	public A a;
	public Just(A a) {this.a=a;}
}

class Nothing<A>:Maybe<A>{
	public Nothing() {}
}
//delegate MaybeConsumed<Reply<TOK,ST,A>> GenParser<TOK,ST,A> (State<TOK,ST> st); 
delegate string shower<A> (A a);
delegate SourcePos poser<TOK,ST> (SourcePos sp,TOK c,List<TOK> cs);
delegate ST stater<TOK,ST> (SourcePos sp,TOK c,List<TOK> cs, ST st);
delegate Maybe<A> tester<TOK,A> (TOK c);


//type CharParser st a    = GenParser Char st a

class Functional{
	public static List<T> filter<T>(List<T> l, Func<T,bool> f) {
		List<T> a=new List<T>();	
		l.ForEach(
			(item)=>
				{
					if (f(item)) 
						{ 
							a.Add(item);
						}
				}
			);
		return a;
	}
	public static List<T> reverse<T>(List<T> l) {
		List<T> a=new List<T>();	
		l.ForEach(
			(item)=>
				{
					a.Add(item);
				}
			);
		a.Reverse();
		return a;
	}
	public static B foldl<A,B>(Func<A,B,B> f,B acu, List<A> l) {
		if (l.Count==0) {
			return acu;
		}
		else {
			List<A> ls=new List<A> (l.Count);
			l.ForEach((item)=>{ls.Add(item);});
			ls.RemoveAt(0); 
			return foldl(f,f(l[0],acu),ls);
		}
	}
}

class Prim {

static public GenParser<TOK,ST,A> mplus<TOK,ST,A>(GenParser<TOK,ST,A> p1, GenParser<TOK,ST,A> p2) {
	return state => {
		List<TOK> ll=(List<TOK>) state.input;	
		//Console.WriteLine(ll.Count());
		MaybeConsumed<Reply<TOK,ST,A>> mc1=p1(state);
		//Console.WriteLine(mc1);
		if ((mc1 is Empty<Reply<TOK,ST,A>>)&&(mc1.a) is Error<TOK,ST,A>) {
			Error<TOK,ST,A> err=(Error<TOK,ST,A>) mc1.a; 
			MaybeConsumed<Reply<TOK,ST,A>> mc2=p2(state);
			//Console.WriteLine(mc2);

			if (mc2 is Empty<Reply<TOK,ST,A>>) { 
				Reply<TOK,ST,A> rep=mc2.a;
				return new Empty<Reply<TOK,ST,A>>(ParseError.mergeErrorReply(err.error,rep));
			}
			else {
				return mc2;
			}
		}
		else {
			return mc1;
		}
	};
}

/*
parsecPlus :: GenParser tok st a -> GenParser tok st a -> GenParser tok st a
parsecPlus (Parser p1) (Parser p2)
    = Parser (\state ->
        case (p1 state) of        
          Empty (Error err) -> case (p2 state) of
                                 Empty reply -> Empty (mergeErrorReply err reply)
                                 consumed    -> consumed
          other             -> other
      )
*/



	static public GenParser<TOK,ST,A> try_<TOK,ST,A>(GenParser<TOK,ST,A> p) {
		return  state=> {
			MaybeConsumed<Reply<TOK,ST,A>> res= p (state);
			if (res is Consumed<Reply<TOK,ST,A>>) {
				Reply<TOK,ST,A> reply=((Consumed<Reply<TOK,ST,A>>) res).a;
				if (reply is Error<TOK,ST,A>) {
					Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
					return new Empty<Reply<TOK,ST,A>>(new Error<TOK,ST,A>( new ParseError(state.pos,error.error) ));
				}
				else {
					Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
					return new Consumed<Reply<TOK,ST,A>>(reply);
				}
			}
			else {
				return res;
			} 		
		};
	}
	static public GenParser<TOK,ST,State<TOK,ST>> updateParserState<TOK,ST>(Func<State<TOK,ST>,State<TOK,ST>> f) {
		return state => {
			State<TOK,ST> newstate=f( state);
			return new Empty<Reply<TOK,ST,State<TOK,ST>>>(new Ok<TOK,ST,State<TOK,ST>>(state, newstate, ParseError.unknownError(newstate)) );
		};
	}
	static public GenParser<TOK,ST,SourcePos> getPosition<TOK,ST>() {
		return from state in getParserState<TOK,ST>() from y in ParserMonad.parsecReturn<TOK,ST,SourcePos>(state.pos) select y;
	} 
	static public GenParser<TOK,ST,List<TOK>> getInput<TOK,ST>() {
		return from state in getParserState<TOK,ST>() from y in ParserMonad.parsecReturn<TOK,ST,List<TOK>>(state.input) select y;
	}
	static public GenParser<TOK,ST,NullType> setPosition<TOK,ST>(SourcePos pos) {
		return from x in updateParserState<TOK,ST>(state => {State<TOK,ST> s= new State<TOK,ST>(state);s.pos=pos;return s;}) from y in ParserMonad.parsecReturn<TOK,ST,NullType>(new NullType()) select y;
	} 
	static public GenParser<TOK,ST,NullType> setInput<TOK,ST>(List<TOK> input) {
		return from x in updateParserState<TOK,ST>(state => {State<TOK,ST> s= new State<TOK,ST>(state);s.input=input;return s;}) from y in ParserMonad.parsecReturn<TOK,ST,NullType>(new NullType()) select y;
	} 


	static public GenParser<TOK,ST,State<TOK,ST>> getParserState<TOK,ST>() {
		return updateParserState<TOK,ST>(x=>x);
	}
	static public GenParser<TOK,ST,State<TOK,ST>> setParserState<TOK,ST>(State<TOK,ST> st) {
		return updateParserState<TOK,ST>(x=>st);
	}

	static public GenParser<TOK,ST,ST> getState<TOK,ST>() {
		return (from state in getParserState<TOK,ST>() from y in ParserMonad.parsecReturn<TOK,ST,ST>(state.userState) select y);
	}
	static public GenParser<TOK,ST,NullType> setState<TOK,ST>(ST st) {
		return (from x in updateParserState<TOK,ST>(state=>{State<TOK,ST> s=new State<TOK,ST>(state);s.userState=st;return s;} ) from y in ParserMonad.parsecReturn<TOK,ST,NullType>(new NullType()) select y);
	}
	static public GenParser<TOK,ST,NullType> updateState<TOK,ST>(Func<ST,ST> f) {
		return (from x in updateParserState<TOK,ST>(state=>{State<TOK,ST> s=new State<TOK,ST>(state);s.userState=f(s.userState);return s;} ) from y in ParserMonad.parsecReturn<TOK,ST,NullType>(new NullType()) select y);
	}

/*

setState :: st -> GenParser tok st ()
setState st     = do{ updateParserState (\(State input pos _) -> State input pos st)
                    ; return ()
                    }

updateState :: (st -> st) -> GenParser tok st ()
updateState f   = do{ updateParserState (\(State input pos user) -> State input pos (f user))
                    ; return ()
                    }

*/

	static public GenParser<TOK,ST,A> unexpected<TOK,ST,A>(String msg) {
		return  state=> {
			return new Empty<Reply<TOK,ST,A>>( new Error<TOK,ST,A>( new ParseError(state.pos, new UnExpect (msg))));
		};
	}
	static public GenParser<TOK,ST,A> pzero<TOK,ST,A>(String msg) {
		return  state=> {
			return new Empty<Reply<TOK,ST,A>>( new Error<TOK,ST,A>( ParseError.unknownError<TOK,ST> (state)));
		};

	}



 	static public GenParser<TOK,ST,A> tokenPrim<TOK,ST,A>( shower<TOK> show,
	 		poser<TOK,ST> nextpos,
			tester<TOK,A> test) {
			return tokenPrimEx<TOK,ST,A>(show,nextpos,new Nothing<stater<TOK,ST>>(),test);
	}
	static public GenParser<char,ST,char> satisfy<ST> (Func<char,bool> f) { 
		return tokenPrim<char,ST,char> ( (char c) => {return Char.ToString(c);} , 
                                (SourcePos pos ,char c ,List<char> cs) => {return pos; }, 
                                (char c) =>{
									if (f(c)) 
										{ return new Just<char>(c);} 
									else {return new Nothing<char>();}
									});
	}

	static public GenParser<TOK,ST,A> tokenPrimEx<TOK,ST,A>( shower<TOK> show,
	 		poser<TOK,ST> nextpos,
			Maybe<stater<TOK,ST>> mbNextState, 
			tester<TOK,A> test) 
	{
		if (mbNextState is Nothing<stater<TOK,ST>>) 
		{	
			return  x=> 
			{
				if (x.input.Count > 0) {
					List<TOK> cs=new List<TOK> (x.input.Count);
					x.input.ForEach((item)=>
				    {
        				cs.Add(item);
    				});
					cs.RemoveAt(0); 
					Maybe<A> ma=test(x.input[0]); 
					if (ma is Just<A>) {
						A a= ((Just<A>) ma).a;
						SourcePos sp=nextpos(x.pos, x.input[0], cs);
						State<TOK,ST> st=new State<TOK,ST> (cs,sp,x.userState); 
						return new Consumed<Reply<TOK,ST,A>>(new Ok<TOK,ST,A>(a,st,ParseError.newErrorUnknown(sp)));
					}
					else {
						return new Empty<Reply<TOK,ST,A>> (new Error<TOK,ST,A> (ParseError.sysUnExpectError(show (x.input[0]), x.pos)));
					}
				}
				else {
					return new Empty<Reply<TOK,ST,A>> (new Error<TOK,ST,A> (ParseError.sysUnExpectError ("", x.pos)));
				}
			};
		}		
		else{
			return x=> {return new Empty<Reply<TOK,ST,A>> (new Error<TOK,ST,A> (ParseError.sysUnExpectError ("", new SourcePos("bla"))));};
		}
	}

	public static GenParser<TOK,ST,A> labels<TOK,ST,A>(
		GenParser<TOK,ST,A> parser, List<string> msgs) {
		return x=> {
			MaybeConsumed<Reply<TOK,ST,A>> result=parser(x);
			if (result is Empty<Reply<TOK,ST,A>>) {
				Reply<TOK,ST,A> reply=((Empty<Reply<TOK,ST,A>>) result).a;
				if (reply is Error<TOK,ST,A>) {
					//return result;
					Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
					return new Empty<Reply<TOK,ST,A>>(new Error<TOK,ST,A>( ParseError.setExpectErrors(error.error,msgs) ));
				}
				else {
					Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
					if (ParseError.errorIsUnknown (ok.error)) {
						return new Empty<Reply<TOK,ST,A>>(reply);
					}
					else {
						return new Empty<Reply<TOK,ST,A>>( new Ok<TOK,ST,A>(ok.a,ok.state,ParseError.setExpectErrors(ok.error, msgs) ) );
					}
				}
			}
			else {
				return result;
			}
		};
	}
	public static GenParser<TOK,ST,A> label<TOK,ST,A>(GenParser<TOK,ST,A> parser, string msg) {
		List<string> l=new List<string>();
		l.Add(msg);
		return labels(parser,l);
	}
/*
	public static GenParser<TOK,ST,List<A>> manyAccum<TOK,ST,A>(Func<A,List<A>,List<A>> accum,GenParser<TOK,ST,A> parser) {
		Func<List<A> , State<TOK,ST> , MaybeConsumed<Reply<TOK,ST,A>> , Reply<TOK,ST,List<A>>> walk= (xs,state2,r)=> {
				if (r is Empty<Reply<TOK,ST,A>>) {
					Reply<TOK,ST,A> reply=((Empty<Reply<TOK,ST,A>>) r).a;
					if (reply is Error<TOK,ST,A>) {
						Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
						return new Ok<TOK,ST,List<A>>(xs,state2,error.error);
					}
					else {
						//Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
						throw new System.Exception("Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string.");
					}
				}
				else {
					Reply<TOK,ST,A> reply=((Consumed<Reply<TOK,ST,A>>) r).a;
					if (reply is Error<TOK,ST,A>) {
						Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
						return new Error<TOK,ST,List<A>>(error.error);
					}
					else {
						Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
						List<A> ys=accum(ok.a,xs);
					
						return walk(ys,ok.state,parser(ok.state));
					}
				}
			}; 				
		return state=> {
			MaybeConsumed<Reply<TOK,ST,A>> result=parser(state);
			if (result is Empty<Reply<TOK,ST,A>>) {
				Reply<TOK,ST,A> reply=((Empty<Reply<TOK,ST,A>>) result).a;
				if (reply is Error<TOK,ST,A>) {
					Error<TOK,ST,A> error=(Error<TOK,ST,A>) reply;
					return new Empty<Reply<TOK,ST,List<A>>>(new Ok<TOK,ST,List<A>>(new List<A>(),state,error.error  ));
				}
				else {
					//Ok<TOK,ST,A> ok=(Ok<TOK,ST,A>) reply;
					throw new System.Exception("Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string.");
				}
			}
			else {
				Consumed<Reply<TOK,ST,List<A>>> r= new Consumed<Reply<TOK,ST,List<A>>>(walk(new List<A>(),state,result));
				return r;			

			}
		};
	}
	public static GenParser<TOK,ST,NullType> skipMany<TOK,ST,A>(GenParser<TOK,ST,A> p) {
		return (from z in Prim.manyAccum((x,xs)=>new List<A>(),p) from y in ParserMonad.parsecReturn<TOK,ST,NullType>(new NullType()) select y);
	}
	public static GenParser<TOK,ST,List<A>> many<TOK,ST,A>(GenParser<TOK,ST,A> p) {
		return (
			from z in Prim.manyAccum((x,xs)=>{
				List<A> l=new List<A>(); l.Add(x); xs.ForEach(i=> {
					l.Add(i);
				});
				return l;
			},p) 
			from y in ParserMonad.parsecReturn<TOK,ST,List<A>>(Functional.reverse<A>(z)) select y);
	}

*/

}
/*
skipMany :: GenParser tok st a -> GenParser tok st ()
skipMany p
  = do{ manyAccum (\x xs -> []) p
      ; return ()
      }
*/


class CharParser {


	static public GenParser<char,NullType,char> oneOf(List<Char> l) {
		return Prim.satisfy<NullType>(x => {return l.Contains(x) ;});
	}
	static public GenParser<char,NullType,char> noneOf(List<Char> l) {
		return Prim.satisfy<NullType>(x => {return !l.Contains(x) ;});
	}
	static public GenParser<char,NullType,char> isWhiteSpace() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsWhiteSpace (x);}),"white space");
	}
	static public GenParser<char,NullType,char> newline() {
		return Prim.label(character('\n'),"new-line");
	}
	static public GenParser<char,NullType,char> tab() {
		return Prim.label(character('\t'),"tab");
	}
	static public GenParser<char,NullType,char> isUpper() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsUpper (x);}),"uppercase letter");
	}
	static public  GenParser<char,NullType,char> isLower() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsLower (x);}),"lowercase letter");
	}
	static public  GenParser<char,NullType,char> isLetterOrDigit() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsLetterOrDigit (x);}),"letter or digit");
	}
	static public  GenParser<char,NullType,char> isLetter() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsLetter (x);}),"letter");
	}
	static public  GenParser<char,NullType,char> isDigit() {
		return Prim.label(Prim.satisfy<NullType>(x => {return Char.IsDigit (x);}),"digit");
	}
	static public  GenParser<char,NullType,char> isOctDigit() {
		return Prim.label(Prim.satisfy<NullType>(x => {return (Char.IsDigit (x)&& (x!='8')&&(x!='9'));}),"octal digit");
	}
	static public  GenParser<char,NullType,char> isHexDigit() {
		return Prim.label(Prim.satisfy<NullType>(x => {
			return (
    			Char.IsDigit (x)||
				(Char.ToUpper(x)=='A')||
				(Char.ToUpper(x)=='B')||
				(Char.ToUpper(x)=='C')||
				(Char.ToUpper(x)=='D')||
				(Char.ToUpper(x)=='E'));}),"hexadecimal  digit");
	}
	static public  GenParser<char,NullType,char> character(char c) {
		return Prim.label(Prim.satisfy<NullType>(x => {return (c==x);}),Char.ToString(c));
	}
	static public  GenParser<char,NullType,char> anychar() {
		return Prim.satisfy<NullType>(x => {return true;});
	}

}
  

public class HelloWorld
{
	static public void Main ()
	{
		GenParser<char,NullType,char>  pxa = Prim.satisfy<NullType>(x => x=='a') ;
		GenParser<char,NullType,char>  pxb = Prim.satisfy<NullType>(x => x=='b') ;
		GenParser<char,NullType,char>  pxd = Prim.satisfy<NullType>(x => x=='d') ;
		GenParser<char,NullType,char>  pxc = Prim.satisfy<NullType>(x => {;return x=='c';}) ;

		GenParser<char,NullType,char>  pxx = 
				from y in pxa 
				from y3 in Prim.mplus( Prim.try_(pxd),pxb) 			
				from y4 in pxc 				
				select y3;




					
		List<char> l= new List<char>();
		l.Add('a');
		l.Add('b');
		l.Add('c');

		List<char> l4= new List<char>();
		l4.Add('a');
		l4.Add('d');
		l4.Add('c');


		List<char> l3= new List<char>();
		l3.Add('a');
		l3.Add('d');
		l3.Add('d');
		l3.Add('c');

		//Functional.filter(l3,x => x!="a").ForEach((item)=>{Console.WriteLine(item); });		
		SourcePos sp=new SourcePos("testdata");
		State<char,NullType> st=new State<char,NullType>(l4,sp,new NullType());
		MaybeConsumed<Reply<char,NullType,char>> z=pxx(st);
		Console.WriteLine (z.a is Error<char,NullType,char>);
    if (z.a is Ok<char,NullType,char>) {
			Ok<char,NullType,char> o=(Ok<char,NullType,char>) z.a;
			char l2=o.a;
			Console.WriteLine (l2);
		}
		Console.WriteLine (z );
		Console.WriteLine (z.a.getinfo() );

		Console.WriteLine ("Hello Mono World");
	} 
}