Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve parser errors #483

Open
mdiep opened this issue Mar 16, 2021 · 2 comments
Open

Improve parser errors #483

mdiep opened this issue Mar 16, 2021 · 2 comments
Labels
kind/enhancement Improvements to existing feature.
Milestone

Comments

@mdiep
Copy link
Collaborator

mdiep commented Mar 16, 2021

When parsing fails, the errors are pretty rough.

Take this example:

Error while parsing response from server: NIOIMAPCore.ParserError(hint: "none of the options match", file: "NIOIMAPCore/Parser/Grammar/GrammarParser.swift", line: 147)

In this case, I think the actual error is that base64-decoding fails. But oneOf throws away useful error information:

    static func oneOf<T>(_ subParsers: [SubParser<T>], buffer: inout ByteBuffer, tracker: StackTracker, file: String = (#file), line: Int = #line) throws -> T {
        for parser in subParsers {
            do {
                return try composite(buffer: &buffer, tracker: tracker, parser)
            } catch is ParserError {
                continue
            }
        }
        throw ParserError(hint: "none of the options match", file: file, line: line)
    }
@Davidde94
Copy link
Collaborator

@mdiep the problem here is that n parsers will have failed before we actually throw the final ParserError. What behaviour would you find useful?

@mdiep
Copy link
Collaborator Author

mdiep commented Mar 22, 2021

IME the solution is:

  1. Don't backtrack if a subparser consumed any input. This ensures that the most relevant error is returned.
  2. Provide a default error to oneOf that's used if no subparsers consumed any input or use the error from the last subparser. (If you do the latter, you can use an always-failing subparser to provide a better error at your discretion.)

elm/parser does (1) but returns a list of errors instead of (2). Haskell's parsec library also works this way.

This approach is also faster since it avoids needless backtracking. But it may require some adjustments to the parser.

@Davidde94 Davidde94 added this to the 0.2 milestone Apr 29, 2021
@danieleggert danieleggert modified the milestones: 0.2, 0.3, 0.4 Dec 14, 2021
@danieleggert danieleggert added the kind/enhancement Improvements to existing feature. label Feb 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Improvements to existing feature.
Projects
None yet
Development

No branches or pull requests

3 participants