-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PoC] Intoroduce parameterizing rules with conditonal
I would like to propose a new grammar in this PR. I believe that more parameterizing rules can handle more abstract rules if we can switch between rules and actions that are expanded by conditions in order to make rules common. Syntax is as follows: ``` %rule defined_rule(X, condition): /* empty */ | X { $$ = $1; } %if(condition) /* 1 */ | %if(condition) X %endif X { $$ = $1; } /* 2 */ ; %% r_true : defined_rule(number, %true) ; r_false : defined_rule(number, %false) ; ``` 1. It's like a postfix if in Ruby. If condition is false, it is equivalent to missing this line. 2. If statementIf condition is false, it is equivalent to missing RHS between `%if` and`% endif`. I believe it will solve the problem mentioned in the article below with the tight coupling with Lexer "to disable certain generation rules under certain conditions" and I would like to propose this feature to solve this problem. https://yui-knk.hatenablog.com/entry/2023/04/04/190413 We can trace the RHS to [f_args](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5523-L5575) > [args_tail](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5487-L5503) > [args_forward](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5586-L5597), where f_args is the RHS of both the lambda argument (f_larglist) and the method definition argument (f_arglist). So if we can switch between RHS and actions by passing parameters, we can break up the Lexer/Parser coupling here.
- Loading branch information
Showing
14 changed files
with
809 additions
and
518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,10 @@ class Lexer | |
%rule | ||
%no-stdlib | ||
%inline | ||
%if | ||
%endif | ||
%true | ||
%false | ||
) | ||
|
||
def initialize(grammar_file) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Lrama | ||
class Lexer | ||
class Token | ||
class ControlSyntax < Token | ||
attr_accessor :condition | ||
|
||
def initialize(s_value:, location:, condition: nil) | ||
@condition = condition | ||
super(s_value: s_value, location: location) | ||
end | ||
|
||
def if? | ||
s_value == '%if' | ||
end | ||
|
||
def endif? | ||
s_value == '%endif' | ||
end | ||
|
||
def true? | ||
!!@condition&.s_value | ||
end | ||
|
||
def false? | ||
!true? | ||
end | ||
|
||
def condition_value | ||
@condition&.s_value | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.