Skip to content

Accept 4-5 quotes at end of triple-quoted string#2388

Merged
plajjan merged 5 commits into
mainfrom
parse-str-4-5-end-quotes
Jul 23, 2025
Merged

Accept 4-5 quotes at end of triple-quoted string#2388
plajjan merged 5 commits into
mainfrom
parse-str-4-5-end-quotes

Conversation

@plajjan

@plajjan plajjan commented Jul 21, 2025

Copy link
Copy Markdown
Contributor

In triple-quoted strings we accept unescaped quotes inside the string,
for example:

a = """"foo""" # note the 4 " at the start
a = """my dog "foo" ate the cat"""

But it hasn't been supported at the end

a = """foo""""

Because the first three " of the end run of 4 quote chars would be
recognized as the end of the string, leaving a single trailing " that
would result in a syntax error. That has now changed, so we accept 4 or
5 runs of quotes at the end, like so:

a = """foo""""
    ^^^---------- start of quote
       ^^^^------ payload: foo"
           ^^^--- end of quote

a = """foo"""""
    ^^^---------- start of quote
       ^^^^^----- payload: foo""
            ^^^-- end of quote

a = """"foo"""""
    ^^^---------- start of quote
       ^^^^^^---- payload: "foo""
             ^^^- end of quote

There are some preparatory commits first that restructure error handling and improves the flow so that we can propagate hints/notes in structured errors. Many errors from the parser have been converted to such structured errors and now come with Notes / Hints, for example:

ERROR: [error Syntax error]: Expected digits after '.' in format specifier
     ╭──▶ test@1:38-1:38
     │
   1 │ f"Missing precision digits {value:10.}"
     •                                       
     •                                      ╰╸ Expected digits after '.' in format specifier
     •
     │ Hint: Add precision digits, e.g. .2f for 2 decimal places
─────╯
     ╭──▶ test/syntaxerrors/err42.act@1:5-1:6
     │
   1 │ def Z():
     •       
     •     ╰╸ Invalid name 'Z'
     •
     │ Note: Single upper case character (optionally followed by digits) are reserved for type variables
     │ Hint: Use a longer name
─────╯

Fixes #2387

Kristian Larsson added 4 commits July 21, 2025 22:54
The FailFastErrors are really all from the parser, so now calling these
CustomParserException, which is a thin wrapper around CustomParserErrors
- this way we can treat errors the same regardless how they propagate to
us, via megaparsec errors or jumping direct using
Control.Exception (wrapped in CustomParserException). This means that we
now use nice custom error types for exceptions we raise as
Control.Exception from within the parser rather than just a single text
message as we had in the FailFastError. Much nicer and we can now
include hints in the parser exceptions!
The test suite and compiler now use the same error formatting logic for
custom parse errors, ensuring that hints (like for type variable name
errors) are preserved and displayed consistently. Our `handle` function
dumbs down errors to our internal acton error type which just consists
of (loc, msg) so hints etc get lost... but no more!

- Add customParseExceptionToDiagnostic to convert exceptions with hints
- Add customParseErrorDiagnostic for consistent formatting
- Update ActonSpec.hs to use common diagnostic functions
- Use handleDiagnostic for custom parse exceptions to preserve hints
In triple-quoted strings we accept unescaped quotes inside the string,
for example:

    a = """"foo""" # note the 4 " at the start
    a = """my dog "foo" ate the cat"""

But it hasn't been supported at the end

    a = """foo""""

Because the first three " of the end run of 4 quote chars would be
recognized as the end of the string, leaving a single trailing " that
would result in a syntax error. That has now changed, so we accept 4 or
5 runs of quotes at the end, like so:

    a = """foo""""  # string payload: foo"
              ^------ payload
               ^^^--- end of quote
    a = """foo""""" # string payload: foo""
              ^^----- payload
                ^^^-- end of quote
Separate the note and hint - simple and clean!
@plajjan plajjan force-pushed the parse-str-4-5-end-quotes branch from e82dc2e to 2a455f3 Compare July 21, 2025 21:22
@plajjan plajjan changed the title Parse str 4 5 end quotes Accept 4-5 quotes at end of triple-quoted string Jul 21, 2025
Rather than printing little text messages we now emit proper structured
errors for a number of errors we have in the parser, in particular for
string formatting. This allows us to add Notes and Hints, for example:

ERROR: [error Syntax error]: Expected digits after '.' in format specifier
     ╭──▶ test@1:38-1:38
     │
   1 │ f"Missing precision digits {value:10.}"
     •
     •                                      ╰╸ Expected digits after '.' in format specifier
     •
     │ Hint: Add precision digits, e.g. .2f for 2 decimal places
─────╯
@plajjan plajjan force-pushed the parse-str-4-5-end-quotes branch from 27bade4 to a9b91ef Compare July 23, 2025 09:21
@plajjan plajjan merged commit 29bf8cd into main Jul 23, 2025
35 checks passed
@plajjan plajjan deleted the parse-str-4-5-end-quotes branch July 23, 2025 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support 4‑ & 5‑quote runs in triple‑quoted strings

1 participant