From 40b4a6531782db63d898934e6eef2a87c8b536a7 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Mon, 4 Nov 2024 11:56:23 +0100 Subject: [PATCH 1/2] Support slashy interpolated string Signed-off-by: Ben Sherman --- src/main/antlr/ScriptLexer.g4 | 20 +++++++++++++++++++ src/main/antlr/ScriptParser.g4 | 7 +++++++ .../nextflow/script/v2/ScriptAstBuilder.java | 14 ++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/antlr/ScriptLexer.g4 b/src/main/antlr/ScriptLexer.g4 index 0c693ed3..4b02947a 100644 --- a/src/main/antlr/ScriptLexer.g4 +++ b/src/main/antlr/ScriptLexer.g4 @@ -139,6 +139,9 @@ GStringBegin TdqGStringBegin : TdqStringQuotationMark -> pushMode(TDQ_GSTRING_MODE) ; +SlashyGStringBegin + : Slash { this.isRegexAllowed() && _input.LA(1) != '*' }? SlashyStringCharacter* Dollar { isFollowedByJavaLetterInGString(_input) }? -> pushMode(SLASHY_GSTRING_MODE) + ; mode DQ_GSTRING_MODE; GStringEnd @@ -174,6 +177,23 @@ TdqGStringExprStart : '${' -> pushMode(DEFAULT_MODE) ; +mode SLASHY_GSTRING_MODE; +SlashyGStringEnd + : Dollar? Slash -> popMode + ; + +SlashyGStringPath + : Dollar IdentifierInGString (Dot IdentifierInGString)* + ; + +SlashyGStringText + : SlashyStringCharacter+ + ; + +SlashyGStringExprStart + : '${' -> pushMode(DEFAULT_MODE) + ; + mode DEFAULT_MODE; // character in the double quotation string. e.g. "a" fragment diff --git a/src/main/antlr/ScriptParser.g4 b/src/main/antlr/ScriptParser.g4 index b31ce572..e26cc240 100644 --- a/src/main/antlr/ScriptParser.g4 +++ b/src/main/antlr/ScriptParser.g4 @@ -515,6 +515,7 @@ stringLiteral gstring : GStringBegin gstringDqPart* GStringEnd | TdqGStringBegin gstringTdqPart* TdqGStringEnd + | SlashyGStringBegin gstringSlashyPart* SlashyGStringEnd ; gstringDqPart @@ -529,6 +530,12 @@ gstringTdqPart | TdqGStringExprStart expression RBRACE #gstringTdqExprAlt ; +gstringSlashyPart + : SlashyGStringText #gstringSlashyTextAlt + | SlashyGStringPath #gstringSlashyPathAlt + | SlashyGStringExprStart expression RBRACE #gstringSlashyExprAlt + ; + // -- constructor method call creator : createdName arguments diff --git a/src/main/groovy/nextflow/script/v2/ScriptAstBuilder.java b/src/main/groovy/nextflow/script/v2/ScriptAstBuilder.java index 576fec6e..3863a8ba 100644 --- a/src/main/groovy/nextflow/script/v2/ScriptAstBuilder.java +++ b/src/main/groovy/nextflow/script/v2/ScriptAstBuilder.java @@ -1207,9 +1207,6 @@ private String stringLiteral(String text) { text = StringUtils.trimQuotations(text, 3); } else if( text.startsWith(SQ_STR) || text.startsWith(DQ_STR) || startsWithSlash ) { - // the slashy string can span rows, so we have to remove CR for it - if( startsWithSlash ) - text = StringUtils.removeCR(text); text = StringUtils.trimQuotations(text, 1); } @@ -1249,6 +1246,17 @@ private Expression gstring(GstringContext ctx) { values.add(expression(eac.expression())); } + for( var part : ctx.gstringSlashyPart() ) { + if( part instanceof GstringSlashyTextAltContext tac ) + strings.add(ast( gstringText(tac, beginQuotation), tac )); + + if( part instanceof GstringSlashyPathAltContext pac ) + values.add(ast( gstringPath(pac), pac )); + + if( part instanceof GstringSlashyExprAltContext eac ) + values.add(expression(eac.expression())); + } + var result = new GStringExpression(verbatimText, strings, values); result.putNodeMetaData(QUOTE_CHAR, beginQuotation); return result; From 6cb6bff2c4ceb80eefdcba592338ccfb9f12e89f Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Tue, 26 Nov 2024 15:05:47 -0600 Subject: [PATCH 2/2] Fix bug Signed-off-by: Ben Sherman --- .../compiler/src/main/java/script/parser/ScriptAstBuilder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/compiler/src/main/java/script/parser/ScriptAstBuilder.java b/modules/compiler/src/main/java/script/parser/ScriptAstBuilder.java index 443818b1..6d1d95ba 100644 --- a/modules/compiler/src/main/java/script/parser/ScriptAstBuilder.java +++ b/modules/compiler/src/main/java/script/parser/ScriptAstBuilder.java @@ -1282,6 +1282,8 @@ private String beginQuotation(String text) { return TDQ_STR; if( text.startsWith(DQ_STR) ) return DQ_STR; + if( text.startsWith(SLASH_STR) ) + return SLASH_STR; throw new IllegalStateException(); }