Show syntax error from Lezer parse

I’m using CodeMirror for a custom language. I’ve successfully written a Lezer grammar and have got syntax highlighting working.

I was hoping the building blocks would be provided to get in-editor indication of syntax errors from the same grammar, but it looks like not. If I’ve understood correctly, error indicators in PM come from the linter support, and there’s no automatic way to get a linter from a lezer parser.

I’ve seen mention in this forum that an LR parser may not be the best tool for the job, but surely it must be way better than nothing?!

I’m thinking it should be fairly easy to:

  • get highest character offset that the parser made it to without hitting a parse error,
  • write a very simple linter that reports that offset as an error

Any advice on how to accomplish that? Or is there a better way to go?

This is doable, but indeed, the parser won’t give any useful error message about a parse failure. What you’d do is write a lint source that takes the current syntax tree, checks if it covers the whole document (so that it doesn’t report errors for partial parses that were aborted due to running out of time), and then iterates through the tree to find the first error marker (node.type.isError).

Amazingly helpful answer in four lines!

In case this is useful to others, here is a working extension:

import {syntaxTree} from "@codemirror/language"
import {linter} from '@codemirror/lint'

function simpleLezerLinter() {
  return linter(view => {
    const {state} = view
    const tree = syntaxTree(state)
    if (tree.length === state.doc.length) {
      let pos = null
      tree.iterate({enter: n => {
        if (pos == null && n.type.isError) {
          pos = n.from
          return false
        }
      }})

      if (pos != null)
        return [{from: pos, to: pos+1, severity: 'error', message: 'syntax error'}]
    } 

    return []
  })
}
1 Like