diff --git a/src/main/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2.java b/src/main/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2.java index 0e84f8b..5cb0b93 100644 --- a/src/main/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2.java +++ b/src/main/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2.java @@ -3077,7 +3077,7 @@ public void exitFieldReferenceWithVariableContextOverride( @Override public void enterLateBoundScalar(LateBoundScalarContext ctx) { this.typeResolutionStack.push( - this.adjustForGrammarAmbiguities(ctx, CardinalityResolutionContext.RESOLVE_SCALAR)); + this.adjustForGrammarAmbiguity(ctx, CardinalityResolutionContext.RESOLVE_SCALAR)); } @Override @@ -3088,7 +3088,7 @@ public void exitLateBoundScalar(LateBoundScalarContext ctx) { @Override public void enterLateBoundSequence(LateBoundSequenceContext ctx) { this.typeResolutionStack.push( - this.adjustForGrammarAmbiguities(ctx, CardinalityResolutionContext.RESOLVE_SEQUENCE)); + this.adjustForGrammarAmbiguity(ctx, CardinalityResolutionContext.RESOLVE_SEQUENCE)); } @Override @@ -3101,36 +3101,21 @@ public void exitLateBoundSequence(LateBoundSequenceContext ctx) { * cardinality is ambiguous, and returns {@code RESOLVE_EITHER} if so. * Otherwise returns the provided default context. * - * There are two grammar ambiguities that require this adjustment: - * - * Ambiguity 1: The {@code expression} rule accepts both - * {@code lateBoundScalar} and {@code lateBoundSequence} via - * {@code lateBoundExpression}. The parser picks one alternative, but the - * actual cardinality is unknown until the preprocessor resolves it. - * - * Ambiguity 2: The {@code for...return} construct has two rules: - * {@code lateBoundSequenceFromIteration} (scalar body) and - * {@code lateBoundSequenceFromConcatenatedIterations} (sequence body). - * The parser picks one, but the body cardinality is unknown until resolved. + * The {@code lateBoundExpression} rule accepts both {@code lateBoundScalar} + * and {@code lateBoundSequence}. The parser picks one alternative, but the + * actual cardinality is unknown until the preprocessor resolves it. This + * ambiguity applies wherever {@code lateBoundExpression} appears in the + * grammar: the top-level {@code expression} rule and the body of + * {@code lateBoundSequenceFromIteration}. * * @param ctx the late-bound parse tree node (scalar or sequence) * @param defaultContext the context to use when no ambiguity is detected * @return {@code RESOLVE_EITHER} if an ambiguity applies, otherwise * {@code defaultContext} */ - private CardinalityResolutionContext adjustForGrammarAmbiguities(ParserRuleContext ctx, + private CardinalityResolutionContext adjustForGrammarAmbiguity(ParserRuleContext ctx, CardinalityResolutionContext defaultContext) { - ParserRuleContext parent = ctx.getParent(); - - // Ambiguity 1: expression → lateBoundExpression → lateBoundScalar | lateBoundSequence - boolean ambiguity1 = (parent instanceof LateBoundExpressionContext) - && (parent.getParent() instanceof ExpressionContext); - - // Ambiguity 2: lateBoundSequenceFromIteration vs lateBoundSequenceFromConcatenatedIterations - boolean ambiguity2 = (parent instanceof LateBoundSequenceFromIterationContext) - || (parent instanceof LateBoundSequenceFromConcatenatedIterationsContext); - - return (ambiguity1 || ambiguity2) + return (ctx.getParent() instanceof LateBoundExpressionContext) ? CardinalityResolutionContext.RESOLVE_EITHER : defaultContext; } @@ -3769,16 +3754,6 @@ public void exitDurationSequenceFromConcatenatedIterations(DurationSequenceFromC this.stack.popStackFrame(); } - @Override - public void enterLateBoundSequenceFromConcatenatedIterations(LateBoundSequenceFromConcatenatedIterationsContext ctx) { - this.stack.pushStackFrame(); - } - - @Override - public void exitLateBoundSequenceFromConcatenatedIterations(LateBoundSequenceFromConcatenatedIterationsContext ctx) { - this.stack.popStackFrame(); - } - // #endregion Scope management -------------------------------------------- // #region Guards --------------------------------------------------------- diff --git a/src/test/java/eu/europa/ted/efx/sdk2/PreprocessorTypeResolutionTest.java b/src/test/java/eu/europa/ted/efx/sdk2/PreprocessorTypeResolutionTest.java index 63daf87..650859a 100644 --- a/src/test/java/eu/europa/ted/efx/sdk2/PreprocessorTypeResolutionTest.java +++ b/src/test/java/eu/europa/ted/efx/sdk2/PreprocessorTypeResolutionTest.java @@ -100,6 +100,13 @@ void testResolveFieldReference_Either_NonRepeatableFieldInForReturn() { "for text:$x in BT-00-Text return BT-00-Text")); } + @Test + void testResolveFieldReference_Either_NestedForReturn() { + assertDoesNotThrow( + () -> translateExpressionWithContext("ND-Root", + "for text:$x in BT-00-Text return (for text:$y in BT-00-Text return BT-00-Repeatable-Text)")); + } + // #endregion resolveFieldOrAttributeReference -------------------------------- // #region resolveFunctionInvocation ------------------------------------------