package net.minecraft.util.parsing.packrat; import org.jspecify.annotations.Nullable; public interface Rule { @Nullable T parse(ParseState state); static Rule fromTerm(final Term child, final Rule.RuleAction action) { return new Rule.WrappedTerm<>(action, child); } static Rule fromTerm(final Term child, final Rule.SimpleRuleAction action) { return new Rule.WrappedTerm<>(action, child); } @FunctionalInterface interface RuleAction { @Nullable T run(ParseState state); } @FunctionalInterface interface SimpleRuleAction extends Rule.RuleAction { T run(Scope ruleScope); @Override default T run(final ParseState state) { return this.run(state.scope()); } } record WrappedTerm(Rule.RuleAction action, Term child) implements Rule { @Override public @Nullable T parse(final ParseState state) { Scope scope = state.scope(); scope.pushFrame(); try { return this.child.parse(state, scope, Control.UNBOUND) ? this.action.run(state) : null; } finally { scope.popFrame(); } } } }