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

Error recovery ideas #342

Open
alecthomas opened this issue May 7, 2023 · 4 comments
Open

Error recovery ideas #342

alecthomas opened this issue May 7, 2023 · 4 comments

Comments

@alecthomas
Copy link
Owner

alecthomas commented May 7, 2023

Implement a RecoverToNext(token...string) option that allows resumption from synchronisation tokens. eg. a language might choose statement keywords like if, while, etc. as synchronisation tokens.

Edit: it might be better to specify a list of nodes to recover to, or generate a mapping of token value to node. The parser would then traverse up from the failing node to the nearest recovery node and attempt to match the token for that node. eg. if, while, etc. might map to the Statement node.

@alecthomas alecthomas changed the title Error recovery to next synchronisation token? Error recovery ideas May 8, 2023
@spatecon
Copy link
Contributor

Could you provide an example that enables external contributors to attempt implementing it?

@alecthomas
Copy link
Owner Author

I would love to, but I'm not sure myself! If you have any ideas, please add them here.

@alecthomas
Copy link
Owner Author

My current thoughts though, are that you might need something like RecoverTo(node...any). For any of the given nodes, Participle would pull out the literals that disambiguate each branch (I think this would be necessary for performance), and seek forward in the token stream until one of those literals is encountered.

Here's a hypothetical partial language:

type Decls struct {
  Func *FuncDecl `@@*`
}

type FuncDecl struct {
  Name string `"func" @Ident "{"`
  Statements []*Stmt `@@* "}"`
}

type Stmt struct {
  If *IfStmt `  "if" @@`
  For *ForStmt `| "for" @@`
  Switch *SwitchStmt `| "switch" @@`
}

var parser = participle.MustBuild[Decls](
  participle.RecoverTo(&FuncDecl{}, &Stmt{}),
)

... though having now written this out I wonder if there could be a recovery heuristic used here to do this automatically. Something like "recover to literals from the nearest ancestral disjunction, and repeat"

@nodir-t
Copy link

nodir-t commented Jul 10, 2023

Absence of fault-tolerant parsing is the only reason I might have to stop using participle (which is otherwise awesome!)

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

No branches or pull requests

3 participants