Rule aliasing #36

Open
opened 2 years ago by jackfirth · 4 comments
jackfirth commented 2 years ago (Migrated from github.com)

I've got a grammar where expressions are split between two rules: inline-expression and block-expression. They have to be split because in some contexts only inline expressions are allowed and in others only block expressions are allowed. However, I want them to both produce (expression ...) nodes in the resulting parse trees. Can brag be extended with some sort of feature for this? I'm picturing something that lets people write grammar rules like this:

#lang brag

expression.inline: ...
expression.block: ...


somerule: ... expression.inline ...
someotherrule: ... expression.block ...

...where expression.inline and expression.block are different rules, but they both produce (expression ...) nodes instead of producing (expression.inline ...) and (expression.block ...) nodes.

I've got a grammar where expressions are split between two rules: `inline-expression` and `block-expression`. They have to be split because in some contexts only inline expressions are allowed and in others only block expressions are allowed. However, I want them to both produce `(expression ...)` nodes in the resulting parse trees. Can `brag` be extended with some sort of feature for this? I'm picturing something that lets people write grammar rules like this: ``` #lang brag expression.inline: ... expression.block: ... somerule: ... expression.inline ... someotherrule: ... expression.block ... ``` ...where `expression.inline` and `expression.block` are different rules, but they both produce `(expression ...)` nodes instead of producing `(expression.inline ...)` and `(expression.block ...)` nodes.
mbutterick commented 2 years ago (Migrated from github.com)

Can brag be extended with some sort of feature for this?

Can’t brag already do this? Define expression in terms of your subrules, and then splice the names of the subrules globally. In the parse tree, the terminals belonging to any inline-expression or block-expression will be hoisted into the surrounding expression node (fragment below):

expression: inline-expression | block-expression
@inline-expression: [rule pattern ···]
@block-expression: [another rule pattern ···]
> Can brag be extended with some sort of feature for this? Can’t `brag` already do this? Define `expression` in terms of your subrules, and then splice the names of the subrules globally. In the parse tree, the terminals belonging to any `inline-expression` or `block-expression` will be hoisted into the surrounding `expression` node (fragment below): ``` expression: inline-expression | block-expression @inline-expression: [rule pattern ···] @block-expression: [another rule pattern ···] ```
jackfirth commented 2 years ago (Migrated from github.com)

No, because when somerule refers to inline-expression it will get the (inline-expression ...) wrapper. There's no way for somerule to refer to a rule named expression while specifying "actually I only meant this kind of expression."

No, because when `somerule` refers to `inline-expression` it will get the `(inline-expression ...)` wrapper. There's no way for `somerule` to refer to a rule named `expression` while specifying "actually I only meant _this kind_ of expression."
mbutterick commented 2 years ago (Migrated from github.com)

OK, I see what you mean. In that case — can’t make-rename-transformer be used (after the parse, within the expander) to convert uses of expression.inline and expression.block into expression?

In general, if the macro expander already has a good solution for task X, I’m unlikely to be persuaded to invent a brag-specific notational solution for that task. For instance, the reason brag has notational cuts and splices is that I discovered that those transformations are difficult & annoying to accomplish within the macro expander.

OK, I see what you mean. In that case — can’t `make-rename-transformer` be used (after the parse, within the expander) to convert uses of `expression.inline` and `expression.block` into `expression`? In general, if the macro expander already has a good solution for task X, I’m unlikely to be persuaded to invent a `brag`-specific notational solution for that task. For instance, the reason `brag` has notational cuts and splices is that I discovered that those transformations are difficult & annoying to accomplish within the macro expander.
jackfirth commented 2 years ago (Migrated from github.com)

That's what I would do for an ordinary language, but I'm trying to make a macro-extensible language with brag so the parse trees I spit out from read-syntax will be visible to userland macro code. I don't want userland macro code to start to use those aliases and then break if I refactor or rename my grammar rules. So I have to do this postprocessing before handing my syntax objects off to the macro expander. I can get very far with cuts and splices, but this one task is tricky to do within read-syntax and outside brag. I have to traverse the syntax tree and swap out and rename things while making sure I copy over source locations and properties just right.

That's what I would do for an ordinary language, but I'm trying to make a macro-extensible language with `brag` so the parse trees I spit out from `read-syntax` will be visible to userland macro code. I don't want userland macro code to start to use those aliases and then break if I refactor or rename my grammar rules. So I have to do this postprocessing before handing my syntax objects off to the macro expander. I can get very far with cuts and splices, but this one task is tricky to do within `read-syntax` and outside `brag`. I have to traverse the syntax tree and swap out and rename things while making sure I copy over source locations and properties just right.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: mbutterick/brag#36
Loading…
There is no content yet.