minecraft-src/net/minecraft/util/parsing/packrat/Term.java
2025-07-04 03:45:38 +03:00

246 lines
6.3 KiB
Java

package net.minecraft.util.parsing.packrat;
import java.util.ArrayList;
import java.util.List;
public interface Term<S> {
boolean parse(ParseState<S> parseState, Scope scope, Control control);
static <S, T> Term<S> marker(Atom<T> name, T value) {
return new Term.Marker<>(name, value);
}
@SafeVarargs
static <S> Term<S> sequence(Term<S>... elements) {
return new Term.Sequence<>(elements);
}
@SafeVarargs
static <S> Term<S> alternative(Term<S>... elements) {
return new Term.Alternative<>(elements);
}
static <S> Term<S> optional(Term<S> term) {
return new Term.Maybe<>(term);
}
static <S, T> Term<S> repeated(NamedRule<S, T> element, Atom<List<T>> listName) {
return repeated(element, listName, 0);
}
static <S, T> Term<S> repeated(NamedRule<S, T> element, Atom<List<T>> listName, int minRepetitions) {
return new Term.Repeated<>(element, listName, minRepetitions);
}
static <S, T> Term<S> repeatedWithTrailingSeparator(NamedRule<S, T> element, Atom<List<T>> listName, Term<S> seperator) {
return repeatedWithTrailingSeparator(element, listName, seperator, 0);
}
static <S, T> Term<S> repeatedWithTrailingSeparator(NamedRule<S, T> element, Atom<List<T>> listName, Term<S> seperator, int minRepetitions) {
return new Term.RepeatedWithSeparator<>(element, listName, seperator, minRepetitions, true);
}
static <S, T> Term<S> repeatedWithoutTrailingSeparator(NamedRule<S, T> element, Atom<List<T>> listName, Term<S> seperator) {
return repeatedWithoutTrailingSeparator(element, listName, seperator, 0);
}
static <S, T> Term<S> repeatedWithoutTrailingSeparator(NamedRule<S, T> element, Atom<List<T>> listName, Term<S> seperator, int minRepetitions) {
return new Term.RepeatedWithSeparator<>(element, listName, seperator, minRepetitions, false);
}
static <S> Term<S> positiveLookahead(Term<S> term) {
return new Term.LookAhead<>(term, true);
}
static <S> Term<S> negativeLookahead(Term<S> term) {
return new Term.LookAhead<>(term, false);
}
static <S> Term<S> cut() {
return new Term<S>() {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
control.cut();
return true;
}
public String toString() {
return "";
}
};
}
static <S> Term<S> empty() {
return new Term<S>() {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
return true;
}
public String toString() {
return "ε";
}
};
}
static <S> Term<S> fail(Object reason) {
return new Term<S>() {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
parseState.errorCollector().store(parseState.mark(), reason);
return false;
}
public String toString() {
return "fail";
}
};
}
public record Alternative<S>(Term<S>[] elements) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
Control control2 = parseState.acquireControl();
try {
int i = parseState.mark();
scope.splitFrame();
for (Term<S> term : this.elements) {
if (term.parse(parseState, scope, control2)) {
scope.mergeFrame();
return true;
}
scope.clearFrameValues();
parseState.restore(i);
if (control2.hasCut()) {
break;
}
}
scope.popFrame();
return false;
} finally {
parseState.releaseControl();
}
}
}
public record LookAhead<S>(Term<S> term, boolean positive) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
int i = parseState.mark();
boolean bl = this.term.parse(parseState.silent(), scope, control);
parseState.restore(i);
return this.positive == bl;
}
}
public record Marker<S, T>(Atom<T> name, T value) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
scope.put(this.name, this.value);
return true;
}
}
public record Maybe<S>(Term<S> term) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
int i = parseState.mark();
if (!this.term.parse(parseState, scope, control)) {
parseState.restore(i);
}
return true;
}
}
public record Repeated<S, T>(NamedRule<S, T> element, Atom<List<T>> listName, int minRepetitions) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
int i = parseState.mark();
List<T> list = new ArrayList(this.minRepetitions);
while (true) {
int j = parseState.mark();
T object = parseState.parse(this.element);
if (object == null) {
parseState.restore(j);
if (list.size() < this.minRepetitions) {
parseState.restore(i);
return false;
} else {
scope.put(this.listName, list);
return true;
}
}
list.add(object);
}
}
}
public record RepeatedWithSeparator<S, T>(
NamedRule<S, T> element, Atom<List<T>> listName, Term<S> separator, int minRepetitions, boolean allowTrailingSeparator
) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
int i = parseState.mark();
List<T> list = new ArrayList(this.minRepetitions);
boolean bl = true;
while (true) {
int j = parseState.mark();
if (!bl && !this.separator.parse(parseState, scope, control)) {
parseState.restore(j);
break;
}
int k = parseState.mark();
T object = parseState.parse(this.element);
if (object == null) {
if (bl) {
parseState.restore(k);
} else {
if (!this.allowTrailingSeparator) {
parseState.restore(i);
return false;
}
parseState.restore(k);
}
break;
}
list.add(object);
bl = false;
}
if (list.size() < this.minRepetitions) {
parseState.restore(i);
return false;
} else {
scope.put(this.listName, list);
return true;
}
}
}
public record Sequence<S>(Term<S>[] elements) implements Term<S> {
@Override
public boolean parse(ParseState<S> parseState, Scope scope, Control control) {
int i = parseState.mark();
for (Term<S> term : this.elements) {
if (!term.parse(parseState, scope, control)) {
parseState.restore(i);
return false;
}
}
return true;
}
}
}