alecthomas / participle

A parser library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error recovery ideas

alecthomas opened this issue · comments

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.

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

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

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"

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