implements PR-11.4
This commit is contained in:
parent
ea44d40410
commit
eb5cecc573
@ -17,6 +17,7 @@ final class PbsExprControlFlowParser {
|
|||||||
private final PbsTokenCursor cursor;
|
private final PbsTokenCursor cursor;
|
||||||
private final ExpressionParserDelegate expressionParserDelegate;
|
private final ExpressionParserDelegate expressionParserDelegate;
|
||||||
private final ExpressionParserDelegate precedenceParserDelegate;
|
private final ExpressionParserDelegate precedenceParserDelegate;
|
||||||
|
private final PbsExprLiteralSupport literalSupport;
|
||||||
|
|
||||||
PbsExprControlFlowParser(
|
PbsExprControlFlowParser(
|
||||||
final PbsExprParserContext context,
|
final PbsExprParserContext context,
|
||||||
@ -26,6 +27,7 @@ final class PbsExprControlFlowParser {
|
|||||||
this.cursor = context.cursor();
|
this.cursor = context.cursor();
|
||||||
this.expressionParserDelegate = expressionParserDelegate;
|
this.expressionParserDelegate = expressionParserDelegate;
|
||||||
this.precedenceParserDelegate = precedenceParserDelegate;
|
this.precedenceParserDelegate = precedenceParserDelegate;
|
||||||
|
this.literalSupport = new PbsExprLiteralSupport(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
PbsAst.Expression parseHandle() {
|
PbsAst.Expression parseHandle() {
|
||||||
@ -173,32 +175,7 @@ final class PbsExprControlFlowParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PbsAst.Expression parseLiteralPatternExpression() {
|
PbsAst.Expression parseLiteralPatternExpression() {
|
||||||
if (cursor.match(PbsTokenKind.TRUE)) {
|
return literalSupport.parseLiteralExpression();
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.BoolLiteralExpr(true, context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.FALSE)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.BoolLiteralExpr(false, context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.INT_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.IntLiteralExpr(parseLongOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.FLOAT_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.FloatLiteralExpr(parseDoubleOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.BOUNDED_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
final var raw = token.lexeme().substring(0, Math.max(token.lexeme().length() - 1, 0));
|
|
||||||
return new PbsAst.BoundedLiteralExpr(parseIntOrDefault(raw), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.STRING_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.StringLiteralExpr(unescapeString(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PbsAst.HandlePattern parseHandlePattern() {
|
PbsAst.HandlePattern parseHandlePattern() {
|
||||||
@ -233,52 +210,4 @@ final class PbsExprControlFlowParser {
|
|||||||
return new PbsAst.ErrorPath(ReadOnlyList.wrap(segments), context.span(first.start(), end));
|
return new PbsAst.ErrorPath(ReadOnlyList.wrap(segments), context.span(first.start(), end));
|
||||||
}
|
}
|
||||||
|
|
||||||
private long parseLongOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Long.parseLong(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int parseIntOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private double parseDoubleOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Double.parseDouble(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String unescapeString(final String lexeme) {
|
|
||||||
if (lexeme.length() < 2) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
final var raw = lexeme.substring(1, lexeme.length() - 1);
|
|
||||||
final var sb = new StringBuilder(raw.length());
|
|
||||||
for (int i = 0; i < raw.length(); i++) {
|
|
||||||
final char c = raw.charAt(i);
|
|
||||||
if (c != '\\' || i + 1 >= raw.length()) {
|
|
||||||
sb.append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final char next = raw.charAt(++i);
|
|
||||||
switch (next) {
|
|
||||||
case 'n' -> sb.append('\n');
|
|
||||||
case 'r' -> sb.append('\r');
|
|
||||||
case 't' -> sb.append('\t');
|
|
||||||
case '"' -> sb.append('"');
|
|
||||||
case '\\' -> sb.append('\\');
|
|
||||||
default -> sb.append('\\').append(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,92 @@
|
|||||||
|
package p.studio.compiler.pbs.parser;
|
||||||
|
|
||||||
|
import p.studio.compiler.pbs.ast.PbsAst;
|
||||||
|
import p.studio.compiler.pbs.lexer.PbsTokenKind;
|
||||||
|
|
||||||
|
final class PbsExprLiteralSupport {
|
||||||
|
private final PbsExprParserContext context;
|
||||||
|
private final PbsTokenCursor cursor;
|
||||||
|
|
||||||
|
PbsExprLiteralSupport(final PbsExprParserContext context) {
|
||||||
|
this.context = context;
|
||||||
|
this.cursor = context.cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
PbsAst.Expression parseLiteralExpression() {
|
||||||
|
if (cursor.match(PbsTokenKind.TRUE)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
return new PbsAst.BoolLiteralExpr(true, context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
if (cursor.match(PbsTokenKind.FALSE)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
return new PbsAst.BoolLiteralExpr(false, context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
if (cursor.match(PbsTokenKind.INT_LITERAL)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
return new PbsAst.IntLiteralExpr(parseLongOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
if (cursor.match(PbsTokenKind.FLOAT_LITERAL)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
return new PbsAst.FloatLiteralExpr(parseDoubleOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
if (cursor.match(PbsTokenKind.BOUNDED_LITERAL)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
final var raw = token.lexeme().substring(0, Math.max(token.lexeme().length() - 1, 0));
|
||||||
|
return new PbsAst.BoundedLiteralExpr(parseIntOrDefault(raw), context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
if (cursor.match(PbsTokenKind.STRING_LITERAL)) {
|
||||||
|
final var token = cursor.previous();
|
||||||
|
return new PbsAst.StringLiteralExpr(unescapeString(token.lexeme()), context.span(token.start(), token.end()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long parseLongOrDefault(final String text) {
|
||||||
|
try {
|
||||||
|
return Long.parseLong(text);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int parseIntOrDefault(final String text) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(text);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double parseDoubleOrDefault(final String text) {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(text);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unescapeString(final String lexeme) {
|
||||||
|
if (lexeme.length() < 2) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final var raw = lexeme.substring(1, lexeme.length() - 1);
|
||||||
|
final var sb = new StringBuilder(raw.length());
|
||||||
|
for (int i = 0; i < raw.length(); i++) {
|
||||||
|
final char c = raw.charAt(i);
|
||||||
|
if (c != '\\' || i + 1 >= raw.length()) {
|
||||||
|
sb.append(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final char next = raw.charAt(++i);
|
||||||
|
switch (next) {
|
||||||
|
case 'n' -> sb.append('\n');
|
||||||
|
case 'r' -> sb.append('\r');
|
||||||
|
case 't' -> sb.append('\t');
|
||||||
|
case '"' -> sb.append('"');
|
||||||
|
case '\\' -> sb.append('\\');
|
||||||
|
default -> sb.append('\\').append(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@ final class PbsExprPrimaryParser {
|
|||||||
private final PbsTokenCursor cursor;
|
private final PbsTokenCursor cursor;
|
||||||
private final ExpressionParserDelegate expressionParserDelegate;
|
private final ExpressionParserDelegate expressionParserDelegate;
|
||||||
private final ErrorPathParserDelegate errorPathParserDelegate;
|
private final ErrorPathParserDelegate errorPathParserDelegate;
|
||||||
|
private final PbsExprLiteralSupport literalSupport;
|
||||||
|
|
||||||
PbsExprPrimaryParser(
|
PbsExprPrimaryParser(
|
||||||
final PbsExprParserContext context,
|
final PbsExprParserContext context,
|
||||||
@ -33,6 +34,7 @@ final class PbsExprPrimaryParser {
|
|||||||
this.cursor = context.cursor();
|
this.cursor = context.cursor();
|
||||||
this.expressionParserDelegate = expressionParserDelegate;
|
this.expressionParserDelegate = expressionParserDelegate;
|
||||||
this.errorPathParserDelegate = errorPathParserDelegate;
|
this.errorPathParserDelegate = errorPathParserDelegate;
|
||||||
|
this.literalSupport = new PbsExprLiteralSupport(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
PbsAst.Expression parsePostfix() {
|
PbsAst.Expression parsePostfix() {
|
||||||
@ -79,30 +81,9 @@ final class PbsExprPrimaryParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PbsAst.Expression parsePrimary() {
|
PbsAst.Expression parsePrimary() {
|
||||||
if (cursor.match(PbsTokenKind.TRUE)) {
|
final var literal = literalSupport.parseLiteralExpression();
|
||||||
final var token = cursor.previous();
|
if (literal != null) {
|
||||||
return new PbsAst.BoolLiteralExpr(true, context.span(token.start(), token.end()));
|
return literal;
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.FALSE)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.BoolLiteralExpr(false, context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.INT_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.IntLiteralExpr(parseLongOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.FLOAT_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.FloatLiteralExpr(parseDoubleOrDefault(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.BOUNDED_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
final var raw = token.lexeme().substring(0, Math.max(token.lexeme().length() - 1, 0));
|
|
||||||
return new PbsAst.BoundedLiteralExpr(parseIntOrDefault(raw), context.span(token.start(), token.end()));
|
|
||||||
}
|
|
||||||
if (cursor.match(PbsTokenKind.STRING_LITERAL)) {
|
|
||||||
final var token = cursor.previous();
|
|
||||||
return new PbsAst.StringLiteralExpr(unescapeString(token.lexeme()), context.span(token.start(), token.end()));
|
|
||||||
}
|
}
|
||||||
if (cursor.match(PbsTokenKind.THIS)) {
|
if (cursor.match(PbsTokenKind.THIS)) {
|
||||||
final var token = cursor.previous();
|
final var token = cursor.previous();
|
||||||
@ -288,52 +269,4 @@ final class PbsExprPrimaryParser {
|
|||||||
return new PbsAst.ErrExpr(errorPath, context.span(errToken.start(), close.end()));
|
return new PbsAst.ErrExpr(errorPath, context.span(errToken.start(), close.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private long parseLongOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Long.parseLong(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int parseIntOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private double parseDoubleOrDefault(final String text) {
|
|
||||||
try {
|
|
||||||
return Double.parseDouble(text);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String unescapeString(final String lexeme) {
|
|
||||||
if (lexeme.length() < 2) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
final var raw = lexeme.substring(1, lexeme.length() - 1);
|
|
||||||
final var sb = new StringBuilder(raw.length());
|
|
||||||
for (int i = 0; i < raw.length(); i++) {
|
|
||||||
final char c = raw.charAt(i);
|
|
||||||
if (c != '\\' || i + 1 >= raw.length()) {
|
|
||||||
sb.append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final char next = raw.charAt(++i);
|
|
||||||
switch (next) {
|
|
||||||
case 'n' -> sb.append('\n');
|
|
||||||
case 'r' -> sb.append('\r');
|
|
||||||
case 't' -> sb.append('\t');
|
|
||||||
case '"' -> sb.append('"');
|
|
||||||
case '\\' -> sb.append('\\');
|
|
||||||
default -> sb.append('\\').append(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user