package net.minecraft.util.parsing.packrat; import java.util.List; import java.util.Optional; import org.apache.commons.lang3.mutable.MutableBoolean; public interface Term { boolean parse(ParseState parseState, Scope scope, Control control); static Term named(Atom name) { return new Term.Reference<>(name); } static Term marker(Atom name, T value) { return new Term.Marker<>(name, value); } @SafeVarargs static Term sequence(Term... elements) { return new Term.Sequence<>(List.of(elements)); } @SafeVarargs static Term alternative(Term... elements) { return new Term.Alternative<>(List.of(elements)); } static Term optional(Term term) { return new Term.Maybe<>(term); } static Term cut() { return new Term() { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { control.cut(); return true; } public String toString() { return "↑"; } }; } static Term empty() { return new Term() { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { return true; } public String toString() { return "ε"; } }; } public record Alternative(List> elements) implements Term { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { MutableBoolean mutableBoolean = new MutableBoolean(); Control control2 = mutableBoolean::setTrue; int i = parseState.mark(); for (Term term : this.elements) { if (mutableBoolean.isTrue()) { break; } Scope scope2 = new Scope(); if (term.parse(parseState, scope2, control2)) { scope.putAll(scope2); return true; } parseState.restore(i); } return false; } } public record Marker(Atom name, T value) implements Term { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { scope.put(this.name, this.value); return true; } } public record Maybe(Term term) implements Term { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { int i = parseState.mark(); if (!this.term.parse(parseState, scope, control)) { parseState.restore(i); } return true; } } public record Reference(Atom name) implements Term { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { Optional optional = parseState.parse(this.name); if (optional.isEmpty()) { return false; } else { scope.put(this.name, (T)optional.get()); return true; } } } public record Sequence(List> elements) implements Term { @Override public boolean parse(ParseState parseState, Scope scope, Control control) { int i = parseState.mark(); for (Term term : this.elements) { if (!term.parse(parseState, scope, control)) { parseState.restore(i); return false; } } return true; } } }