246 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			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> separator) {
 | |
| 		return repeatedWithTrailingSeparator(element, listName, separator, 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;
 | |
| 		}
 | |
| 	}
 | |
| }
 |