summaryrefslogtreecommitdiff
path: root/tool/lrama/lib/lrama/grammar/parameterizing_rule
diff options
context:
space:
mode:
Diffstat (limited to 'tool/lrama/lib/lrama/grammar/parameterizing_rule')
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb56
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb37
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb18
3 files changed, 111 insertions, 0 deletions
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb
new file mode 100644
index 0000000000..d8f3ae7897
--- /dev/null
+++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb
@@ -0,0 +1,56 @@
+module Lrama
+ class Grammar
+ class ParameterizingRule
+ class Resolver
+ attr_accessor :rules, :created_lhs_list
+
+ def initialize
+ @rules = []
+ @created_lhs_list = []
+ end
+
+ def add_parameterizing_rule(rule)
+ @rules << rule
+ end
+
+ def find_rule(token)
+ select_rules(@rules, token).last
+ end
+
+ def find_inline(token)
+ @rules.select { |rule| rule.name == token.s_value && rule.is_inline }.last
+ end
+
+ def created_lhs(lhs_s_value)
+ @created_lhs_list.reverse.find { |created_lhs| created_lhs.s_value == lhs_s_value }
+ end
+
+ private
+
+ def select_rules(rules, token)
+ rules = select_not_inline_rules(rules)
+ rules = select_rules_by_name(rules, token.rule_name)
+ rules = rules.select { |rule| rule.required_parameters_count == token.args_count }
+ if rules.empty?
+ raise "Invalid number of arguments. `#{token.rule_name}`"
+ else
+ rules
+ end
+ end
+
+ def select_not_inline_rules(rules)
+ rules.select { |rule| !rule.is_inline }
+ end
+
+ def select_rules_by_name(rules, rule_name)
+ rules = rules.select { |rule| rule.name == rule_name }
+ if rules.empty?
+ raise "Parameterizing rule does not exist. `#{rule_name}`"
+ else
+ rules
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb
new file mode 100644
index 0000000000..3eb92f8ef4
--- /dev/null
+++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb
@@ -0,0 +1,37 @@
+module Lrama
+ class Grammar
+ class ParameterizingRule
+ class Rhs
+ attr_accessor :symbols, :user_code, :precedence_sym
+
+ def initialize
+ @symbols = []
+ @user_code = nil
+ @precedence_sym = nil
+ end
+
+ def resolve_user_code(bindings)
+ return unless user_code
+
+ var_to_arg = {}
+ symbols.each do |sym|
+ resolved_sym = bindings.resolve_symbol(sym)
+ if resolved_sym != sym
+ var_to_arg[sym.s_value] = resolved_sym.s_value
+ end
+ end
+
+ var_to_arg.each do |var, arg|
+ user_code.references.each do |ref|
+ if ref.name == var
+ ref.name = arg
+ end
+ end
+ end
+
+ return user_code
+ end
+ end
+ end
+ end
+end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb
new file mode 100644
index 0000000000..38f0fca4ea
--- /dev/null
+++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb
@@ -0,0 +1,18 @@
+module Lrama
+ class Grammar
+ class ParameterizingRule
+ class Rule
+ attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :tag, :is_inline
+
+ def initialize(name, parameters, rhs_list, tag: nil, is_inline: false)
+ @name = name
+ @parameters = parameters
+ @rhs_list = rhs_list
+ @tag = tag
+ @is_inline = is_inline
+ @required_parameters_count = parameters.count
+ end
+ end
+ end
+ end
+end