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

Implemented mapping syntax in peg grammars #433

Closed
wants to merge 5 commits into from

Conversation

QaDeS
Copy link

@QaDeS QaDeS commented Sep 1, 2023

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
Copy link
Member

Mingun commented Sep 1, 2023

What's wrong with:

{{
// Nothing to see here
}}

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

?

@QaDeS
Copy link
Author

QaDeS commented Sep 1, 2023

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
Copy link
Contributor

hildjj commented Sep 1, 2023

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
Copy link
Author

QaDeS commented Sep 2, 2023

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:

  • simple string-to-string mappings (working)
  • string-to-array mapping (kinda working)
  • escaping / embedding via template strings (soon to be working, especially useful for choice and class expressions)
  • directly using const maps inside the parser, hopefully with appropriate expectation and error handling

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.

/ "n"%"\n"
/ "r"%"\r"
/ "t"%"\t"
/ "v"%"\v"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't find this easier to read or maintain. Are there other examples you think might benefit from this approach? Maybe add a new example that shows the full power?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. In any case it is better to use -> or =>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, if it was => I might be able to get excited about this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Particularly if we also added &=> and !=> at the same time...

@hildjj
Copy link
Contributor

hildjj commented Dec 9, 2023

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

@hildjj hildjj closed this Dec 9, 2023
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

Successfully merging this pull request may close these issues.

3 participants