Beispiel #1
0
 /// <summary>
 /// Combine two rows at the same precedence level
 /// </summary>
 /// <param name="otherRow">A collection of parsers for operators</param>
 /// <returns>The current collection of parsers combined with <paramref name="otherRow"/></returns>
 public OperatorTableRow <TToken, T> And(OperatorTableRow <TToken, T> otherRow)
 => new OperatorTableRow <TToken, T>(
     InfixNOps.Concat(otherRow.InfixNOps),
     InfixLOps.Concat(otherRow.InfixLOps),
     InfixROps.Concat(otherRow.InfixROps),
     PrefixOps.Concat(otherRow.PrefixOps),
     PostfixOps.Concat(otherRow.PostfixOps)
     );
Beispiel #2
0
        private static Parser <TToken, T> Build <TToken, T>(Parser <TToken, T> term, OperatorTableRow <TToken, T> row)
        {
            var returnIdentity = Parser <TToken> .Return <Func <T, T> >(x => x);

            var returnIdentityArray = new[] { returnIdentity };

            var pTerm = Map(
                (pre, tm, post) => post(pre(tm)),
                OneOf(row.PrefixOps.Concat(returnIdentityArray)),
                term,
                OneOf(row.PostfixOps.Concat(returnIdentityArray))
                );

            var infixN = Op(pTerm, row.InfixNOps).Select <Func <T, T> >(p => z => p.ApplyL(z));
            var infixL = Op(pTerm, row.InfixLOps)
                         .AtLeastOncePooled()
                         .Select <Func <T, T> >(fxs =>
                                                z =>
            {
                var result = fxs.Aggregate(
                    z,
                    (exp, fx) => fx.ApplyL(exp)
                    );
                fxs.Clear();
                return(result);
            }
                                                );
            var infixR = Op(pTerm, row.InfixROps)
                         .AtLeastOncePooled()
                         .Select <Func <T, T> >(fxs =>
            {
                // reassociate the parsed operators:
                // move the right-hand term of each operator to the
                // left-hand side of the next operator on the right,
                // leaving a hole at the left
                var result = fxs.AggregateR(
                    new Partial <T>((y, _) => y, default(T)),
                    (fx, agg) => new Partial <T>(fx.Func, agg.ApplyL(fx.Arg))
                    );
                fxs.Clear();
                return(z => result.ApplyL(z));
            }
                                                );

            var op = OneOf(
                infixN,
                infixL,
                infixR,
                returnIdentity
                );

            return(Map(
                       (x, f) => f(x),
                       pTerm,
                       op
                       ));
        }
Beispiel #3
0
 public Builder(Parser <TToken, T> term, OperatorTableRow <TToken, T> row)
 {
     _pTerm = Map(
         (pre, tm, post) => post(pre(tm)),
         OneOf(row.PrefixOps.Concat(_returnIdentity)),
         term,
         OneOf(row.PostfixOps.Concat(_returnIdentity))
         );
     _infixNOp   = OneOf(row.InfixNOps);
     _infixLOp   = OneOf(row.InfixLOps);
     _infixROp   = OneOf(row.InfixROps);
     _infixRTail = _pTerm.Then(t => InfixR(t).Or(Parser <TToken> .Return(t)));
 }