com.github.leeonky.interpreter.Notation Maven / Gradle / Ivy
package com.github.leeonky.interpreter;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static java.util.stream.Collectors.toSet;
public class Notation, O extends Operator,
P extends Procedure, E extends Expression>
implements ObjectParser {
private final String label;
private Notation(String label) {
this.label = label;
}
public static , O extends Operator,
P extends Procedure, E extends Expression>
Notation notation(String label) {
return new Notation<>(label);
}
public String getLabel() {
return label;
}
public int length() {
return label.length();
}
private Optional getToken(P procedure, Predicate predicate) {
return procedure.getSourceCode().popWord(this, () -> predicate.test(procedure));
}
private Optional getToken(P procedure) {
return getToken(procedure, p -> true);
}
public NodeParser node(Function factory) {
return procedure -> getToken(procedure).map(token ->
factory.apply(token.getContent()).setPositionBegin(token.getPosition()));
}
public NodeParser wordNode(Function factory, Set delimiter) {
return procedure -> procedure.getSourceCode().tryFetch(() -> getToken(procedure).map(token ->
notAWord(delimiter, procedure) ? null :
factory.apply(token.getContent()).setPositionBegin(token.getPosition())));
}
private boolean notAWord(Set delimiter, P procedure) {
return procedure.getSourceCode().hasCode()
&& delimiter.stream().noneMatch(s -> procedure.getSourceCode().startsWith(s));
}
public OperatorParser operator(Supplier factory, Predicate predicate) {
return procedure -> getToken(procedure, predicate).map(token -> factory.get().setPosition(token.getPosition()));
}
public OperatorParser operator(Supplier factory) {
return operator(factory, procedure -> true);
}
public OperatorParser keywordOperator(Supplier factory, Set Delimiter) {
return procedure -> procedure.getSourceCode().tryFetch(() -> operator(factory, p -> true)
.parse(procedure).map(operator -> notAWord(Delimiter, procedure) ? null : operator));
}
public NodeParser with(NodeParser.Mandatory mandatory) {
return procedure -> getToken(procedure).map(t -> mandatory.parse(procedure).setPositionBegin(t.getPosition()));
}
public , MA extends Parser.Mandatory, T> PA before(PA parser) {
return parser.castParser(procedure -> procedure.getSourceCode().tryFetch(() -> getToken(procedure)
.flatMap(t -> parser.parse(procedure))));
}
public , MA extends Parser.Mandatory, T> PA before(MA ma) {
return ma.castParser(procedure -> getToken(procedure).map(t -> ma.parse(procedure)));
}
public ClauseParser clause(BiFunction nodeFactory) {
return procedure -> getToken(procedure).map(token -> input ->
nodeFactory.apply(token, input).setPositionBegin(token.getPosition()));
}
@Override
public Optional parse(P procedure) {
return procedure.getSourceCode().popString(getLabel());
}
public Set> postfix(Set> postfixes) {
return postfixes.stream().map(c -> getLabel() + c).map(label -> Notation.notation(label)).collect(toSet());
}
}