diff options
Diffstat (limited to 'tool/lrama/lib/lrama/grammar/parameterizing_rules')
7 files changed, 98 insertions, 31 deletions
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb index 28c9ad427d..20950b9b36 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb @@ -8,6 +8,7 @@ require 'lrama/grammar/parameterizing_rules/builder/separated_list' module Lrama class Grammar class ParameterizingRules + # Builder for parameterizing rules class Builder RULES = { option: Lrama::Grammar::ParameterizingRules::Builder::Option, @@ -20,23 +21,39 @@ module Lrama separated_list: Lrama::Grammar::ParameterizingRules::Builder::SeparatedList, } - def initialize(token, rule_counter, lhs, 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 = lhs + @lhs_tag = lhs_tag @user_code = user_code @precedence_sym = precedence_sym @line = line + @builder = nil end def build - if RULES.key?(@key) - RULES[@key].new(@token, @rule_counter, @lhs, @user_code, @precedence_sym, @line).build - else - raise "Parameterizing rule does not exist. `#{@key}`" + create_builder + @builder.build + end + + def build_token + create_builder + @builder.build_token + end + + private + + def create_builder + unless @builder + validate_key! + @builder = RULES[@key].new(@token, @rule_counter, @lhs_tag, @user_code, @precedence_sym, @line) end end + + def validate_key! + raise "Parameterizing rule does not exist. `#{@key}`" unless RULES.key?(@key) + end end end end diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb index a85348c94f..5787714f0c 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb @@ -2,16 +2,24 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Base class for parameterizing rules builder class Base - def initialize(token, rule_counter, lhs, user_code, precedence_sym, line) + attr_reader :build_token + + def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line) @args = token.args @token = @args.first @rule_counter = rule_counter - @lhs = lhs + @lhs_tag = lhs_tag @user_code = user_code @precedence_sym = precedence_sym @line = line @expected_argument_num = 1 + @build_token = nil + end + + def build + raise NotImplementedError end private diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb index f814160416..248e1e7ad4 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb @@ -2,15 +2,23 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Builder for list of general parameterizing rules class List < Base + + # program: list(number) + # + # => + # + # program: list_number + # list_number: ε + # list_number: list_number number def build validate_argument_number! rules = [] - list_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}") - rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: list_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: list_token, _rhs: [list_token, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) + @build_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}") + 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 diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb index 142d6c156b..bcec1d823a 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb @@ -2,15 +2,23 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Builder for nonempty list of general parameterizing rules class NonemptyList < Base + + # program: nonempty_list(number) + # + # => + # + # program: nonempty_list_number + # nonempty_list_number: number + # nonempty_list_number: nonempty_list_number number def build validate_argument_number! rules = [] - nonempty_list_token = Lrama::Lexer::Token::Ident.new(s_value: "nonempty_list_#{@token.s_value}") - rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [nonempty_list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: nonempty_list_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: nonempty_list_token, _rhs: [nonempty_list_token, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) + @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], 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 diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb index f751609e44..8be045ec30 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb @@ -2,15 +2,23 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Builder for option of general parameterizing rules class Option < Base + + # program: option(number) + # + # => + # + # program: option_number + # option_number: ε + # option_number: number def build validate_argument_number! rules = [] - option_token = Lrama::Lexer::Token::Ident.new(s_value: "option_#{@token.s_value}") - rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [option_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: option_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: option_token, _rhs: [@token], token_code: @ser_code, precedence_sym: @precedence_sym, lineno: @line) + @build_token = Lrama::Lexer::Token::Ident.new(s_value: "option_#{@token.s_value}") + 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 diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb index 95f8156498..f9677cadbc 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb @@ -2,23 +2,34 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Builder for separated list of general parameterizing rules class SeparatedList < Base - def initialize(token, rule_counter, lhs, user_code, precedence_sym, line) + def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line) super @separator = @args[0] @token = @args[1] @expected_argument_num = 2 end + # program: separated_list(',', number) + # + # => + # + # program: separated_list_number + # separated_list_number: ε + # separated_list_number: separated_nonempty_list_number + # separated_nonempty_list_number: number + # separated_nonempty_list_number: separated_nonempty_list_number ',' number def build validate_argument_number! rules = [] - separated_list_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_list_#{@token.s_value}") - rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [separated_list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: separated_list_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: separated_list_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: separated_list_token, _rhs: [separated_list_token, @separator, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) + @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: [], 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 diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb index 64662180a0..ba6ecf24cc 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb @@ -2,22 +2,29 @@ module Lrama class Grammar class ParameterizingRules class Builder + # Builder for separated nonempty list of general parameterizing rules class SeparatedNonemptyList < Base - def initialize(token, rule_counter, lhs, user_code, precedence_sym, line) + def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line) super @separator = @args[0] @token = @args[1] @expected_argument_num = 2 end + # program: separated_nonempty_list(',', number) + # + # => + # + # program: separated_nonempty_list_number + # separated_nonempty_list_number: number + # separated_nonempty_list_number: separated_nonempty_list_number ',' number def build validate_argument_number! rules = [] - separated_list_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_nonempty_list_#{@token.s_value}") - rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [separated_list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: separated_list_token, _rhs: [@token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) - rules << Rule.new(id: @rule_counter.increment, _lhs: separated_list_token, _rhs: [separated_list_token, @separator, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line) + @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], 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 |