From eb5cecc57324cac82dec2961b168028745a8f3b8 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 10 Mar 2026 09:58:07 +0000 Subject: [PATCH] implements PR-11.4 --- .../pbs/parser/PbsExprControlFlowParser.java | 77 +--------------- .../pbs/parser/PbsExprLiteralSupport.java | 92 +++++++++++++++++++ .../pbs/parser/PbsExprPrimaryParser.java | 77 +--------------- 3 files changed, 100 insertions(+), 146 deletions(-) create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprLiteralSupport.java diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprControlFlowParser.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprControlFlowParser.java index 093e52cf..1ed2b863 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprControlFlowParser.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprControlFlowParser.java @@ -17,6 +17,7 @@ final class PbsExprControlFlowParser { private final PbsTokenCursor cursor; private final ExpressionParserDelegate expressionParserDelegate; private final ExpressionParserDelegate precedenceParserDelegate; + private final PbsExprLiteralSupport literalSupport; PbsExprControlFlowParser( final PbsExprParserContext context, @@ -26,6 +27,7 @@ final class PbsExprControlFlowParser { this.cursor = context.cursor(); this.expressionParserDelegate = expressionParserDelegate; this.precedenceParserDelegate = precedenceParserDelegate; + this.literalSupport = new PbsExprLiteralSupport(context); } PbsAst.Expression parseHandle() { @@ -173,32 +175,7 @@ final class PbsExprControlFlowParser { } PbsAst.Expression parseLiteralPatternExpression() { - 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; + return literalSupport.parseLiteralExpression(); } PbsAst.HandlePattern parseHandlePattern() { @@ -233,52 +210,4 @@ final class PbsExprControlFlowParser { 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(); - } } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprLiteralSupport.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprLiteralSupport.java new file mode 100644 index 00000000..27af3855 --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprLiteralSupport.java @@ -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(); + } +} diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprPrimaryParser.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprPrimaryParser.java index d0f249ff..e2377fb2 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprPrimaryParser.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/parser/PbsExprPrimaryParser.java @@ -24,6 +24,7 @@ final class PbsExprPrimaryParser { private final PbsTokenCursor cursor; private final ExpressionParserDelegate expressionParserDelegate; private final ErrorPathParserDelegate errorPathParserDelegate; + private final PbsExprLiteralSupport literalSupport; PbsExprPrimaryParser( final PbsExprParserContext context, @@ -33,6 +34,7 @@ final class PbsExprPrimaryParser { this.cursor = context.cursor(); this.expressionParserDelegate = expressionParserDelegate; this.errorPathParserDelegate = errorPathParserDelegate; + this.literalSupport = new PbsExprLiteralSupport(context); } PbsAst.Expression parsePostfix() { @@ -79,30 +81,9 @@ final class PbsExprPrimaryParser { } PbsAst.Expression parsePrimary() { - 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())); + final var literal = literalSupport.parseLiteralExpression(); + if (literal != null) { + return literal; } if (cursor.match(PbsTokenKind.THIS)) { final var token = cursor.previous(); @@ -288,52 +269,4 @@ final class PbsExprPrimaryParser { 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(); - } }