[
https://issues.apache.org/jira/browse/GROOVY-12171?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18097241#comment-18097241
]
ASF GitHub Bot commented on GROOVY-12171:
-----------------------------------------
github-actions[bot] commented on PR #2719:
URL: https://github.com/apache/groovy/pull/2719#issuecomment-5009598098
### JMH summary — indy (commit `58ab35f`)
Speedup vs trailing 90-day baseline on gh-pages. Higher = faster.
`1.00` = in line with history. Per-benchmark ratio, geomean within group.
Time-per-op units inverted so direction is consistent. The *calibrated*
column divides out this runner's speed vs the baseline hardware, as
measured by Groovy-independent pure-Java ruler benchmarks.
| Group | Speedup | Calibrated | n |
|--------|---------|------------|---|
| bench | 0.993 × | 0.965 × | 84 |
| core | 3.741 × | 3.787 × | 77 |
| grails | 2.174 × | 2.371 × | 80 |
<sub>Runner calibration (this run vs baseline hardware): bench 1.02× (26
rulers) · core-ag 0.99× (3 rulers) · core-hz 0.98× (3 rulers) · grails-ad 0.92×
(3 rulers) · grails-ez 0.91× (3 rulers)</sub>
<sub>Baseline: <code>dev/bench/jmh/<part>/indy/data.js</code> on
gh-pages, trailing 90 days. <a
href="https://apache.github.io/groovy/dev/bench/jmh/summary.html">Daily
dashboard</a> · <a
href="https://apache.github.io/groovy/dev/bench/jmh/">Per-suite raw
data</a></sub>
<!
> Improve GString syntax error when '$' is not followed by a valid interpolation
> ------------------------------------------------------------------------------
>
> Key: GROOVY-12171
> URL: https://issues.apache.org/jira/browse/GROOVY-12171
> Project: Groovy
> Issue Type: Improvement
> Reporter: Daniel Sun
> Priority: Major
>
> h3. Problem
> When a double-quoted or triple-double-quoted GString places an illegal
> character immediately after {{$}} (most commonly a trailing bare dollar
> before the closing quote), the Antlr4 lexer reports a generic *token
> recognition error* at that character and never mentions the dollar. The caret
> location is often correct, but the message is hard to understand compared
> with Groovy 2, which reported {*}illegal string body character after dollar
> sign{*}.
> Typical mistakes:
> * trailing bare {{$}} before the closer: {{{}"releases$"{}}},
> {{"""releases$"""}}
> * {{$}} not followed by an identifier or brace expression: {{{}"a$ b"{}}},
> {{"$"}}
> * EOF or newline immediately after {{$}} in an unclosed GString: {{"hello$}}
> Valid programs are unaffected ({{{}$name{}}}, brace expressions, and {{\$}}
> for a literal dollar already work).
> h3. Examples (before)
> * Source:
> {noformat}
> def Target = "releases$"
> {noformat}
> Report:
> {noformat}
> token recognition error at: '"' @ line 1, column 24.
> def Target = "releases$"
> ^
> {noformat}
> * Source:
> {noformat}
> def Target = """releases$"""
> {noformat}
> Report: *token recognition error at: '"'* at the first character of the
> closing {{"""}} (no mention of {{{}${}}})
> * Source:
> {noformat}
> def x = "a$ b"
> {noformat}
> Report: *token recognition error at: ' '* (no mention of {{{}${}}})
> h3. Root cause
> After {{GStringBegin}} / {{GStringPart}} consumes {{{}${}}}, the lexer enters
> {{GSTRING_TYPE_SELECTOR_MODE}} and expects either an opening brace or an
> identifier. Any other character raises {{{}LexerNoViableAltException{}}}.
> Default Antlr recovery surfaces that as *token recognition error at: '…'*
> with no GString-specific wording.
> A related edge case: when {{$}} is the last character of the input, Antlr
> sets {{_hitEOF}} after the begin/part token and the next {{nextToken()}}
> emits EOF without ever matching in the selector mode, so the failure becomes
> a generic unexpected-EOF parse error instead of a dollar-body diagnostic.
> h3. Goal
> Restore a clear, Groovy 2–style diagnostic — *Illegal string body character
> after dollar sign* — with an accurate caret, and name the offending character
> when one is available. Prefer a dedicated {{GroovySyntaxError}} on the lexer
> path so the parser does not fall back to an opaque exception or a useless
> SLL→LL retry for this case.
> h3. Approach
> Localised handling in {{GroovyLangLexer}} only (no grammar / public API
> change):
> * In {{{}GSTRING_TYPE_SELECTOR_MODE{}}}, override {{notifyListeners}} /
> {{recover}} for {{LexerNoViableAltException}} to emit the dedicated
> dollar-body message (append the illegal character via {{getCharErrorDisplay}}
> when not EOF).
> * Override {{nextToken}} so that EOF while still in the selector mode
> reports the same message instead of a bare unexpected-EOF parse failure.
> * Throw {{GroovySyntaxError}} with source {{LEXER}} so {{AstBuilder}} treats
> it as a fatal lexical error with line/column.
> h3. Expected result (after)
> * Source:
> {noformat}
> def Target = "releases$"
> {noformat}
> Expected:
> {noformat}
> Illegal string body character after dollar sign: '"' @ line 1, column 24.
> def Target = "releases$"
> ^
> {noformat}
> * Source:
> {noformat}
> def Target = """releases$"""
> {noformat}
> Expected: *Illegal string body character after dollar sign: '"'* at the first
> closing quote character
> * Source:
> {noformat}
> def x = "a$ b"
> {noformat}
> Expected: *Illegal string body character after dollar sign: ' '* at the space
> after {{$}}
> * Source (EOF immediately after {{{}${}}}):
> {noformat}
> def x = "hello$
> {noformat}
> Expected: *Illegal string body character after dollar sign* (no character
> suffix) at end of input
> Legal cases must keep compiling:
> {noformat}
> def Target = "releases\$"
> assert Target == 'releases$'
> def name = 'world'
> assert "hello $name" == 'hello world'
> assert "hello ${name}" == 'hello world'
> {noformat}
> h3. Compatibility and performance
> * No grammar, bytecode, or public API changes — valid GStrings parse and run
> as before.
> * Extra work runs only on the failing lexical path (mode check + message
> build); successful lexing is unchanged aside from a cheap mode check when
> emitting EOF.
> *
--
This message was sent by Atlassian Jira
(v8.20.10#820010)