mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
格式化
This commit is contained in:
@@ -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,152 +248,151 @@ 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,
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(StringReaderTerms.character('+'), Term.marker(sign, Sign.PLUS)),
|
Term.sequence(StringReaderTerms.character('+'), Term.marker(sign, Sign.PLUS)),
|
||||||
Term.sequence(StringReaderTerms.character('-'), Term.marker(sign, Sign.MINUS))
|
Term.sequence(StringReaderTerms.character('-'), Term.marker(sign, Sign.MINUS))
|
||||||
),
|
),
|
||||||
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,
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(
|
|
||||||
StringReaderTerms.characters('u', 'U'),
|
|
||||||
Term.alternative(
|
|
||||||
Term.sequence(
|
Term.sequence(
|
||||||
StringReaderTerms.characters('b', 'B'),
|
StringReaderTerms.characters('u', 'U'),
|
||||||
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.BYTE))
|
Term.alternative(
|
||||||
|
Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.BYTE))),
|
||||||
|
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.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.SHORT))
|
Term.alternative(
|
||||||
|
Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.BYTE))),
|
||||||
|
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(
|
Term.sequence(StringReaderTerms.characters('b', 'B'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.BYTE))),
|
||||||
StringReaderTerms.characters('i', 'I'),
|
Term.sequence(StringReaderTerms.characters('s', 'S'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.SHORT))),
|
||||||
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.INT))
|
Term.sequence(StringReaderTerms.characters('i', 'I'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.INT))),
|
||||||
),
|
Term.sequence(StringReaderTerms.characters('l', 'L'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.LONG)))
|
||||||
Term.sequence(
|
|
||||||
StringReaderTerms.characters('l', 'L'),
|
|
||||||
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.UNSIGNED, TypeSuffix.LONG))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
Term.sequence(
|
|
||||||
StringReaderTerms.characters('s', 'S'),
|
|
||||||
Term.alternative(
|
|
||||||
Term.sequence(
|
|
||||||
StringReaderTerms.characters('b', 'B'),
|
|
||||||
Term.marker(integerSuffix, new IntegerSuffix(SignedPrefix.SIGNED, TypeSuffix.BYTE))
|
|
||||||
),
|
|
||||||
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('s', 'S'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.SHORT))),
|
|
||||||
Term.sequence(StringReaderTerms.characters('i', 'I'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.INT))),
|
|
||||||
Term.sequence(StringReaderTerms.characters('l', 'L'), Term.marker(integerSuffix, new IntegerSuffix(null, TypeSuffix.LONG)))
|
|
||||||
),
|
|
||||||
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,
|
||||||
Term.sequence(
|
Term.sequence(
|
||||||
Term.optional(rules.named(sign)),
|
Term.optional(rules.named(sign)),
|
||||||
Term.alternative(
|
|
||||||
Term.sequence(
|
|
||||||
StringReaderTerms.character('0'),
|
|
||||||
Term.cut(),
|
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(StringReaderTerms.characters('x', 'X'), Term.cut(), rules.named(hexNumeral)),
|
Term.sequence(
|
||||||
Term.sequence(StringReaderTerms.characters('b', 'B'), rules.named(binaryNumeral)),
|
StringReaderTerms.character('0'),
|
||||||
Term.sequence(rules.named(decimalNumeral), Term.cut(), Term.fail(ERROR_LEADING_ZERO_NOT_ALLOWED)),
|
Term.cut(),
|
||||||
Term.marker(decimalNumeral, "0")
|
Term.alternative(
|
||||||
)
|
Term.sequence(StringReaderTerms.characters('x', 'X'), Term.cut(), rules.named(hexNumeral)),
|
||||||
),
|
Term.sequence(StringReaderTerms.characters('b', 'B'), rules.named(binaryNumeral)),
|
||||||
rules.named(decimalNumeral)
|
Term.sequence(rules.named(decimalNumeral), Term.cut(), Term.fail(ERROR_LEADING_ZERO_NOT_ALLOWED)),
|
||||||
|
Term.marker(decimalNumeral, "0")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
rules.named(decimalNumeral)
|
||||||
|
),
|
||||||
|
Term.optional(rules.named(integerSuffix))
|
||||||
),
|
),
|
||||||
Term.optional(rules.named(integerSuffix))
|
scope -> {
|
||||||
),
|
IntegerSuffix suffix = scope.getOrDefault(integerSuffix, IntegerSuffix.EMPTY);
|
||||||
scope -> {
|
Sign signValue = scope.getOrDefault(sign, Sign.PLUS);
|
||||||
IntegerSuffix suffix = scope.getOrDefault(integerSuffix, IntegerSuffix.EMPTY);
|
String decimalContents = scope.get(decimalNumeral);
|
||||||
Sign signValue = scope.getOrDefault(sign, Sign.PLUS);
|
if (decimalContents != null) {
|
||||||
String decimalContents = scope.get(decimalNumeral);
|
return new IntegerLiteral(signValue, Base.DECIMAL, decimalContents, suffix);
|
||||||
if (decimalContents != null) {
|
}
|
||||||
return new IntegerLiteral(signValue, Base.DECIMAL, decimalContents, suffix);
|
String hexContents = scope.get(hexNumeral);
|
||||||
|
if (hexContents != null) {
|
||||||
|
return new IntegerLiteral(signValue, Base.HEX, hexContents, suffix);
|
||||||
|
}
|
||||||
|
String binaryContents = scope.getOrThrow(binaryNumeral);
|
||||||
|
return new IntegerLiteral(signValue, Base.BINARY, binaryContents, suffix);
|
||||||
}
|
}
|
||||||
String string1 = scope.get(hexNumeral);
|
|
||||||
if (string1 != null) {
|
|
||||||
return new IntegerLiteral(signValue, Base.HEX, string1, suffix);
|
|
||||||
}
|
|
||||||
String string2 = scope.getOrThrow(binaryNumeral);
|
|
||||||
return new IntegerLiteral(signValue, Base.BINARY, string2, suffix);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Atom<TypeSuffix> floatTypeSuffix = Atom.of("float_type_suffix");
|
Atom<TypeSuffix> floatTypeSuffix = Atom.of("float_type_suffix");
|
||||||
rules.put(
|
rules.put(
|
||||||
floatTypeSuffix,
|
floatTypeSuffix,
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(StringReaderTerms.characters('f', 'F'), Term.marker(floatTypeSuffix, TypeSuffix.FLOAT)),
|
Term.sequence(StringReaderTerms.characters('f', 'F'), Term.marker(floatTypeSuffix, TypeSuffix.FLOAT)),
|
||||||
Term.sequence(StringReaderTerms.characters('d', 'D'), Term.marker(floatTypeSuffix, TypeSuffix.DOUBLE))
|
Term.sequence(StringReaderTerms.characters('d', 'D'), Term.marker(floatTypeSuffix, TypeSuffix.DOUBLE))
|
||||||
),
|
),
|
||||||
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");
|
||||||
rules.putComplex(
|
rules.putComplex(
|
||||||
floatLiteral,
|
floatLiteral,
|
||||||
Term.sequence(
|
Term.sequence(
|
||||||
Term.optional(rules.named(sign)),
|
Term.optional(rules.named(sign)),
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(
|
Term.sequence(
|
||||||
rules.namedWithAlias(decimalNumeral, floatWholePart),
|
rules.namedWithAlias(decimalNumeral, floatWholePart),
|
||||||
StringReaderTerms.character('.'),
|
StringReaderTerms.character('.'),
|
||||||
Term.cut(),
|
Term.cut(),
|
||||||
Term.optional(rules.namedWithAlias(decimalNumeral, floatFractionPart)),
|
Term.optional(rules.namedWithAlias(decimalNumeral, floatFractionPart)),
|
||||||
Term.optional(rules.named(floatExponentPart)),
|
Term.optional(rules.named(floatExponentPart)),
|
||||||
Term.optional(rules.named(floatTypeSuffix))
|
Term.optional(rules.named(floatTypeSuffix))
|
||||||
),
|
),
|
||||||
Term.sequence(
|
Term.sequence(
|
||||||
StringReaderTerms.character('.'),
|
StringReaderTerms.character('.'),
|
||||||
Term.cut(),
|
Term.cut(),
|
||||||
rules.namedWithAlias(decimalNumeral, floatFractionPart),
|
rules.namedWithAlias(decimalNumeral, floatFractionPart),
|
||||||
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 -> {
|
||||||
Scope scope = state.scope();
|
Scope scope = state.scope();
|
||||||
Sign wholeSign = scope.getOrDefault(sign, Sign.PLUS);
|
Sign wholeSign = scope.getOrDefault(sign, Sign.PLUS);
|
||||||
@@ -402,116 +401,160 @@ public class SnbtGrammar {
|
|||||||
Signed<String> exponent = scope.get(floatExponentPart);
|
Signed<String> exponent = scope.get(floatExponentPart);
|
||||||
TypeSuffix typeSuffix = scope.get(floatTypeSuffix);
|
TypeSuffix typeSuffix = scope.get(floatTypeSuffix);
|
||||||
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,
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(StringReaderTerms.character('b'), Term.marker(stringEscapeSequence, "\b")),
|
Term.sequence(StringReaderTerms.character('b'), Term.marker(stringEscapeSequence, "\b")),
|
||||||
Term.sequence(StringReaderTerms.character('s'), Term.marker(stringEscapeSequence, " ")),
|
Term.sequence(StringReaderTerms.character('s'), Term.marker(stringEscapeSequence, " ")),
|
||||||
Term.sequence(StringReaderTerms.character('t'), Term.marker(stringEscapeSequence, "\t")),
|
Term.sequence(StringReaderTerms.character('t'), Term.marker(stringEscapeSequence, "\t")),
|
||||||
Term.sequence(StringReaderTerms.character('n'), Term.marker(stringEscapeSequence, "\n")),
|
Term.sequence(StringReaderTerms.character('n'), Term.marker(stringEscapeSequence, "\n")),
|
||||||
Term.sequence(StringReaderTerms.character('f'), Term.marker(stringEscapeSequence, "\f")),
|
Term.sequence(StringReaderTerms.character('f'), Term.marker(stringEscapeSequence, "\f")),
|
||||||
Term.sequence(StringReaderTerms.character('r'), Term.marker(stringEscapeSequence, "\r")),
|
Term.sequence(StringReaderTerms.character('r'), Term.marker(stringEscapeSequence, "\r")),
|
||||||
Term.sequence(StringReaderTerms.character('\\'), Term.marker(stringEscapeSequence, "\\")),
|
Term.sequence(StringReaderTerms.character('\\'), Term.marker(stringEscapeSequence, "\\")),
|
||||||
Term.sequence(StringReaderTerms.character('\''), Term.marker(stringEscapeSequence, "'")),
|
Term.sequence(StringReaderTerms.character('\''), Term.marker(stringEscapeSequence, "'")),
|
||||||
Term.sequence(StringReaderTerms.character('"'), Term.marker(stringEscapeSequence, "\"")),
|
Term.sequence(StringReaderTerms.character('"'), Term.marker(stringEscapeSequence, "\"")),
|
||||||
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();
|
||||||
String plainEscape = scope.getAny(stringEscapeSequence);
|
String plainEscape = scope.getAny(stringEscapeSequence);
|
||||||
if (plainEscape != null) {
|
if (plainEscape != null) {
|
||||||
return plainEscape;
|
return plainEscape;
|
||||||
}
|
}
|
||||||
String hexEscape = scope.getAny(stringHex2, stringHex4, stringHex8);
|
String hexEscape = scope.getAny(stringHex2, stringHex4, stringHex8);
|
||||||
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);
|
||||||
}
|
}
|
||||||
String character = scope.getOrThrow(stringUnicodeName);
|
String character = scope.getOrThrow(stringUnicodeName);
|
||||||
|
|
||||||
int codePoint;
|
int codePoint;
|
||||||
try {
|
try {
|
||||||
codePoint = Character.codePointOf(character);
|
codePoint = Character.codePointOf(character);
|
||||||
} catch (IllegalArgumentException var12x) {
|
} catch (IllegalArgumentException var12x) {
|
||||||
state.errorCollector().store(state.mark(), ERROR_INVALID_CHARACTER_NAME);
|
state.errorCollector().store(state.mark(), ERROR_INVALID_CHARACTER_NAME);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
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),
|
||||||
Term.sequence(StringReaderTerms.character('\\'), rules.namedWithAlias(stringEscapeSequence, stringContents)),
|
Term.sequence(StringReaderTerms.character('\\'), rules.namedWithAlias(stringEscapeSequence, stringContents)),
|
||||||
Term.sequence(StringReaderTerms.character('"'), Term.marker(stringContents, "\""))
|
Term.sequence(StringReaderTerms.character('"'), Term.marker(stringContents, "\""))
|
||||||
),
|
),
|
||||||
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),
|
||||||
Term.sequence(StringReaderTerms.character('\\'), rules.namedWithAlias(stringEscapeSequence, stringContents)),
|
Term.sequence(StringReaderTerms.character('\\'), rules.namedWithAlias(stringEscapeSequence, stringContents)),
|
||||||
Term.sequence(StringReaderTerms.character('\''), Term.marker(stringContents, "'"))
|
Term.sequence(StringReaderTerms.character('\''), Term.marker(stringContents, "'"))
|
||||||
),
|
),
|
||||||
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();
|
||||||
String contents = scope.getOrThrow(unquotedString);
|
String contents = scope.getOrThrow(unquotedString);
|
||||||
@@ -522,114 +565,192 @@ public class SnbtGrammar {
|
|||||||
SnbtOperations.BuiltinOperation operation = SnbtOperations.BUILTIN_OPERATIONS.get(key);
|
SnbtOperations.BuiltinOperation operation = SnbtOperations.BUILTIN_OPERATIONS.get(key);
|
||||||
if (operation != null) {
|
if (operation != null) {
|
||||||
return operation.run(ops, arguments, state);
|
return operation.run(ops, arguments, state);
|
||||||
}
|
}
|
||||||
state.errorCollector().store(state.mark(), DelayedException.create(ERROR_NO_SUCH_OPERATION, key.toString()));
|
state.errorCollector().store(state.mark(), DelayedException.create(ERROR_NO_SUCH_OPERATION, key.toString()));
|
||||||
return null;
|
return null;
|
||||||
} else if (contents.equalsIgnoreCase("true")) {
|
} else if (contents.equalsIgnoreCase("true")) {
|
||||||
return trueValue;
|
return trueValue;
|
||||||
} else if (contents.equalsIgnoreCase("false")) {
|
} else if (contents.equalsIgnoreCase("false")) {
|
||||||
return falseValue;
|
return falseValue;
|
||||||
} else if (contents.equalsIgnoreCase("null")) {
|
} else if (contents.equalsIgnoreCase("null")) {
|
||||||
return Objects.requireNonNullElseGet(ops.empty(), () -> {
|
return Objects.requireNonNullElseGet(ops.empty(), () -> {
|
||||||
if (isJavaType) {
|
if (isJavaType) {
|
||||||
return (T) CachedParseState.JAVA_NULL_VALUE_MARKER;
|
return (T) CachedParseState.JAVA_NULL_VALUE_MARKER;
|
||||||
}
|
}
|
||||||
return nullString;
|
return nullString;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return ops.createString(contents);
|
return ops.createString(contents);
|
||||||
}
|
}
|
||||||
state.errorCollector().store(state.mark(), SnbtOperations.BUILTIN_IDS, ERROR_INVALID_UNQUOTED_START);
|
state.errorCollector().store(state.mark(), SnbtOperations.BUILTIN_IDS, ERROR_INVALID_UNQUOTED_START);
|
||||||
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()) {
|
||||||
state.errorCollector().store(state.mark(), ERROR_EMPTY_KEY);
|
state.errorCollector().store(state.mark(), ERROR_EMPTY_KEY);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
T value = scope.getOrThrow(literal);
|
T value = scope.getOrThrow(literal);
|
||||||
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(
|
||||||
List<Entry<String, T>> entries = scope.getOrThrow(mapEntries);
|
mapLiteral,
|
||||||
if (entries.isEmpty()) {
|
Term.sequence(
|
||||||
return emptyMapValue;
|
StringReaderTerms.character('{'),
|
||||||
}
|
Scope.increaseDepth(),
|
||||||
Builder<T, T> builder = ImmutableMap.builderWithExpectedSize(entries.size());
|
rules.named(mapEntries),
|
||||||
|
Scope.decreaseDepth(),
|
||||||
|
StringReaderTerms.character('}')
|
||||||
|
),
|
||||||
|
scope -> {
|
||||||
|
List<Entry<String, T>> entries = scope.getOrThrow(mapEntries);
|
||||||
|
if (entries.isEmpty()) {
|
||||||
|
return emptyMapValue;
|
||||||
|
}
|
||||||
|
Builder<T, T> builder = ImmutableMap.builderWithExpectedSize(entries.size());
|
||||||
|
for (Entry<String, T> e : entries) {
|
||||||
|
builder.put(ops.createString(e.getKey()), e.getValue());
|
||||||
|
}
|
||||||
|
return ops.createMap(builder.buildKeepingLast());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
for (Entry<String, T> e : entries) {
|
|
||||||
builder.put(ops.createString(e.getKey()), e.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
||||||
Term.alternative(
|
Term.alternative(
|
||||||
Term.sequence(StringReaderTerms.character('B'), Term.marker(arrayPrefix, ArrayPrefix.BYTE)),
|
Term.sequence(StringReaderTerms.character('B'), Term.marker(arrayPrefix, ArrayPrefix.BYTE)),
|
||||||
Term.sequence(StringReaderTerms.character('L'), Term.marker(arrayPrefix, ArrayPrefix.LONG)),
|
Term.sequence(StringReaderTerms.character('L'), Term.marker(arrayPrefix, ArrayPrefix.LONG)),
|
||||||
Term.sequence(StringReaderTerms.character('I'), Term.marker(arrayPrefix, ArrayPrefix.INT))
|
Term.sequence(StringReaderTerms.character('I'), Term.marker(arrayPrefix, ArrayPrefix.INT))
|
||||||
),
|
),
|
||||||
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(
|
||||||
Scope.decreaseDepth(),
|
Term.sequence(
|
||||||
StringReaderTerms.character(']')
|
rules.named(arrayPrefix),
|
||||||
),
|
StringReaderTerms.character(';'),
|
||||||
|
rules.named(intArrayEntries)
|
||||||
|
),
|
||||||
|
rules.named(listEntries)
|
||||||
|
),
|
||||||
|
Scope.decreaseDepth(),
|
||||||
|
StringReaderTerms.character(']')
|
||||||
|
),
|
||||||
state -> {
|
state -> {
|
||||||
Scope scope = state.scope();
|
Scope scope = state.scope();
|
||||||
ArrayPrefix arrayType = scope.get(arrayPrefix);
|
ArrayPrefix arrayType = scope.get(arrayPrefix);
|
||||||
if (arrayType != null) {
|
if (arrayType != null) {
|
||||||
List<IntegerLiteral> entries = scope.getOrThrow(intArrayEntries);
|
List<IntegerLiteral> entries = scope.getOrThrow(intArrayEntries);
|
||||||
return entries.isEmpty() ? arrayType.create(ops) : arrayType.create(ops, entries, state);
|
return entries.isEmpty() ? arrayType.create(ops) : arrayType.create(ops, entries, state);
|
||||||
}
|
}
|
||||||
List<T> entries = scope.getOrThrow(listEntries);
|
List<T> entries = scope.getOrThrow(listEntries);
|
||||||
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.namedWithAlias(unquotedStringOrBuiltIn, 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)
|
||||||
|
),
|
||||||
state -> {
|
state -> {
|
||||||
Scope scope = state.scope();
|
Scope scope = state.scope();
|
||||||
String quotedString = scope.get(quotedStringLiteral);
|
String quotedString = scope.get(quotedStringLiteral);
|
||||||
if (quotedString != null) {
|
if (quotedString != null) {
|
||||||
return ops.createString(quotedString);
|
return ops.createString(quotedString);
|
||||||
}
|
}
|
||||||
IntegerLiteral integer = scope.get(integerLiteral);
|
IntegerLiteral integer = scope.get(integerLiteral);
|
||||||
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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user