public static ParserErrorException ParserError(IImmutableEnumerator <GraphemeCluster> context, IImmutableEnumerator <GraphemeCluster> rest, S state, List <Rule> possibleNext, GraphemeCluster gc) { var strContext = context .ToIEnumerable() .TakeUntil(c => c.Equals(rest)) .Select(c => c.str) .JoinWith(""); var strRest = rest .TakeUntil(c => c.str.StartsWith("\n")) .Select(c => c.str) .JoinWith(""); var expected = ", ".Join(possibleNext.Select(p => p.description)); var actual = (gc.endOfFile ? "" : "grapheme cluster ") + gc.Description(); var cat = gc.codePoints .First() .Match(Some: x => x.UnicodeCategory(0).ToString(), None: "None (empty string)"); return(new ParserErrorException( $"Unexpected {actual} (Unicode category {cat}) while the lexer was in state {state}: expected one of {expected}{Environment.NewLine}{strContext} <--HERE {strRest}" )); }
public IImmutableEnumerator <T> F( IImmutableEnumerator <IImmutableEnumerator <T> > e ) => e.MoveNext().Match( Some: element => element.First.Concat(element.Rest.Flatten()), None: () => Empty <T>());
public IImmutableEnumerator <Lexeme> F( IImmutableEnumerator <Lexeme> lx ) => lx.FirstAndRest().Match( Some: hdtl => // skip the initial empty whitespace "".Equals(hdtl.Item1.lexeme) ? hdtl.Item2 : hdtl.Item1.ImSingleton().Concat(hdtl.Item2), None: Empty <Lexeme>());
public static IImmutableEnumerator <IImmutableEnumerator <Lexeme> > Lex2(IImmutableEnumerator <GraphemeCluster> ie) { var lexeme = ""; var state = S.Space; // In a REPL we could reset the context at the end of each statement. // We could also reset the context to the containing line or function when processing files. var context = ie; return(ie.SelectAggregate((lexeme, state, context), Flub.Eq)); }
public IImmutableEnumerator <Lexeme> F( IImmutableEnumerator <Lexeme> lx ) => lx.FirstAndRest().Match <Tuple <Lexeme, IImmutableEnumerator <Lexeme> >, IImmutableEnumerator <Lexeme> >( Some: hdtl => { var rest = hdtl.Item2.Lazy(DiscardWhitespace.Eq); return(hdtl.Item1.state.Equals(S.Space) ? rest : hdtl.Item1.ImSingleton().Concat(rest)); }, None: Empty <Lexeme>());
public static IEnumerable <T> ToIEnumerable <T>(this IImmutableEnumerator <T> e) { var next = e.MoveNext(); while (next.IsSome) { var elem = next.ElseThrow(new Exception("impossible")); yield return(elem.First); next = elem.Rest.MoveNext(); } }
public static Option <ValueTuple <IImmutableEnumerator <Lexeme>, ParserResult> > Parse3( Func <IImmutableEnumerator <Lexeme>, Grammar2, //Option<IImmutableEnumerator<Lexeme>> Option <ValueTuple <IImmutableEnumerator <Lexeme>, ParserResult> > > Parse3, IImmutableEnumerator <Lexeme> tokens, Grammar2 grammar ) //=> Log($"Parser {grammar.ToString()} against {tokens.FirstAndRest().IfSome((first, rest) => first)}", () => grammar.Match(
public static IImmutableEnumerator <T> TakeUntil <T>(this IImmutableEnumerator <T> e, IEqF <IImmutableEnumerator <T>, bool> predicate) => new PureImmutableEnumerator <
public static Option <Tuple <T, IImmutableEnumerator <T> > > FirstAndRest <T>(this IImmutableEnumerator <T> e) => e.MoveNext() .Match( None: () => Option.None <Tuple <T, IImmutableEnumerator <T> > >(), Some: elt => new Tuple <T, IImmutableEnumerator <T> >( elt.First, elt.Rest ).Some() );
public PureImmutableEnumeratorElement(U element, IImmutableEnumerator <U> rest) { this.element = element; this.rest = rest; this.hashCode = Equality.HashCode("PureImmutableEnumeratorElement", element, rest); }
public bool Equals(IImmutableEnumerator <U> other) => Equality.Equatable <IImmutableEnumerator <U> >(this, other);