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

com.github.leeonky.interpreter.Syntax Maven / Gradle / Ivy

The newest version!
package com.github.leeonky.interpreter;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;

public abstract class Syntax, P extends Procedure, PA extends Parser,
        MA extends Parser.Mandatory, T, R, A> {
    protected final BiFunction, A> parser;

    private Token token;

    protected Syntax(BiFunction, A> parser) {
        this.parser = parser;
    }

    public static , P extends Procedure, PA extends Parser,
            MA extends Parser.Mandatory, T> Syntax, T> single(PA parser) {
        return new DefaultSyntax, T>((procedure, syntax) -> {
            Optional optional = parser.parse(procedure);
            if (optional.isPresent()) {
                syntax.isClose(procedure);
                syntax.close(procedure);
            }
            return optional.orElse(null);
        }) {
            @Override
            protected NodeParser parse(Syntax,
                    T> syntax, Function factory) {
                return (P procedure) -> Optional.ofNullable(parser.apply(procedure, syntax)).map(factory);
            }
        };
    }

    public static , P extends Procedure, PA extends Parser,
            MA extends Parser.Mandatory, T> Syntax, T> single(MA parser) {
        return new DefaultSyntax, T>((procedure, syntax) -> {
            T t = parser.parse(procedure);
            syntax.isClose(procedure);
            syntax.close(procedure);
            return t;
        }) {
            @Override
            protected NodeParser.Mandatory parse(Syntax, T> syntax, Function factory) {
                return (P procedure) -> factory.apply(parser.apply(procedure, syntax));
            }
        };
    }

    public static , P extends Procedure, PA extends Parser,
            MA extends Parser.Mandatory, T> Syntax, List> many(MA mandatory) {
        return new DefaultSyntax<>((procedure, syntax) -> procedure.withColumn(() -> new ArrayList() {{
            while (!syntax.isClose(procedure)) {
                add(mandatory.parse(procedure));
                procedure.incrementColumn();
                if (!syntax.isSplitter(procedure)) {
                    syntax.isClose(procedure);
                    break;
                }
            }
            syntax.close(procedure);
        }}));
    }

    public static , P extends Procedure, PA extends Parser,
            MA extends Parser.Mandatory, T> Syntax, List> many(PA parser) {
        return new DefaultSyntax<>((procedure, syntax) -> procedure.withColumn(() -> new ArrayList() {{
            while (!syntax.isClose(procedure)) {
                Optional optional = parser.parse(procedure);
                if (!optional.isPresent())
                    break;
                add(optional.get());
                procedure.incrementColumn();
                if (!syntax.isSplitter(procedure)) {
                    syntax.isClose(procedure);
                    break;
                }
            }
            syntax.close(procedure);
        }}));
    }

    protected abstract boolean isClose(P procedure);

    protected abstract void close(P procedure);

    protected abstract boolean isSplitter(P procedure);

    @SuppressWarnings("unchecked")
    protected R parse(Syntax syntax, Function factory) {
        return (R) (NodeParser.Mandatory) procedure -> factory.apply(parser.apply(procedure, syntax));
    }

    public  Syntax and(Function,
            Syntax> rule) {
        return rule.apply(this);
    }

    public R as(Function factory) {
        return parse(this, factory);
    }

    @SuppressWarnings("unchecked")
    public R as() {
        return parse(this, a -> (N) a);
    }

    protected Token getToken() {
        return token;
    }

    protected void setToken(Token token) {
        this.token = token;
    }

    public static class DefaultSyntax, P extends Procedure,
            PA extends Parser, MA extends Parser.Mandatory, T, R, A>
            extends Syntax {

        public DefaultSyntax(BiFunction, A> parser) {
            super(parser);
        }

        @Override
        protected boolean isClose(P procedure) {
            return false;
        }

        @Override
        protected void close(P procedure) {
        }

        @Override
        protected boolean isSplitter(P procedure) {
            return true;
        }
    }

    public static class CompositeSyntax, P extends Procedure,
            PA extends Parser, MA extends Parser.Mandatory, T, R, A>
            extends Syntax {

        private final Syntax syntax;

        public CompositeSyntax(Syntax syntax) {
            super(syntax.parser);
            this.syntax = syntax;
        }

        protected String quote(String label) {
            return label.contains("`") ? "'" + label + "'" : "`" + label + "`";
        }

        @Override
        protected boolean isClose(P procedure) {
            return syntax.isClose(procedure);
        }

        @Override
        protected void close(P procedure) {
            syntax.close(procedure);
        }

        @Override
        protected boolean isSplitter(P procedure) {
            return syntax.isSplitter(procedure);
        }

        @Override
        protected R parse(Syntax syntax, Function factory) {
            return this.syntax.parse(syntax, factory);
        }

        @Override
        protected Token getToken() {
            return syntax.getToken();
        }

        @Override
        protected void setToken(Token token) {
            syntax.setToken(token);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy