From 94a32b232f8faacd174087db9466504a670f024a Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Thu, 18 Dec 2025 15:58:41 +0100 Subject: [PATCH] Fix parsing of %{EXPR} and @{EXPR} as hash/array dereferences Previously, %{expr} was incorrectly parsed as an infix modulo operator when used as an argument to functions like 'say'. For example: say %{sub {{ a => 3 }}->()} was parsed as (say ) % {hash_literal} instead of say(%{sub...->()}). The fix adds '{' to the lookahead check in looksLikeEmptyList() so that %{...} and @{...} are recognized as hash/array dereferences rather than infix operators. This is needed for JPERL_LARGECODE=refactor which generates constructs like %{sub{...}->()}. --- src/main/java/org/perlonjava/parser/ListParser.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/perlonjava/parser/ListParser.java b/src/main/java/org/perlonjava/parser/ListParser.java index 334e72065..6e8aeed4b 100644 --- a/src/main/java/org/perlonjava/parser/ListParser.java +++ b/src/main/java/org/perlonjava/parser/ListParser.java @@ -329,9 +329,13 @@ public static boolean looksLikeEmptyList(Parser parser) { } else if (token.text.equals("&")) { // Looks like a subroutine call, not an infix `&` parser.ctx.logDebug("parseZeroOrMoreList looks like subroutine call"); - } else if (token.text.equals("%") && (nextToken.text.equals("$") || nextToken.type == LexerTokenType.IDENTIFIER)) { + } else if (token.text.equals("%") && (nextToken.text.equals("$") || nextToken.text.equals("{") || nextToken.type == LexerTokenType.IDENTIFIER)) { // Looks like a hash deref, not an infix `%` - parser.ctx.logDebug("parseZeroOrMoreList looks like Hash"); + // %$ref, %{expr}, %hash + parser.ctx.logDebug("parseZeroOrMoreList looks like Hash: token=" + token.text + " nextToken=" + nextToken.text); + } else if (token.text.equals("@") && nextToken.text.equals("{")) { + // Looks like an array deref @{expr}, not an infix `@` + parser.ctx.logDebug("parseZeroOrMoreList looks like Array deref"); } else if (token.text.equals(".") && token1.type == LexerTokenType.NUMBER) { // Looks like a fractional number, not an infix `.` parser.ctx.logDebug("parseZeroOrMoreList looks like Number");