Module: Ibex::NormalizeParameterValidation
- Included in:
- Normalizer
- Defined in:
- lib/ibex/normalize/parameter_validation.rb,
sig/ibex/normalize/parameter_validation.rbs
Overview
Static validation and collection of parameterized user rule definitions.
Instance Method Summary collapse
- #gather_parameter_templates ⇒ void
- #gather_parameterized_rule(rule, plain_rules) ⇒ void
- #parameter_template?(name) ⇒ Boolean
- #parameterized_rule?(rule) ⇒ Boolean
- #reject_argument_named_reference(item) ⇒ bot
- #reject_mixed_parameterized_rule(rule) ⇒ bot
- #validate_parameter_call(reference) ⇒ void
- #validate_parameter_formals(rule) ⇒ void
- #validate_parameter_item(item, formals, inside_argument:) ⇒ void
- #validate_parameter_references(rule) ⇒ void
- #validate_parameter_terminal_collisions ⇒ void
- #validate_parameterized_item(item, formals, inside_argument:) ⇒ void
Instance Method Details
#gather_parameter_templates ⇒ void
This method returns an undefined value.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 9 def gather_parameter_templates # @type self: Normalizer @parameter_templates = {} #: Hash[String, Array[Frontend::AST::Rule]] @parameter_formals = {} #: Hash[String, Array[String]] plain_rules = {} #: Hash[String, Frontend::AST::Rule] @rule_documentation = validated_rule_documentation @ast.rules.each do |rule| if parameterized_rule?(rule) gather_parameterized_rule(rule, plain_rules) else reject_mixed_parameterized_rule(rule) if @parameter_templates.key?(rule.lhs) plain_rules[rule.lhs] ||= rule end end validate_parameter_terminal_collisions @ast.rules.each { |rule| validate_parameter_references(rule) } end |
#gather_parameterized_rule(rule, plain_rules) ⇒ void
This method returns an undefined value.
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 29 def gather_parameterized_rule(rule, plain_rules) # @type self: Normalizer reject_mixed_parameterized_rule(rule) if plain_rules.key?(rule.lhs) duplicate = rule.parameters.tally.find { |_name, count| count > 1 }&.first fail_at(rule.loc, "duplicate parameter #{duplicate} in rule #{rule.lhs}") if duplicate validate_parameter_formals(rule) @parameter_formals[rule.lhs] ||= rule.parameters (@parameter_templates[rule.lhs] ||= Array.new(0)) << rule end |
#parameter_template?(name) ⇒ Boolean
136 137 138 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 136 def parameter_template?(name) @parameter_templates.key?(name) end |
#parameterized_rule?(rule) ⇒ Boolean
131 132 133 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 131 def parameterized_rule?(rule) !rule.parameters.empty? end |
#reject_argument_named_reference(item) ⇒ bot
111 112 113 114 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 111 def reject_argument_named_reference(item) # @type self: Normalizer fail_at(item.loc, "named references are not allowed in parameter arguments") end |
#reject_mixed_parameterized_rule(rule) ⇒ bot
54 55 56 57 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 54 def reject_mixed_parameterized_rule(rule) # @type self: Normalizer fail_at(rule.loc, "rule #{rule.lhs} has both plain and parameterized definitions") end |
#validate_parameter_call(reference) ⇒ void
This method returns an undefined value.
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 117 def validate_parameter_call(reference) # @type self: Normalizer formals = @parameter_formals[reference.name] fail_at(reference.loc, "undefined parameterized rule #{reference.name}") unless formals return if reference.arguments.length == formals.length fail_at( reference.loc, "parameterized rule #{reference.name} expects #{formals.length} arguments, " \ "got #{reference.arguments.length}" ) end |
#validate_parameter_formals(rule) ⇒ void
This method returns an undefined value.
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 41 def validate_parameter_formals(rule) # @type self: Normalizer expected = @parameter_formals[rule.lhs] return unless expected && expected != rule.parameters fail_at( rule.loc, "parameterized rule #{rule.lhs} uses inconsistent parameters " \ "(expected #{expected.join(', ')}, got #{rule.parameters.join(', ')})" ) end |
#validate_parameter_item(item, formals, inside_argument:) ⇒ void
This method returns an undefined value.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 80 def validate_parameter_item(item, formals, inside_argument:) # @type self: Normalizer case item when Frontend::AST::ParameterizedReference validate_parameterized_item(item, formals, inside_argument: inside_argument) when Frontend::AST::SymbolReference reject_argument_named_reference(item) if inside_argument && item.named_reference when Frontend::AST::Group item.alternatives.flatten.each do |child| validate_parameter_item(child, formals, inside_argument: inside_argument) end when Frontend::AST::Optional, Frontend::AST::Star, Frontend::AST::Plus validate_parameter_item(item.item, formals, inside_argument: inside_argument) when Frontend::AST::SeparatedList validate_parameter_item(item.item, formals, inside_argument: inside_argument) validate_parameter_item(item.separator, formals, inside_argument: inside_argument) end end |
#validate_parameter_references(rule) ⇒ void
This method returns an undefined value.
70 71 72 73 74 75 76 77 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 70 def validate_parameter_references(rule) # @type self: Normalizer rule.alternatives.each do |alternative| alternative.items.each do |item| validate_parameter_item(item, rule.parameters, inside_argument: false) end end end |
#validate_parameter_terminal_collisions ⇒ void
This method returns an undefined value.
60 61 62 63 64 65 66 67 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 60 def validate_parameter_terminal_collisions # @type self: Normalizer @parameter_templates.each do |name, rules| next unless @declared_tokens.key?(name) || @precedence.key?(name) fail_at(rules.fetch(0).loc, "parameterized rule #{name} collides with terminal #{name}") end end |
#validate_parameterized_item(item, formals, inside_argument:) ⇒ void
This method returns an undefined value.
100 101 102 103 104 105 106 107 108 |
# File 'lib/ibex/normalize/parameter_validation.rb', line 100 def validate_parameterized_item(item, formals, inside_argument:) # @type self: Normalizer if formals.include?(item.name) fail_at(item.loc, "formal #{item.name} cannot be used as a parameterized rule name") end validate_parameter_call(item) reject_argument_named_reference(item) if inside_argument && item.named_reference item.arguments.each { |argument| validate_parameter_item(argument, formals, inside_argument: true) } end |