Skip to content

Commit

Permalink
Merge pull request #272 from ydah/type-specification-parameterizing
Browse files Browse the repository at this point in the history
Add support for type specification in parameterizing rules
  • Loading branch information
yui-knk authored Nov 29, 2023
2 parents 90a75d6 + c6d64e5 commit 3e30ee6
Show file tree
Hide file tree
Showing 17 changed files with 267 additions and 109 deletions.
2 changes: 1 addition & 1 deletion lib/lrama/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def normalize_rules
end

builder.parameterizing_rules.each do |rule|
add_nterm(id: rule._lhs)
add_nterm(id: rule._lhs, tag: rule.lhs_tag)
@rules << rule
end

Expand Down
5 changes: 3 additions & 2 deletions lib/lrama/grammar/parameterizing_rules/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ class Builder
separated_list: Lrama::Grammar::ParameterizingRules::Builder::SeparatedList,
}

def initialize(token, rule_counter, user_code, precedence_sym, line)
def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
@token = token
@key = token.s_value.to_sym
@rule_counter = rule_counter
@lhs_tag = lhs_tag
@user_code = user_code
@precedence_sym = precedence_sym
@line = line
Expand All @@ -46,7 +47,7 @@ def build_token
def create_builder
unless @builder
validate_key!
@builder = RULES[@key].new(@token, @rule_counter, @user_code, @precedence_sym, @line)
@builder = RULES[@key].new(@token, @rule_counter, @lhs_tag, @user_code, @precedence_sym, @line)
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/lrama/grammar/parameterizing_rules/builder/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ class Builder
class Base
attr_reader :build_token

def initialize(token, rule_counter, user_code, precedence_sym, line)
def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
@args = token.args
@token = @args.first
@rule_counter = rule_counter
@lhs_tag = lhs_tag
@user_code = user_code
@precedence_sym = precedence_sym
@line = line
Expand Down
4 changes: 2 additions & 2 deletions lib/lrama/grammar/parameterizing_rules/builder/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def build

rules = []
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}")
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def build

rules = []
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "nonempty_list_#{@token.s_value}")
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/lrama/grammar/parameterizing_rules/builder/option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def build

rules = []
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "option_#{@token.s_value}")
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class ParameterizingRules
class Builder
# Builder for separated list of general parameterizing rules
class SeparatedList < Base
def initialize(token, rule_counter, user_code, precedence_sym, line)
def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
super
@separator = @args[0]
@token = @args[1]
Expand All @@ -26,10 +26,10 @@ def build
rules = []
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_list_#{@token.s_value}")
separated_nonempty_list_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_nonempty_list_#{@token.s_value}")
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [separated_nonempty_list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [separated_nonempty_list_token, @separator, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [separated_nonempty_list_token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [separated_nonempty_list_token, @separator, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class ParameterizingRules
class Builder
# Builder for separated nonempty list of general parameterizing rules
class SeparatedNonemptyList < Base
def initialize(token, rule_counter, user_code, precedence_sym, line)
def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
super
@separator = @args[0]
@token = @args[1]
Expand All @@ -23,8 +23,8 @@ def build

rules = []
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_nonempty_list_#{@token.s_value}")
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @separator, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @separator, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
rules
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/lrama/grammar/rule.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
module Lrama
class Grammar
# _rhs holds original RHS element. Use rhs to refer to Symbol.
class Rule < Struct.new(:id, :_lhs, :lhs, :_rhs, :rhs, :token_code, :position_in_original_rule_rhs, :nullable, :precedence_sym, :lineno, keyword_init: true)
class Rule < Struct.new(:id, :_lhs, :lhs, :lhs_tag, :_rhs, :rhs, :token_code, :position_in_original_rule_rhs, :nullable, :precedence_sym, :lineno, keyword_init: true)
attr_accessor :original_rule

def ==(other)
self.class == other.class &&
self.lhs == other.lhs &&
self.lhs_tag == other.lhs_tag &&
self.rhs == other.rhs &&
self.token_code == other.token_code &&
self.position_in_original_rule_rhs == other.position_in_original_rule_rhs &&
Expand Down
5 changes: 3 additions & 2 deletions lib/lrama/grammar/rule_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Lrama
class Grammar
class RuleBuilder
attr_accessor :lhs, :line
attr_accessor :lhs, :lhs_tag, :line
attr_reader :rhs, :user_code, :precedence_sym

def initialize(rule_counter, midrule_action_counter, position_in_original_rule_rhs = nil, skip_preprocess_references: false)
Expand All @@ -14,6 +14,7 @@ def initialize(rule_counter, midrule_action_counter, position_in_original_rule_r

@lhs = nil
@rhs = []
@lhs_tag = nil
@user_code = nil
@precedence_sym = nil
@line = nil
Expand Down Expand Up @@ -109,7 +110,7 @@ def process_rhs
when Lrama::Lexer::Token::Ident
@replaced_rhs << token
when Lrama::Lexer::Token::Parameterizing
parameterizing = ParameterizingRules::Builder.new(token, @rule_counter, user_code, precedence_sym, line)
parameterizing = ParameterizingRules::Builder.new(token, @rule_counter, @lhs_tag, user_code, precedence_sym, line)
parameterizing.build.each do |r|
@parameterizing_rules << r
end
Expand Down
Loading

0 comments on commit 3e30ee6

Please sign in to comment.