ComponentPredicateParser.java

net.minecraft.commands.arguments.item.ComponentPredicateParser

信息

  • 全限定名:net.minecraft.commands.arguments.item.ComponentPredicateParser
  • 类型:public class
  • 包:net.minecraft.commands.arguments.item
  • 源码路径:src/main/java/net/minecraft/commands/arguments/item/ComponentPredicateParser.java
  • 起始行号:L27
  • 职责:

    TODO

字段/常量

内部类/嵌套类型

  • net.minecraft.commands.arguments.item.ComponentPredicateParser.ComponentLookupRule

    • 类型: class
    • 修饰符: private static
    • 源码定位: L128
    • 说明:

      TODO

  • net.minecraft.commands.arguments.item.ComponentPredicateParser.Context

    • 类型: interface
    • 修饰符: public
    • 源码定位: L144
    • 说明:

      TODO

  • net.minecraft.commands.arguments.item.ComponentPredicateParser.ElementLookupRule

    • 类型: class
    • 修饰符: private static
    • 源码定位: L172
    • 说明:

      TODO

  • net.minecraft.commands.arguments.item.ComponentPredicateParser.PredicateLookupRule

    • 类型: class
    • 修饰符: private static
    • 源码定位: L188
    • 说明:

      TODO

  • net.minecraft.commands.arguments.item.ComponentPredicateParser.TagLookupRule

    • 类型: class
    • 修饰符: private static
    • 源码定位: L204
    • 说明:

      TODO

构造器

方法

下面的方法块按源码顺序生成。

public static <T,C,P> Grammar<List<T>> createGrammar(ComponentPredicateParser.Context<T,C,P> context) @ L28

  • 方法名:createGrammar
  • 源码定位:L28
  • 返回类型:<T,C,P> Grammar<List>
  • 修饰符:public static

参数:

  • context: ComponentPredicateParser.Context<T,C,P>

说明:

TODO

代码

public class ComponentPredicateParser {
    public static <T, C, P> Grammar<List<T>> createGrammar(ComponentPredicateParser.Context<T, C, P> context) {
        Atom<List<T>> top = Atom.of("top");
        Atom<Optional<T>> type = Atom.of("type");
        Atom<Unit> anyType = Atom.of("any_type");
        Atom<T> elementType = Atom.of("element_type");
        Atom<T> tagType = Atom.of("tag_type");
        Atom<List<T>> conditions = Atom.of("conditions");
        Atom<List<T>> alternatives = Atom.of("alternatives");
        Atom<T> term = Atom.of("term");
        Atom<T> negation = Atom.of("negation");
        Atom<T> test = Atom.of("test");
        Atom<C> componentType = Atom.of("component_type");
        Atom<P> predicateType = Atom.of("predicate_type");
        Atom<Identifier> id = Atom.of("id");
        Atom<Dynamic<?>> tag = Atom.of("tag");
        Dictionary<StringReader> rules = new Dictionary<>();
        NamedRule<StringReader, Identifier> idRule = rules.put(id, IdentifierParseRule.INSTANCE);
        NamedRule<StringReader, List<T>> topRule = rules.put(
            top,
            Term.alternative(
                Term.sequence(
                    rules.named(type), StringReaderTerms.character('['), Term.cut(), Term.optional(rules.named(conditions)), StringReaderTerms.character(']')
                ),
                rules.named(type)
            ),
            scope -> {
                Builder<T> builder = ImmutableList.builder();
                scope.getOrThrow(type).ifPresent(builder::add);
                List<T> parsedConditions = scope.get(conditions);
                if (parsedConditions != null) {
                    builder.addAll(parsedConditions);
                }
 
                return builder.build();
            }
        );
        rules.put(
            type,
            Term.alternative(rules.named(elementType), Term.sequence(StringReaderTerms.character('#'), Term.cut(), rules.named(tagType)), rules.named(anyType)),
            scope -> Optional.ofNullable(scope.getAny(elementType, tagType))
        );
        rules.put(anyType, StringReaderTerms.character('*'), s -> Unit.INSTANCE);
        rules.put(elementType, new ComponentPredicateParser.ElementLookupRule<>(idRule, context));
        rules.put(tagType, new ComponentPredicateParser.TagLookupRule<>(idRule, context));
        rules.put(
            conditions,
            Term.sequence(rules.named(alternatives), Term.optional(Term.sequence(StringReaderTerms.character(','), rules.named(conditions)))),
            scope -> {
                T parsedCondition = context.anyOf(scope.getOrThrow(alternatives));
                return Optional.ofNullable(scope.get(conditions)).map(rest -> Util.copyAndAdd(parsedCondition, (List<T>)rest)).orElse(List.of(parsedCondition));
            }
        );
        rules.put(
            alternatives,
            Term.sequence(rules.named(term), Term.optional(Term.sequence(StringReaderTerms.character('|'), rules.named(alternatives)))),
            scope -> {
                T alternative = scope.getOrThrow(term);
                return Optional.ofNullable(scope.get(alternatives)).map(rest -> Util.copyAndAdd(alternative, (List<T>)rest)).orElse(List.of(alternative));
            }
        );
        rules.put(
            term,
            Term.alternative(rules.named(test), Term.sequence(StringReaderTerms.character('!'), rules.named(negation))),
            scope -> scope.getAnyOrThrow(test, negation)
        );
        rules.put(negation, rules.named(test), scope -> context.negate(scope.getOrThrow(test)));
        rules.putComplex(
            test,
            Term.alternative(
                Term.sequence(rules.named(componentType), StringReaderTerms.character('='), Term.cut(), rules.named(tag)),
                Term.sequence(rules.named(predicateType), StringReaderTerms.character('~'), Term.cut(), rules.named(tag)),
                rules.named(componentType)
            ),
            state -> {
                Scope scope = state.scope();
                P predicate = scope.get(predicateType);
 
                try {
                    if (predicate != null) {
                        Dynamic<?> value = scope.getOrThrow(tag);
                        return context.createPredicateTest(state.input(), predicate, value);
                    } else {
                        C component = scope.getOrThrow(componentType);
                        Dynamic<?> value = scope.get(tag);
                        return value != null
                            ? context.createComponentTest(state.input(), component, value)
                            : context.createComponentTest(state.input(), component);
                    }
                } catch (CommandSyntaxException var9x) {
                    state.errorCollector().store(state.mark(), var9x);
                    return null;
                }
            }
        );
        rules.put(componentType, new ComponentPredicateParser.ComponentLookupRule<>(idRule, context));
        rules.put(predicateType, new ComponentPredicateParser.PredicateLookupRule<>(idRule, context));
        rules.put(tag, new TagParseRule<>(NbtOps.INSTANCE));
        return new Grammar<>(rules, topRule);
    }
 
    private static class ComponentLookupRule<T, C, P> extends ResourceLookupRule<ComponentPredicateParser.Context<T, C, P>, C> {
        private ComponentLookupRule(NamedRule<StringReader, Identifier> idParser, ComponentPredicateParser.Context<T, C, P> context) {
            super(idParser, context);
        }
 
        @Override
        protected C validateElement(ImmutableStringReader reader, Identifier id) throws Exception {
            return this.context.lookupComponentType(reader, id);
        }
 
        @Override
        public Stream<Identifier> possibleResources() {
            return this.context.listComponentTypes();
        }
    }
 
    public interface Context<T, C, P> {
        T forElementType(ImmutableStringReader reader, Identifier id) throws CommandSyntaxException;
 
        Stream<Identifier> listElementTypes();
 
        T forTagType(ImmutableStringReader reader, Identifier id) throws CommandSyntaxException;
 
        Stream<Identifier> listTagTypes();
 
        C lookupComponentType(ImmutableStringReader reader, Identifier id) throws CommandSyntaxException;
 
        Stream<Identifier> listComponentTypes();
 
        T createComponentTest(ImmutableStringReader reader, C componentType, Dynamic<?> value) throws CommandSyntaxException;
 
        T createComponentTest(ImmutableStringReader reader, C componentType);
 
        P lookupPredicateType(ImmutableStringReader reader, Identifier id) throws CommandSyntaxException;
 
        Stream<Identifier> listPredicateTypes();
 
        T createPredicateTest(ImmutableStringReader reader, P predicateType, Dynamic<?> value) throws CommandSyntaxException;
 
        T negate(T value);
 
        T anyOf(List<T> alternatives);
    }
 
    private static class ElementLookupRule<T, C, P> extends ResourceLookupRule<ComponentPredicateParser.Context<T, C, P>, T> {
        private ElementLookupRule(NamedRule<StringReader, Identifier> idParser, ComponentPredicateParser.Context<T, C, P> context) {
            super(idParser, context);
        }
 
        @Override
        protected T validateElement(ImmutableStringReader reader, Identifier id) throws Exception {
            return this.context.forElementType(reader, id);
        }
 
        @Override
        public Stream<Identifier> possibleResources() {
            return this.context.listElementTypes();
        }
    }
 
    private static class PredicateLookupRule<T, C, P> extends ResourceLookupRule<ComponentPredicateParser.Context<T, C, P>, P> {
        private PredicateLookupRule(NamedRule<StringReader, Identifier> idParser, ComponentPredicateParser.Context<T, C, P> context) {
            super(idParser, context);
        }
 
        @Override
        protected P validateElement(ImmutableStringReader reader, Identifier id) throws Exception {
            return this.context.lookupPredicateType(reader, id);
        }
 
        @Override
        public Stream<Identifier> possibleResources() {
            return this.context.listPredicateTypes();
        }
    }
 
    private static class TagLookupRule<T, C, P> extends ResourceLookupRule<ComponentPredicateParser.Context<T, C, P>, T> {
        private TagLookupRule(NamedRule<StringReader, Identifier> idParser, ComponentPredicateParser.Context<T, C, P> context) {
            super(idParser, context);
        }
 
        @Override
        protected T validateElement(ImmutableStringReader reader, Identifier id) throws Exception {
            return this.context.forTagType(reader, id);
        }
 
        @Override
        public Stream<Identifier> possibleResources() {
            return this.context.listTagTypes();
        }
    }
}

引用的其他类

  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.copyAndAdd()
  • Atom

    • 引用位置: 方法调用
    • 关联成员: Atom.of()
  • Term

    • 引用位置: 方法调用
    • 关联成员: Term.alternative(), Term.cut(), Term.optional(), Term.sequence()
  • Grammar

    • 引用位置: 返回值
  • StringReaderTerms

    • 引用位置: 方法调用
    • 关联成员: StringReaderTerms.character()