9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

格式化

This commit is contained in:
jhqwqmc
2025-12-01 07:57:46 +08:00
parent 16aedafbe4
commit edfdf083e0
2 changed files with 334 additions and 224 deletions

View File

@@ -24,7 +24,7 @@ import java.util.stream.LongStream;
public class SnbtGrammar { public class SnbtGrammar {
private static final DynamicCommandExceptionType ERROR_NUMBER_PARSE_FAILURE = new LocalizedDynamicCommandExceptionType( private static final DynamicCommandExceptionType ERROR_NUMBER_PARSE_FAILURE = new LocalizedDynamicCommandExceptionType(
number -> new LocalizedMessage("warning.config.type.snbt.parser.number_parse_failure", String.valueOf(number)) message -> new LocalizedMessage("warning.config.type.snbt.parser.number_parse_failure", String.valueOf(message))
); );
static final DynamicCommandExceptionType ERROR_EXPECTED_HEX_ESCAPE = new LocalizedDynamicCommandExceptionType( static final DynamicCommandExceptionType ERROR_EXPECTED_HEX_ESCAPE = new LocalizedDynamicCommandExceptionType(
length -> new LocalizedMessage("warning.config.type.snbt.parser.expected_hex_escape", String.valueOf(length)) length -> new LocalizedMessage("warning.config.type.snbt.parser.expected_hex_escape", String.valueOf(length))
@@ -248,7 +248,9 @@ public class SnbtGrammar {
T emptyList = ops.emptyList(); T emptyList = ops.emptyList();
T nullString = ops.createString("null"); T nullString = ops.createString("null");
boolean isJavaType = "null".equals(nullString); // 确定是 Java 类型的 boolean isJavaType = "null".equals(nullString); // 确定是 Java 类型的
Dictionary<StringReader> rules = new Dictionary<>(); Dictionary<StringReader> rules = new Dictionary<>();
Atom<Sign> sign = Atom.of("sign"); Atom<Sign> sign = Atom.of("sign");
rules.put( rules.put(
sign, sign,
@@ -258,6 +260,7 @@ public class SnbtGrammar {
), ),
scope -> scope.getOrThrow(sign) scope -> scope.getOrThrow(sign)
); );
Atom<IntegerSuffix> integerSuffix = Atom.of("integer_suffix"); Atom<IntegerSuffix> integerSuffix = Atom.of("integer_suffix");
rules.put( rules.put(
integerSuffix, integerSuffix,
@@ -265,43 +268,19 @@ public class SnbtGrammar {
Term.sequence( Term.sequence(
StringReaderTerms.characters('u', 'U'), StringReaderTerms.characters('u', 'U'),
Term.alternative( Term.alternative(
Term.sequence( Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.BYTE))),
StringReaderTerms.characters('b', 'B'), Term.sequence(StringReaderTerms.characters('s', 'S'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.SHORT))),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.BYTE)) Term.sequence(StringReaderTerms.characters('i', 'I'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.INT))),
), Term.sequence(StringReaderTerms.characters('l', 'L'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.LONG)))
Term.sequence(
StringReaderTerms.characters('s', 'S'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.SHORT))
),
Term.sequence(
StringReaderTerms.characters('i', 'I'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.INT))
),
Term.sequence(
StringReaderTerms.characters('l', 'L'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.LONG))
)
) )
), ),
Term.sequence( Term.sequence(
StringReaderTerms.characters('s', 'S'), StringReaderTerms.characters('s', 'S'),
Term.alternative( Term.alternative(
Term.sequence( Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.BYTE))),
StringReaderTerms.characters('b', 'B'), Term.sequence(StringReaderTerms.characters('s', 'S'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.SHORT))),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.BYTE)) Term.sequence(StringReaderTerms.characters('i', 'I'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.INT))),
), Term.sequence(StringReaderTerms.characters('l', 'L'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.LONG)))
Term.sequence(
StringReaderTerms.characters('s', 'S'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.SHORT))
),
Term.sequence(
StringReaderTerms.characters('i', 'I'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.INT))
),
Term.sequence(
StringReaderTerms.characters('l', 'L'),
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.LONG))
)
) )
), ),
Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.BYTE))), Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.BYTE))),
@@ -311,12 +290,16 @@ public class SnbtGrammar {
), ),
scope -> scope.getOrThrow(integerSuffix) scope -> scope.getOrThrow(integerSuffix)
); );
Atom<String> binaryNumeral = Atom.of("binary_numeral"); Atom<String> binaryNumeral = Atom.of("binary_numeral");
rules.put(binaryNumeral, BINARY_NUMERAL); rules.put(binaryNumeral, BINARY_NUMERAL);
Atom<String> decimalNumeral = Atom.of("decimal_numeral"); Atom<String> decimalNumeral = Atom.of("decimal_numeral");
rules.put(decimalNumeral, DECIMAL_NUMERAL); rules.put(decimalNumeral, DECIMAL_NUMERAL);
Atom<String> hexNumeral = Atom.of("hex_numeral"); Atom<String> hexNumeral = Atom.of("hex_numeral");
rules.put(hexNumeral, HEX_NUMERAL); rules.put(hexNumeral, HEX_NUMERAL);
Atom<IntegerLiteral> integerLiteral = Atom.of("integer_literal"); Atom<IntegerLiteral> integerLiteral = Atom.of("integer_literal");
NamedRule<StringReader, IntegerLiteral> integerLiteralRule = rules.put( NamedRule<StringReader, IntegerLiteral> integerLiteralRule = rules.put(
integerLiteral, integerLiteral,
@@ -344,14 +327,15 @@ public class SnbtGrammar {
if (decimalContents != null) { if (decimalContents != null) {
return new IntegerLiteral(signValue, Base.DECIMAL, decimalContents, suffix); return new IntegerLiteral(signValue, Base.DECIMAL, decimalContents, suffix);
} }
String string1 = scope.get(hexNumeral); String hexContents = scope.get(hexNumeral);
if (string1 != null) { if (hexContents != null) {
return new IntegerLiteral(signValue, Base.HEX, string1, suffix); return new IntegerLiteral(signValue, Base.HEX, hexContents, suffix);
} }
String string2 = scope.getOrThrow(binaryNumeral); String binaryContents = scope.getOrThrow(binaryNumeral);
return new IntegerLiteral(signValue, Base.BINARY, string2, suffix); return new IntegerLiteral(signValue, Base.BINARY, binaryContents, suffix);
} }
); );
Atom<TypeSuffix> floatTypeSuffix = Atom.of("float_type_suffix"); Atom<TypeSuffix> floatTypeSuffix = Atom.of("float_type_suffix");
rules.put( rules.put(
floatTypeSuffix, floatTypeSuffix,
@@ -361,12 +345,18 @@ public class SnbtGrammar {
), ),
scope -> scope.getOrThrow(floatTypeSuffix) scope -> scope.getOrThrow(floatTypeSuffix)
); );
Atom<Signed<String>> floatExponentPart = Atom.of("float_exponent_part"); Atom<Signed<String>> floatExponentPart = Atom.of("float_exponent_part");
rules.put( rules.put(
floatExponentPart, floatExponentPart,
Term.sequence(StringReaderTerms.characters('e', 'E'), Term.optional(rules.named(sign)), rules.named(decimalNumeral)), Term.sequence(
StringReaderTerms.characters('e', 'E'),
Term.optional(rules.named(sign)),
rules.named(decimalNumeral)
),
scope -> new Signed<>(scope.getOrDefault(sign, Sign.PLUS), scope.getOrThrow(decimalNumeral)) scope -> new Signed<>(scope.getOrDefault(sign, Sign.PLUS), scope.getOrThrow(decimalNumeral))
); );
Atom<String> floatWholePart = Atom.of("float_whole_part"); Atom<String> floatWholePart = Atom.of("float_whole_part");
Atom<String> floatFractionPart = Atom.of("float_fraction_part"); Atom<String> floatFractionPart = Atom.of("float_fraction_part");
Atom<T> floatLiteral = Atom.of("float_literal"); Atom<T> floatLiteral = Atom.of("float_literal");
@@ -390,8 +380,17 @@ public class SnbtGrammar {
Term.optional(rules.named(floatExponentPart)), Term.optional(rules.named(floatExponentPart)),
Term.optional(rules.named(floatTypeSuffix)) Term.optional(rules.named(floatTypeSuffix))
), ),
Term.sequence(rules.namedWithAlias(decimalNumeral, floatWholePart), rules.named(floatExponentPart), Term.cut(), Term.optional(rules.named(floatTypeSuffix))), Term.sequence(
Term.sequence(rules.namedWithAlias(decimalNumeral, floatWholePart), Term.optional(rules.named(floatExponentPart)), rules.named(floatTypeSuffix)) rules.namedWithAlias(decimalNumeral, floatWholePart),
rules.named(floatExponentPart),
Term.cut(),
Term.optional(rules.named(floatTypeSuffix))
),
Term.sequence(
rules.namedWithAlias(decimalNumeral, floatWholePart),
Term.optional(rules.named(floatExponentPart)),
rules.named(floatTypeSuffix)
)
) )
), ),
state -> { state -> {
@@ -404,14 +403,19 @@ public class SnbtGrammar {
return createFloat(ops, wholeSign, whole, fraction, exponent, typeSuffix, state); return createFloat(ops, wholeSign, whole, fraction, exponent, typeSuffix, state);
} }
); );
Atom<String> stringHex2 = Atom.of("string_hex_2"); Atom<String> stringHex2 = Atom.of("string_hex_2");
rules.put(stringHex2, new SimpleHexLiteralParseRule(2)); rules.put(stringHex2, new SimpleHexLiteralParseRule(2));
Atom<String> stringHex4 = Atom.of("string_hex_4"); Atom<String> stringHex4 = Atom.of("string_hex_4");
rules.put(stringHex4, new SimpleHexLiteralParseRule(4)); rules.put(stringHex4, new SimpleHexLiteralParseRule(4));
Atom<String> stringHex8 = Atom.of("string_hex_8"); Atom<String> stringHex8 = Atom.of("string_hex_8");
rules.put(stringHex8, new SimpleHexLiteralParseRule(8)); rules.put(stringHex8, new SimpleHexLiteralParseRule(8));
Atom<String> stringUnicodeName = Atom.of("string_unicode_name"); Atom<String> stringUnicodeName = Atom.of("string_unicode_name");
rules.put(stringUnicodeName, new GreedyPatternParseRule(UNICODE_NAME, ERROR_INVALID_CHARACTER_NAME)); rules.put(stringUnicodeName, new GreedyPatternParseRule(UNICODE_NAME, ERROR_INVALID_CHARACTER_NAME));
Atom<String> stringEscapeSequence = Atom.of("string_escape_sequence"); Atom<String> stringEscapeSequence = Atom.of("string_escape_sequence");
rules.putComplex( rules.putComplex(
stringEscapeSequence, stringEscapeSequence,
@@ -428,7 +432,12 @@ public class SnbtGrammar {
Term.sequence(StringReaderTerms.character('x'), rules.named(stringHex2)), Term.sequence(StringReaderTerms.character('x'), rules.named(stringHex2)),
Term.sequence(StringReaderTerms.character('u'), rules.named(stringHex4)), Term.sequence(StringReaderTerms.character('u'), rules.named(stringHex4)),
Term.sequence(StringReaderTerms.character('U'), rules.named(stringHex8)), Term.sequence(StringReaderTerms.character('U'), rules.named(stringHex8)),
Term.sequence(StringReaderTerms.character('N'), StringReaderTerms.character('{'), rules.named(stringUnicodeName), StringReaderTerms.character('}')) Term.sequence(
StringReaderTerms.character('N'),
StringReaderTerms.character('{'),
rules.named(stringUnicodeName),
StringReaderTerms.character('}')
)
), ),
state -> { state -> {
Scope scope = state.scope(); Scope scope = state.scope();
@@ -440,8 +449,7 @@ public class SnbtGrammar {
if (hexEscape != null) { if (hexEscape != null) {
int codePoint = HexFormat.fromHexDigits(hexEscape); int codePoint = HexFormat.fromHexDigits(hexEscape);
if (!Character.isValidCodePoint(codePoint)) { if (!Character.isValidCodePoint(codePoint)) {
state.errorCollector() state.errorCollector().store(state.mark(), DelayedException.create(ERROR_INVALID_CODEPOINT, String.format(Locale.ROOT, "U+%08X", codePoint)));
.store(state.mark(), DelayedException.create(ERROR_INVALID_CODEPOINT, String.format(Locale.ROOT, "U+%08X", codePoint)));
return null; return null;
} }
return Character.toString(codePoint); return Character.toString(codePoint);
@@ -459,12 +467,14 @@ public class SnbtGrammar {
return Character.toString(codePoint); return Character.toString(codePoint);
} }
); );
Atom<String> stringPlainContents = Atom.of("string_plain_contents"); Atom<String> stringPlainContents = Atom.of("string_plain_contents");
rules.put(stringPlainContents, PLAIN_STRING_CHUNK); rules.put(stringPlainContents, PLAIN_STRING_CHUNK);
Atom<List<String>> stringChunks = Atom.of("string_chunks"); Atom<List<String>> stringChunks = Atom.of("string_chunks");
Atom<String> stringContents = Atom.of("string_contents"); Atom<String> stringContents = Atom.of("string_contents");
Atom<String> singleQuotedStringChunk = Atom.of("single_quoted_string_chunk"); Atom<String> singleQuotedStringChunk = Atom.of("single_quoted_string_chunk");
NamedRule<StringReader, String> namedRule1 = rules.put( NamedRule<StringReader, String> singleQuotedStringChunkRule = rules.put(
singleQuotedStringChunk, singleQuotedStringChunk,
Term.alternative( Term.alternative(
rules.namedWithAlias(stringPlainContents, stringContents), rules.namedWithAlias(stringPlainContents, stringContents),
@@ -474,9 +484,14 @@ public class SnbtGrammar {
scope -> scope.getOrThrow(stringContents) scope -> scope.getOrThrow(stringContents)
); );
Atom<String> singleQuotedStringContents = Atom.of("single_quoted_string_contents"); Atom<String> singleQuotedStringContents = Atom.of("single_quoted_string_contents");
rules.put(singleQuotedStringContents, Term.repeated(namedRule1, stringChunks), scope -> joinList(scope.getOrThrow(stringChunks))); rules.put(
singleQuotedStringContents,
Term.repeated(singleQuotedStringChunkRule, stringChunks),
scope -> joinList(scope.getOrThrow(stringChunks))
);
Atom<String> doubleQuotedStringChunk = Atom.of("double_quoted_string_chunk"); Atom<String> doubleQuotedStringChunk = Atom.of("double_quoted_string_chunk");
NamedRule<StringReader, String> namedRule2 = rules.put( NamedRule<StringReader, String> doubleQuotedStringChunkRule = rules.put(
doubleQuotedStringChunk, doubleQuotedStringChunk,
Term.alternative( Term.alternative(
rules.namedWithAlias(stringPlainContents, stringContents), rules.namedWithAlias(stringPlainContents, stringContents),
@@ -486,31 +501,59 @@ public class SnbtGrammar {
scope -> scope.getOrThrow(stringContents) scope -> scope.getOrThrow(stringContents)
); );
Atom<String> doubleQuotedStringContents = Atom.of("double_quoted_string_contents"); Atom<String> doubleQuotedStringContents = Atom.of("double_quoted_string_contents");
rules.put(doubleQuotedStringContents, Term.repeated(namedRule2, stringChunks), scope -> joinList(scope.getOrThrow(stringChunks))); rules.put(
doubleQuotedStringContents,
Term.repeated(doubleQuotedStringChunkRule, stringChunks),
scope -> joinList(scope.getOrThrow(stringChunks))
);
Atom<String> quotedStringLiteral = Atom.of("quoted_string_literal"); Atom<String> quotedStringLiteral = Atom.of("quoted_string_literal");
rules.put( rules.put(
quotedStringLiteral, quotedStringLiteral,
Term.alternative( Term.alternative(
Term.sequence( Term.sequence(
StringReaderTerms.character('"'), Term.cut(), Term.optional(rules.namedWithAlias(doubleQuotedStringContents, stringContents)), StringReaderTerms.character('"') StringReaderTerms.character('"'),
Term.cut(),
Term.optional(rules.namedWithAlias(doubleQuotedStringContents, stringContents)),
StringReaderTerms.character('"')
), ),
Term.sequence(StringReaderTerms.character('\''), Term.optional(rules.namedWithAlias(singleQuotedStringContents, stringContents)), StringReaderTerms.character('\'')) Term.sequence(
StringReaderTerms.character('\''),
Term.optional(rules.namedWithAlias(singleQuotedStringContents, stringContents)),
StringReaderTerms.character('\'')
)
), ),
scope -> scope.getOrThrow(stringContents) scope -> scope.getOrThrow(stringContents)
); );
Atom<String> unquotedString = Atom.of("unquoted_string"); Atom<String> unquotedString = Atom.of("unquoted_string");
rules.put(unquotedString, new UnquotedStringParseRule(1, ERROR_EXPECTED_UNQUOTED_STRING)); rules.put(
unquotedString,
new UnquotedStringParseRule(1, ERROR_EXPECTED_UNQUOTED_STRING)
);
Atom<T> literal = Atom.of("literal"); Atom<T> literal = Atom.of("literal");
Atom<List<T>> argumentList = Atom.of("arguments"); Atom<List<T>> argumentList = Atom.of("arguments");
rules.put( rules.put(
argumentList, Term.repeatedWithTrailingSeparator(rules.forward(literal), argumentList, StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)), scope -> scope.getOrThrow(argumentList) argumentList,
Term.repeatedWithTrailingSeparator(
rules.forward(literal),
argumentList,
StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)
),
scope -> scope.getOrThrow(argumentList)
); );
Atom<T> unquotedStringOrBuiltIn = Atom.of("unquoted_string_or_builtin"); Atom<T> unquotedStringOrBuiltIn = Atom.of("unquoted_string_or_builtin");
rules.putComplex( rules.putComplex(
unquotedStringOrBuiltIn, unquotedStringOrBuiltIn,
Term.sequence( Term.sequence(
rules.named(unquotedString), rules.named(unquotedString),
Term.optional(Term.sequence(StringReaderTerms.character('('), rules.named(argumentList), StringReaderTerms.character(')'))) Term.optional(Term.sequence(
StringReaderTerms.character('('),
rules.named(argumentList),
StringReaderTerms.character(')')
))
), ),
state -> { state -> {
Scope scope = state.scope(); Scope scope = state.scope();
@@ -543,11 +586,26 @@ public class SnbtGrammar {
return null; return null;
} }
); );
Atom<String> mapKey = Atom.of("map_key"); Atom<String> mapKey = Atom.of("map_key");
rules.put(mapKey, Term.alternative(rules.named(quotedStringLiteral), rules.named(unquotedString)), scope -> scope.getAnyOrThrow(quotedStringLiteral, unquotedString)); rules.put(
mapKey,
Term.alternative(
rules.named(quotedStringLiteral),
rules.named(unquotedString)
),
scope -> scope.getAnyOrThrow(quotedStringLiteral, unquotedString)
);
Atom<Entry<String, T>> mapEntry = Atom.of("map_entry"); Atom<Entry<String, T>> mapEntry = Atom.of("map_entry");
NamedRule<StringReader, Entry<String, T>> mapEntryRule = rules.putComplex( NamedRule<StringReader, Entry<String, T>> mapEntryRule = rules.putComplex(
mapEntry, Term.sequence(rules.named(mapKey), StringReaderTerms.character(TagParser.NAME_VALUE_SEPARATOR), rules.named(literal)), state -> { mapEntry,
Term.sequence(
rules.named(mapKey),
StringReaderTerms.character(TagParser.NAME_VALUE_SEPARATOR),
rules.named(literal)
),
state -> {
Scope scope = state.scope(); Scope scope = state.scope();
String key = scope.getOrThrow(mapKey); String key = scope.getOrThrow(mapKey);
if (key.isEmpty()) { if (key.isEmpty()) {
@@ -558,26 +616,52 @@ public class SnbtGrammar {
return Map.entry(key, value); return Map.entry(key, value);
} }
); );
Atom<List<Entry<String, T>>> mapEntries = Atom.of("map_entries"); Atom<List<Entry<String, T>>> mapEntries = Atom.of("map_entries");
rules.put(mapEntries, Term.repeatedWithTrailingSeparator(mapEntryRule, mapEntries, StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)), scope -> scope.getOrThrow(mapEntries)); rules.put(
mapEntries,
Term.repeatedWithTrailingSeparator(
mapEntryRule,
mapEntries,
StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)
),
scope -> scope.getOrThrow(mapEntries)
);
Atom<T> mapLiteral = Atom.of("map_literal"); Atom<T> mapLiteral = Atom.of("map_literal");
rules.put(mapLiteral, Term.sequence(StringReaderTerms.character('{'), Scope.increaseDepth(), rules.named(mapEntries), Scope.decreaseDepth(), StringReaderTerms.character('}')), scope -> { rules.put(
mapLiteral,
Term.sequence(
StringReaderTerms.character('{'),
Scope.increaseDepth(),
rules.named(mapEntries),
Scope.decreaseDepth(),
StringReaderTerms.character('}')
),
scope -> {
List<Entry<String, T>> entries = scope.getOrThrow(mapEntries); List<Entry<String, T>> entries = scope.getOrThrow(mapEntries);
if (entries.isEmpty()) { if (entries.isEmpty()) {
return emptyMapValue; return emptyMapValue;
} }
Builder<T, T> builder = ImmutableMap.builderWithExpectedSize(entries.size()); Builder<T, T> builder = ImmutableMap.builderWithExpectedSize(entries.size());
for (Entry<String, T> e : entries) { for (Entry<String, T> e : entries) {
builder.put(ops.createString(e.getKey()), e.getValue()); builder.put(ops.createString(e.getKey()), e.getValue());
} }
return ops.createMap(builder.buildKeepingLast()); return ops.createMap(builder.buildKeepingLast());
}); }
);
Atom<List<T>> listEntries = Atom.of("list_entries"); Atom<List<T>> listEntries = Atom.of("list_entries");
rules.put( rules.put(
listEntries, Term.repeatedWithTrailingSeparator(rules.forward(literal), listEntries, StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)), scope -> scope.getOrThrow(listEntries) listEntries,
Term.repeatedWithTrailingSeparator(
rules.forward(literal),
listEntries,
StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)
),
scope -> scope.getOrThrow(listEntries)
); );
Atom<ArrayPrefix> arrayPrefix = Atom.of("array_prefix"); Atom<ArrayPrefix> arrayPrefix = Atom.of("array_prefix");
rules.put( rules.put(
arrayPrefix, arrayPrefix,
@@ -588,15 +672,32 @@ public class SnbtGrammar {
), ),
scope -> scope.getOrThrow(arrayPrefix) scope -> scope.getOrThrow(arrayPrefix)
); );
Atom<List<IntegerLiteral>> intArrayEntries = Atom.of("int_array_entries"); Atom<List<IntegerLiteral>> intArrayEntries = Atom.of("int_array_entries");
rules.put(intArrayEntries, Term.repeatedWithTrailingSeparator(integerLiteralRule, intArrayEntries, StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)), scope -> scope.getOrThrow(intArrayEntries)); rules.put(
intArrayEntries,
Term.repeatedWithTrailingSeparator(
integerLiteralRule,
intArrayEntries,
StringReaderTerms.character(TagParser.ELEMENT_SEPARATOR)
),
scope -> scope.getOrThrow(intArrayEntries)
);
Atom<T> listLiteral = Atom.of("list_literal"); Atom<T> listLiteral = Atom.of("list_literal");
rules.putComplex( rules.putComplex(
listLiteral, listLiteral,
Term.sequence( Term.sequence(
StringReaderTerms.character('['), StringReaderTerms.character('['),
Scope.increaseDepth(), Scope.increaseDepth(),
Term.alternative(Term.sequence(rules.named(arrayPrefix), StringReaderTerms.character(';'), rules.named(intArrayEntries)), rules.named(listEntries)), Term.alternative(
Term.sequence(
rules.named(arrayPrefix),
StringReaderTerms.character(';'),
rules.named(intArrayEntries)
),
rules.named(listEntries)
),
Scope.decreaseDepth(), Scope.decreaseDepth(),
StringReaderTerms.character(']') StringReaderTerms.character(']')
), ),
@@ -611,13 +712,32 @@ public class SnbtGrammar {
return entries.isEmpty() ? emptyList : ops.createList(entries.stream()); return entries.isEmpty() ? emptyList : ops.createList(entries.stream());
} }
); );
NamedRule<StringReader, T> literalRule = rules.putComplex( NamedRule<StringReader, T> literalRule = rules.putComplex(
literal, literal,
Term.alternative( Term.alternative(
Term.sequence(Term.positiveLookahead(NUMBER_LOOKEAHEAD), Term.alternative(rules.namedWithAlias(floatLiteral, literal), rules.named(integerLiteral))), Term.sequence(
Term.sequence(Term.positiveLookahead(StringReaderTerms.characters('"', '\'')), Term.cut(), rules.named(quotedStringLiteral)), Term.positiveLookahead(NUMBER_LOOKEAHEAD),
Term.sequence(Term.positiveLookahead(StringReaderTerms.character('{')), Term.cut(), rules.namedWithAlias(mapLiteral, literal)), Term.alternative(
Term.sequence(Term.positiveLookahead(StringReaderTerms.character('[')), Term.cut(), rules.namedWithAlias(listLiteral, literal)), rules.namedWithAlias(floatLiteral, literal),
rules.named(integerLiteral)
)
),
Term.sequence(
Term.positiveLookahead(StringReaderTerms.characters('"', '\'')),
Term.cut(),
rules.named(quotedStringLiteral)
),
Term.sequence(
Term.positiveLookahead(StringReaderTerms.character('{')),
Term.cut(),
rules.namedWithAlias(mapLiteral, literal)
),
Term.sequence(
Term.positiveLookahead(StringReaderTerms.character('[')),
Term.cut(),
rules.namedWithAlias(listLiteral, literal)
),
rules.namedWithAlias(unquotedStringOrBuiltIn, literal) rules.namedWithAlias(unquotedStringOrBuiltIn, literal)
), ),
state -> { state -> {
@@ -630,6 +750,7 @@ public class SnbtGrammar {
return integer != null ? integer.create(ops, state) : scope.getOrThrow(literal); return integer != null ? integer.create(ops, state) : scope.getOrThrow(literal);
} }
); );
return new Grammar<>(rules, literalRule); return new Grammar<>(rules, literalRule);
} }
@@ -646,16 +767,13 @@ public class SnbtGrammar {
@Override @Override
public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) { public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) {
ByteList result = new ByteArrayList(); ByteList result = new ByteArrayList();
for (IntegerLiteral entry : entries) { for (IntegerLiteral entry : entries) {
Number number = this.buildNumber(entry, state); Number number = this.buildNumber(entry, state);
if (number == null) { if (number == null) {
return null; return null;
} }
result.add(number.byteValue()); result.add(number.byteValue());
} }
return ops.createByteList(ByteBuffer.wrap(result.toByteArray())); return ops.createByteList(ByteBuffer.wrap(result.toByteArray()));
} }
}, },
@@ -669,16 +787,13 @@ public class SnbtGrammar {
@Override @Override
public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) { public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) {
IntStream.Builder result = IntStream.builder(); IntStream.Builder result = IntStream.builder();
for (IntegerLiteral entry : entries) { for (IntegerLiteral entry : entries) {
Number parsedNumber = this.buildNumber(entry, state); Number parsedNumber = this.buildNumber(entry, state);
if (parsedNumber == null) { if (parsedNumber == null) {
return null; return null;
} }
result.add(parsedNumber.intValue()); result.add(parsedNumber.intValue());
} }
return ops.createIntList(result.build()); return ops.createIntList(result.build());
} }
}, },
@@ -692,16 +807,13 @@ public class SnbtGrammar {
@Override @Override
public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) { public <T> T create(DynamicOps<T> ops, List<IntegerLiteral> entries, ParseState<?> state) {
LongStream.Builder result = LongStream.builder(); LongStream.Builder result = LongStream.builder();
for (IntegerLiteral entry : entries) { for (IntegerLiteral entry : entries) {
Number parsedNumber = this.buildNumber(entry, state); Number parsedNumber = this.buildNumber(entry, state);
if (parsedNumber == null) { if (parsedNumber == null) {
return null; return null;
} }
result.add(parsedNumber.longValue()); result.add(parsedNumber.longValue());
} }
return ops.createLongList(result.build()); return ops.createLongList(result.build());
} }
}; };
@@ -717,7 +829,6 @@ public class SnbtGrammar {
public boolean isAllowed(TypeSuffix type) { public boolean isAllowed(TypeSuffix type) {
return type == this.defaultType || this.additionalTypes.contains(type); return type == this.defaultType || this.additionalTypes.contains(type);
} }
public abstract <T> T create(DynamicOps<T> ops); public abstract <T> T create(DynamicOps<T> ops);
@Nullable @Nullable
@@ -742,7 +853,6 @@ public class SnbtGrammar {
return !this.isAllowed(type) ? null : type; return !this.isAllowed(type) ? null : type;
} }
} }
enum Base { enum Base {
BINARY, BINARY,
DECIMAL, DECIMAL,

View File

@@ -10,7 +10,7 @@ import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
public class LocalizedCommandSyntaxException extends CommandSyntaxException { public class LocalizedCommandSyntaxException extends CommandSyntaxException {
public static final int CONTEXT_AMOUNT = 10; public static final int CONTEXT_AMOUNT = 50;
public static final String PARSE_ERROR_NODE = "warning.config.type.snbt.invalid_syntax.parse_error"; public static final String PARSE_ERROR_NODE = "warning.config.type.snbt.invalid_syntax.parse_error";
public static final String HERE_NODE = "warning.config.type.snbt.invalid_syntax.here"; public static final String HERE_NODE = "warning.config.type.snbt.invalid_syntax.here";
private final Message message; private final Message message;