All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hamnaberg.json.internal.org.javafp.parsecj.Parser Maven / Gradle / Ivy

There is a newer version: 6.2.0
Show newest version
package org.javafp.parsecj;

import org.javafp.data.*;

import java.util.Optional;
import java.util.function.*;

/**
 * A parser is essentially a function taking the input stream and returning a ConsumedT.
 * The Parser type along with the retn and bind functions constitute a monad.
 * @param  Input stream symbol type.
 * @param  Parse result type
 */
@FunctionalInterface
public interface Parser {

    public static  Parser parser(Function, ConsumedT> parser) {
        return parser::apply;
    }

    static  Ref ref() {
        return new Ref();
    }

    static  Ref ref(Parser parser) {
        return new Ref(parser);
    }

    /**
     * A lazily initialised reference to a Parser.
     */
    public static class Ref implements Supplier>, Parser {

        private Parser parser;

        private Ref(Parser parser) {
            this.parser = parser;
        }

        private Ref() {
            this.parser = null;
        }

        public Parser set(Parser parser) {
            this.parser = parser;
            return this;
        }

        @Override
        public synchronized Parser get() {
            if (parser == null) {
                throw new RuntimeException("Null Parser Reference");
            }
            return parser;
        }

        @Override
        public ConsumedT apply(State input) {
            return get().apply(input);
        }
    }

    /**
     * Parse the input state
     * @return a ConsumedT result
     */
    ConsumedT apply(State state);

    /**
     * Parse the input state, extract the result and apply one of the supplied functions.
     * @return a parse result
     */
    default Reply parse(State state) {
        return
            apply(state)
                .getReply()
                .match(
                    // Strip off the message if the parse was successful.
                    ok -> Reply.ok(ok.result, ok.rest, Message.of()),
                    error -> error
                );
    }

    // Helper functions to allow combinators to be chained in a fluent style.

    /**
     * @see Combinators#bind
     */
    default  Parser bind(Function> f) {
        return Combinators.bind(this, f);
    }

    /**
     * @see Combinators#then
     */
    default  Parser then(Parser p) {
        return Combinators.then(this, p);
    }

    /**
     * @see Combinators#or
     */
    default Parser or(Parser q) {
        return Combinators.or(this, q);
    }

    /**
     * @see Combinators#label
     */
    default Parser label(String name) {
        return Combinators.label(this, name);
    }

    /**
     * @see Combinators#attempt
     */
    default Parser attempt() {
        return Combinators.attempt(this);
    }

    /**
     * @see Combinators#option
     */
    default Parser option(A x) {
        return Combinators.option(this, x);
    }

    /**
     * @see Combinators#optionalOpt
     */
    default Parser> optionalOpt() {
        return Combinators.optionalOpt(this);
    }

    /**
     * @see Combinators#optional
     */
    default Parser optional() {
        return Combinators.optional(this);
    }

    /**
     * @see Combinators#between
     */
    default  Parser between(Parser open, Parser close) {
        return Combinators.between(open, close, this);
    }

    /**
     * @see Combinators#many
     */
    default Parser> many() {
        return Combinators.many(this);
    }

    /**
     * @see Combinators#many1
     */
    default Parser> many1() {
        return Combinators.many1(this);
    }

    /**
     * @see Combinators#skipMany
     */
    default Parser skipMany() {
        return Combinators.skipMany(this);
    }

    /**
     * @see Combinators#skipMany1
     */
    default Parser skipMany1() {
        return Combinators.skipMany1(this);
    }

    /**
     * @see Combinators#sepBy
     */
    default  Parser> sepBy(Parser sep) {
        return Combinators.sepBy(this, sep);
    }

    /**
     * @see Combinators#sepBy1
     */
    default  Parser> sepBy1(Parser sep) {
        return Combinators.sepBy1(this, sep);
    }

    /**
     * @see Combinators#sepEndBy
     */
    default  Parser> sepEndBy(Parser sep) {
        return Combinators.sepEndBy(this, sep);
    }

    /**
     * @see Combinators#sepEndBy1
     */
    default  Parser> sepEndBy1(Parser sep) {
        return Combinators.sepEndBy1(this, sep);
    }

    /**
     * @see Combinators#endBy
     */
    default  Parser> endBy(Parser sep) {
        return Combinators.endBy(this, sep);
    }

    /**
     * @see Combinators#endBy1
     */
    default  Parser> endBy1(Parser sep) {
        return Combinators.endBy1(this, sep);
    }

    /**
     * @see Combinators#count
     */
    default Parser> count(int n) {
        return Combinators.count(this, n);
    }

    /**
     * @see Combinators#chainr
     */
    default Parser chainr(Parser> op, A x) {
        return Combinators.chainr(this, op, x);
    }

    /**
     * @see Combinators#chainr1
     */
    default Parser chainr1(Parser> op) {
        return Combinators.chainr1(this, op);
    }

    /**
     * @see Combinators#chainl
     */
    default Parser chainl(Parser> op, A x) {
        return Combinators.chainl(this, op, x);
    }

    /**
     * @see Combinators#chainl1
     */
    default Parser chainl1(Parser> op) {
        return Combinators.chainl1(this, op);
    }
}