peggyjs / peggy

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

Implemented mapping syntax in peg grammars #433

Closed QaDeS closed 9 months ago

QaDeS commented 1 year ago

This PR enables direct mapping of string literals without using const maps, removing duplication in the grammar files.

Before:

{{
const DIRS = {
  l: "left",
  r: "right"
}
}}

start =
  ( "l"i
  /  "r"i
  ) { return DIRS[text()] }

After:

{{
// Nothing to see here
}}

start
  = "l"i:"left"
  /  "r"i:"right"

I chose the : as separator so you can translate your existing maps with minimal effort, another one that might make sense for reducing ambiguity might be % or even ->. Awaiting your feedback on possible improvements :)

Mingun commented 1 year ago

What's wrong with:

{{
// Nothing to see here
}}

start
  = "l"i { return "left";  }
  / "r"i { return "right"; }

?

QaDeS commented 1 year ago

Generally nothing, but it's so verbose that you tend to use a const instead and ignore the repetition. I think that it promotes the use of a bad pattern. The way I implemented it also saves a method call (or map lookup, respectively) in the resulting parser, with marginal overhead in the compilation step.

hildjj commented 1 year ago

I'm not terribly excited about this one. I don't think it's generally-useful enough to add syntax for.

I'm willing to think about it some more, though.

QaDeS commented 1 year ago

I'm all in for exploring if/how a syntax for mapping can be so useful that it justifies an addition to the grammar. Or maybe there's a way to implement this as a plugin? Don't have a lot of experience with the whole parsing shebang, so I'm going to trust your judgment on this.

Currently, I am working on a Tailwind-like CSS creation mechanism, which requires a lot of expanding letters to keywords and mapping in general. In some of your example grammars, and also the core peggy one, I spotted similar patterns. Mapping characters like & and ! to node types, or (un-)escaping seem to be very common use cases.

So the ideas I am now playing around with are:

Generally, I'm just fiddling and learning about the inner workings of Peggy right now. If something useful comes out of it, even better.

Settled on % instead of : for now, btw. Makes it more clear that something very different is happening there.

hildjj commented 9 months ago

I'm going to close this for now. If we come up with better use cases, I'm open to further discussion.