peggyjs / peggy

Peggy: Parser generator for JavaScript
https://peggyjs.org/
MIT License
883 stars 63 forks source link

Start and end index of matched rule in the source code. #503

Closed alex-klimov closed 4 months ago

alex-klimov commented 4 months ago

I need to provide additional information in the editor, when user stands on the text matching particular rules.

Is there built-in way to return start and end index of the text matched with a rule?

Mingun commented 4 months ago

Yes, location() or range(). Try to see this output:

start = "a" { return {
  offset: offset(),
  text: text(),
  range: range(),
  location: location(),
}; }
alex-klimov commented 4 months ago

Thanks, this works brilliantly!

One quick question before closing the issue: range() seems to give exactly what I was asking for. In addition, it has property source which is undefined. Is this supposed to be exactly as what text() returns? Should I be concerned that range.source is undefined?

Mingun commented 4 months ago

Just read the linked documentation. This is the value of options.grammarSource and it is intended to give location a filename.

alex-klimov commented 4 months ago

Found it, thanks! Linking it here, so other people might make use of it in the future: https://peggyjs.org/documentation.html#locations

hildjj commented 4 months ago

One additional quick note. I sometimes use a function called "loc" when I'm applying locations to lots of AST nodes:

{
  function loc(node) {
    node.loc = location();
  }
}

foo = "foo" { return loc({type: "foo"}); }

location() knows about the current parse state, and the function is available within scope to all initializer functions inside of the initial {} (but NOT top-level initializers using {{}}). I particularly use this approach when I have to modify the location to be in a different form for a specific AST, like here in @peggyjs/eslint-parser