diff --git a/lib/puppet/pops/evaluator/evaluator_impl.rb b/lib/puppet/pops/evaluator/evaluator_impl.rb index 8881ee21b..370f9b0ad 100644 --- a/lib/puppet/pops/evaluator/evaluator_impl.rb +++ b/lib/puppet/pops/evaluator/evaluator_impl.rb @@ -1,1106 +1,1111 @@ require 'rgen/ecore/ecore' require 'puppet/pops/evaluator/compare_operator' require 'puppet/pops/evaluator/relationship_operator' require 'puppet/pops/evaluator/access_operator' require 'puppet/pops/evaluator/closure' require 'puppet/pops/evaluator/external_syntax_support' # This implementation of {Puppet::Pops::Evaluator} performs evaluation using the puppet 3.x runtime system # in a manner largely compatible with Puppet 3.x, but adds new features and introduces constraints. # # The evaluation uses _polymorphic dispatch_ which works by dispatching to the first found method named after # the class or one of its super-classes. The EvaluatorImpl itself mainly deals with evaluation (it currently # also handles assignment), and it uses a delegation pattern to more specialized handlers of some operators # that in turn use polymorphic dispatch; this to not clutter EvaluatorImpl with too much responsibility). # # Since a pattern is used, only the main entry points are fully documented. The parameters _o_ and _scope_ are # the same in all the polymorphic methods, (the type of the parameter _o_ is reflected in the method's name; # either the actual class, or one of its super classes). The _scope_ parameter is always the scope in which # the evaluation takes place. If nothing else is mentioned, the return is always the result of evaluation. # # See {Puppet::Pops::Visitable} and {Puppet::Pops::Visitor} for more information about # polymorphic calling. # class Puppet::Pops::Evaluator::EvaluatorImpl include Puppet::Pops::Utils # Provides access to the Puppet 3.x runtime (scope, etc.) # This separation has been made to make it easier to later migrate the evaluator to an improved runtime. # include Puppet::Pops::Evaluator::Runtime3Support include Puppet::Pops::Evaluator::ExternalSyntaxSupport # This constant is not defined as Float::INFINITY in Ruby 1.8.7 (but is available in later version # Refactor when support is dropped for Ruby 1.8.7. # INFINITY = 1.0 / 0.0 EMPTY_STRING = ''.freeze COMMA_SEPARATOR = ', '.freeze # Reference to Issues name space makes it easier to refer to issues # (Issues are shared with the validator). # Issues = Puppet::Pops::Issues def initialize @@eval_visitor ||= Puppet::Pops::Visitor.new(self, "eval", 1, 1) @@lvalue_visitor ||= Puppet::Pops::Visitor.new(self, "lvalue", 1, 1) @@assign_visitor ||= Puppet::Pops::Visitor.new(self, "assign", 3, 3) @@string_visitor ||= Puppet::Pops::Visitor.new(self, "string", 1, 1) @@type_calculator ||= Puppet::Pops::Types::TypeCalculator.new() @@type_parser ||= Puppet::Pops::Types::TypeParser.new() @@compare_operator ||= Puppet::Pops::Evaluator::CompareOperator.new() @@relationship_operator ||= Puppet::Pops::Evaluator::RelationshipOperator.new() # Initialize the runtime module Puppet::Pops::Evaluator::Runtime3Support.instance_method(:initialize).bind(self).call() end # @api private def type_calculator @@type_calculator end # Evaluates the given _target_ object in the given scope. # # @overload evaluate(target, scope) # @param target [Object] evaluation target - see methods on the pattern assign_TYPE for actual supported types. # @param scope [Object] the runtime specific scope class where evaluation should take place # @return [Object] the result of the evaluation # # @api public # def evaluate(target, scope) begin @@eval_visitor.visit_this_1(self, target, scope) rescue Puppet::Pops::SemanticError => e # a raised issue may not know the semantic target fail(e.issue, e.semantic || target, e.options, e) rescue StandardError => e if e.is_a? Puppet::ParseError # ParseError's are supposed to be fully configured with location information raise e end fail(Issues::RUNTIME_ERROR, target, {:detail => e.message}, e) end end # Assigns the given _value_ to the given _target_. The additional argument _o_ is the instruction that # produced the target/value tuple and it is used to set the origin of the result. # # @param target [Object] assignment target - see methods on the pattern assign_TYPE for actual supported types. # @param value [Object] the value to assign to `target` # @param o [Puppet::Pops::Model::PopsObject] originating instruction # @param scope [Object] the runtime specific scope where evaluation should take place # # @api private # def assign(target, value, o, scope) @@assign_visitor.visit_this_3(self, target, value, o, scope) end # Computes a value that can be used as the LHS in an assignment. # @param o [Object] the expression to evaluate as a left (assignable) entity # @param scope [Object] the runtime specific scope where evaluation should take place # # @api private # def lvalue(o, scope) @@lvalue_visitor.visit_this_1(self, o, scope) end # Produces a String representation of the given object _o_ as used in interpolation. # @param o [Object] the expression of which a string representation is wanted # @param scope [Object] the runtime specific scope where evaluation should take place # # @api public # def string(o, scope) @@string_visitor.visit_this_1(self, o, scope) end # Evaluate a BlockExpression in a new scope with variables bound to the # given values. # # @param scope [Puppet::Parser::Scope] the parent scope # @param variable_bindings [Hash{String => Object}] the variable names and values to bind (names are keys, bound values are values) # @param block [Puppet::Pops::Model::BlockExpression] the sequence of expressions to evaluate in the new scope # # @api private # def evaluate_block_with_bindings(scope, variable_bindings, block_expr) with_guarded_scope(scope) do # change to create local scope_from - cannot give it file and line - # that is the place of the call, not "here" create_local_scope_from(variable_bindings, scope) evaluate(block_expr, scope) end end protected def lvalue_VariableExpression(o, scope) # evaluate the name evaluate(o.expr, scope) end # Catches all illegal lvalues # def lvalue_Object(o, scope) fail(Issues::ILLEGAL_ASSIGNMENT, o) end # Assign value to named variable. # The '$' sign is never part of the name. # @example In Puppet DSL # $name = value # @param name [String] name of variable without $ # @param value [Object] value to assign to the variable # @param o [Puppet::Pops::Model::PopsObject] originating instruction # @param scope [Object] the runtime specific scope where evaluation should take place # @return [value] # def assign_String(name, value, o, scope) if name =~ /::/ fail(Issues::CROSS_SCOPE_ASSIGNMENT, o.left_expr, {:name => name}) end set_variable(name, value, o, scope) value end def assign_Numeric(n, value, o, scope) fail(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o.left_expr, {:varname => n.to_s}) end # Catches all illegal assignment (e.g. 1 = 2, {'a'=>1} = 2, etc) # def assign_Object(name, value, o, scope) fail(Issues::ILLEGAL_ASSIGNMENT, o) end def eval_Factory(o, scope) evaluate(o.current, scope) end # Evaluates any object not evaluated to something else to itself. def eval_Object o, scope o end # Allows nil to be used as a Nop, Evaluates to nil def eval_NilClass(o, scope) nil end # Evaluates Nop to nil. def eval_Nop(o, scope) nil end # Captures all LiteralValues not handled elsewhere. # def eval_LiteralValue(o, scope) o.value end # Reserved Words fail to evaluate # def eval_ReservedWord(o, scope) fail(Puppet::Pops::Issues::RESERVED_WORD, o, {:word => o.word}) end def eval_LiteralDefault(o, scope) :default end def eval_LiteralUndef(o, scope) nil end # A QualifiedReference (i.e. a capitalized qualified name such as Foo, or Foo::Bar) evaluates to a PType # def eval_QualifiedReference(o, scope) @@type_parser.interpret(o) end def eval_NotExpression(o, scope) ! is_true?(evaluate(o.expr, scope)) end def eval_UnaryMinusExpression(o, scope) - coerce_numeric(evaluate(o.expr, scope), o, scope) end def eval_UnfoldExpression(o, scope) candidate = evaluate(o.expr, scope) case candidate when Array candidate when Hash candidate.to_a else # turns anything else into an array (so result can be unfolded) [candidate] end end # Abstract evaluation, returns array [left, right] with the evaluated result of left_expr and # right_expr # @return > array with result of evaluating left and right expressions # def eval_BinaryExpression o, scope [ evaluate(o.left_expr, scope), evaluate(o.right_expr, scope) ] end # Evaluates assignment with operators =, +=, -= and # # @example Puppet DSL # $a = 1 # $a += 1 # $a -= 1 # def eval_AssignmentExpression(o, scope) name = lvalue(o.left_expr, scope) value = evaluate(o.right_expr, scope) if o.operator == :'=' assign(name, value, o, scope) else fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator}) end value end ARITHMETIC_OPERATORS = [:'+', :'-', :'*', :'/', :'%', :'<<', :'>>'] COLLECTION_OPERATORS = [:'+', :'-', :'<<'] # Handles binary expression where lhs and rhs are array/hash or numeric and operator is +, - , *, % / << >> # def eval_ArithmeticExpression(o, scope) left = evaluate(o.left_expr, scope) right = evaluate(o.right_expr, scope) begin result = calculate(left, right, o.operator, o.left_expr, o.right_expr, scope) rescue ArgumentError => e fail(Issues::RUNTIME_ERROR, o, {:detail => e.message}, e) end result end # Handles binary expression where lhs and rhs are array/hash or numeric and operator is +, - , *, % / << >> # def calculate(left, right, operator, left_o, right_o, scope) unless ARITHMETIC_OPERATORS.include?(operator) fail(Issues::UNSUPPORTED_OPERATOR, left_o.eContainer, {:operator => o.operator}) end if (left.is_a?(Array) || left.is_a?(Hash)) && COLLECTION_OPERATORS.include?(operator) # Handle operation on collections case operator when :'+' concatenate(left, right) when :'-' delete(left, right) when :'<<' unless left.is_a?(Array) fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left}) end left + [right] end else # Handle operation on numeric left = coerce_numeric(left, left_o, scope) right = coerce_numeric(right, right_o, scope) begin if operator == :'%' && (left.is_a?(Float) || right.is_a?(Float)) # Deny users the fun of seeing severe rounding errors and confusing results fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left}) end result = left.send(operator, right) rescue NoMethodError => e fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left}) rescue ZeroDivisionError => e fail(Issues::DIV_BY_ZERO, right_o) end if result == INFINITY || result == -INFINITY fail(Issues::RESULT_IS_INFINITY, left_o, {:operator => operator}) end result end end def eval_EppExpression(o, scope) scope["@epp"] = [] evaluate(o.body, scope) result = scope["@epp"].join result end def eval_RenderStringExpression(o, scope) scope["@epp"] << o.value.dup nil end def eval_RenderExpression(o, scope) scope["@epp"] << string(evaluate(o.expr, scope), scope) nil end # Evaluates Puppet DSL ->, ~>, <-, and <~ def eval_RelationshipExpression(o, scope) # First level evaluation, reduction to basic data types or puppet types, the relationship operator then translates this # to the final set of references (turning strings into references, which can not naturally be done by the main evaluator since # all strings should not be turned into references. # real = eval_BinaryExpression(o, scope) @@relationship_operator.evaluate(real, o, scope) end # Evaluates x[key, key, ...] # def eval_AccessExpression(o, scope) left = evaluate(o.left_expr, scope) keys = o.keys.nil? ? [] : o.keys.collect {|key| evaluate(key, scope) } Puppet::Pops::Evaluator::AccessOperator.new(o).access(left, scope, *keys) end # Evaluates <, <=, >, >=, and == # def eval_ComparisonExpression o, scope left = evaluate(o.left_expr, scope) right = evaluate(o.right_expr, scope) begin # Left is a type if left.is_a?(Puppet::Pops::Types::PAnyType) case o.operator when :'==' @@type_calculator.equals(left,right) when :'!=' !@@type_calculator.equals(left,right) when :'<' # left can be assigned to right, but they are not equal @@type_calculator.assignable?(right, left) && ! @@type_calculator.equals(left,right) when :'<=' # left can be assigned to right @@type_calculator.assignable?(right, left) when :'>' # right can be assigned to left, but they are not equal @@type_calculator.assignable?(left,right) && ! @@type_calculator.equals(left,right) when :'>=' # right can be assigned to left @@type_calculator.assignable?(left, right) else fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator}) end else case o.operator when :'==' @@compare_operator.equals(left,right) when :'!=' ! @@compare_operator.equals(left,right) when :'<' @@compare_operator.compare(left,right) < 0 when :'<=' @@compare_operator.compare(left,right) <= 0 when :'>' @@compare_operator.compare(left,right) > 0 when :'>=' @@compare_operator.compare(left,right) >= 0 else fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator}) end end rescue ArgumentError => e fail(Issues::COMPARISON_NOT_POSSIBLE, o, { :operator => o.operator, :left_value => left, :right_value => right, :detail => e.message}, e) end end # Evaluates matching expressions with type, string or regexp rhs expression. # If RHS is a type, the =~ matches compatible (instance? of) type. # # @example # x =~ /abc.*/ # @example # x =~ "abc.*/" # @example # y = "abc" # x =~ "${y}.*" # @example # [1,2,3] =~ Array[Integer[1,10]] # # Note that a string is not instance? of Regexp, only Regular expressions are. # The Pattern type should instead be used as it is specified as subtype of String. # # @return [Boolean] if a match was made or not. Also sets $0..$n to matchdata in current scope. # def eval_MatchExpression o, scope left = evaluate(o.left_expr, scope) pattern = evaluate(o.right_expr, scope) # matches RHS types as instance of for all types except a parameterized Regexp[R] if pattern.is_a?(Puppet::Pops::Types::PAnyType) # evaluate as instance? of type check matched = @@type_calculator.instance?(pattern, left) # convert match result to Boolean true, or false return o.operator == :'=~' ? !!matched : !matched end begin pattern = Regexp.new(pattern) unless pattern.is_a?(Regexp) rescue StandardError => e fail(Issues::MATCH_NOT_REGEXP, o.right_expr, {:detail => e.message}, e) end unless left.is_a?(String) fail(Issues::MATCH_NOT_STRING, o.left_expr, {:left_value => left}) end matched = pattern.match(left) # nil, or MatchData set_match_data(matched,scope) # creates ephemeral # convert match result to Boolean true, or false o.operator == :'=~' ? !!matched : !matched end # Evaluates Puppet DSL `in` expression # def eval_InExpression o, scope left = evaluate(o.left_expr, scope) right = evaluate(o.right_expr, scope) @@compare_operator.include?(right, left, scope) end # @example # $a and $b # b is only evaluated if a is true # def eval_AndExpression o, scope is_true?(evaluate(o.left_expr, scope)) ? is_true?(evaluate(o.right_expr, scope)) : false end # @example # a or b # b is only evaluated if a is false # def eval_OrExpression o, scope is_true?(evaluate(o.left_expr, scope)) ? true : is_true?(evaluate(o.right_expr, scope)) end # Evaluates each entry of the literal list and creates a new Array # Supports unfolding of entries # @return [Array] with the evaluated content # def eval_LiteralList o, scope unfold([], o.values, scope) end # Evaluates each entry of the literal hash and creates a new Hash. # @return [Hash] with the evaluated content # def eval_LiteralHash o, scope # optimized o.entries.reduce({}) {|h,entry| h[evaluate(entry.key, scope)] = evaluate(entry.value, scope); h } end # Evaluates all statements and produces the last evaluated value # def eval_BlockExpression o, scope r = nil o.statements.each {|s| r = evaluate(s, scope)} r end # Performs optimized search over case option values, lazily evaluating each # until there is a match. If no match is found, the case expression's default expression # is evaluated (it may be nil or Nop if there is no default, thus producing nil). # If an option matches, the result of evaluating that option is returned. # @return [Object, nil] what a matched option returns, or nil if nothing matched. # def eval_CaseExpression(o, scope) # memo scope level before evaluating test - don't want a match in the case test to leak $n match vars # to expressions after the case expression. # with_guarded_scope(scope) do test = evaluate(o.test, scope) result = nil the_default = nil if o.options.find do |co| # the first case option that matches if co.values.find do |c| case c when Puppet::Pops::Model::LiteralDefault the_default = co.then_expr is_match?(test, evaluate(c, scope), c, scope) when Puppet::Pops::Model::UnfoldExpression # not ideal for error reporting, since it is not known which unfolded result # that caused an error - the entire unfold expression is blamed (i.e. the var c, passed to is_match?) evaluate(c, scope).any? {|v| is_match?(test, v, c, scope) } else is_match?(test, evaluate(c, scope), c, scope) end end result = evaluate(co.then_expr, scope) true # the option was picked end end result # an option was picked, and produced a result else evaluate(the_default, scope) # evaluate the default (should be a nop/nil) if there is no default). end end end # Evaluates a CollectExpression by transforming it into a 3x AST::Collection and then evaluating that. # This is done because of the complex API between compiler, indirector, backends, and difference between # collecting virtual resources and exported resources. # def eval_CollectExpression o, scope # The Collect Expression and its contained query expressions are implemented in such a way in # 3x that it is almost impossible to do anything about them (the AST objects are lazily evaluated, # and the built structure consists of both higher order functions and arrays with query expressions # that are either used as a predicate filter, or given to an indirection terminus (such as the Puppet DB # resource terminus). Unfortunately, the 3x implementation has many inconsistencies that the implementation # below carries forward. # collect_3x = Puppet::Pops::Model::AstTransformer.new().transform(o) collected = collect_3x.evaluate(scope) # the 3x returns an instance of Parser::Collector (but it is only registered with the compiler at this # point and does not contain any valuable information (like the result) # Dilemma: If this object is returned, it is a first class value in the Puppet Language and we # need to be able to perform operations on it. We can forbid it from leaking by making CollectExpression # a non R-value. This makes it possible for the evaluator logic to make use of the Collector. collected end def eval_ParenthesizedExpression(o, scope) evaluate(o.expr, scope) end # This evaluates classes, nodes and resource type definitions to nil, since 3x: # instantiates them, and evaluates their parameters and body. This is achieved by # providing bridge AST classes in Puppet::Parser::AST::PopsBridge that bridges a # Pops Program and a Pops Expression. # # Since all Definitions are handled "out of band", they are treated as a no-op when # evaluated. # def eval_Definition(o, scope) nil end def eval_Program(o, scope) evaluate(o.body, scope) end # Produces Array[PAnyType], an array of resource references # def eval_ResourceExpression(o, scope) exported = o.exported virtual = o.virtual # Get the type name type_name = if (tmp_name = o.type_name).is_a?(Puppet::Pops::Model::QualifiedName) tmp_name.value # already validated as a name else evaluated_name = evaluate(tmp_name, scope) # must be String or Resource Type case evaluated_name when String resulting_name = evaluated_name.downcase if resulting_name !~ Puppet::Pops::Patterns::CLASSREF fail(Puppet::Pops::Issues::ILLEGAL_CLASSREF, o.type_name, {:name=>resulting_name}) end resulting_name when Puppet::Pops::Types::PHostClassType unless evaluated_name.class_name.nil? fail(Puppet::Pops::Issues::ILLEGAL_RESOURCE_TYPE, o.type_name, {:actual=> evaluated_name.to_s}) end 'class' when Puppet::Pops::Types::PResourceType unless evaluated_name.title().nil? fail(Puppet::Pops::Issues::ILLEGAL_RESOURCE_TYPE, o.type_name, {:actual=> evaluated_name.to_s}) end evaluated_name.type_name # assume validated else actual = type_calculator.generalize!(type_calculator.infer(evaluated_name)).to_s fail(Puppet::Pops::Issues::ILLEGAL_RESOURCE_TYPE, o.type_name, {:actual=>actual}) end end # This is a runtime check - the model is valid, but will have runtime issues when evaluated # and storeconfigs is not set. #if acceptor.will_accept?(Issues::RT_NO_STORECONFIGS) && o.exported if(o.exported) optionally_fail(Puppet::Pops::Issues::RT_NO_STORECONFIGS_EXPORT, o); end titles_to_body = {} body_to_titles = {} body_to_params = {} # titles are evaluated before attribute operations o.bodies.map do | body | titles = evaluate(body.title, scope) # Title may not be nil # Titles may be given as an array, it is ok if it is empty, but not if it contains nil entries # Titles may not be an empty String # Titles must be unique in the same resource expression # There may be a :default entry, its entries apply with lower precedence # if titles.nil? fail(Puppet::Pops::Issues::MISSING_TITLE, body.title) end titles = [titles].flatten # Check types of evaluated titles and duplicate entries titles.each_with_index do |title, index| if title.nil? fail(Puppet::Pops::Issues::MISSING_TITLE_AT, body.title, {:index => index}) elsif !title.is_a?(String) && title != :default actual = type_calculator.generalize!(type_calculator.infer(title)).to_s fail(Puppet::Pops::Issues::ILLEGAL_TITLE_TYPE_AT, body.title, {:index => index, :actual => actual}) elsif title == EMPTY_STRING fail(Puppet::Pops::Issues::EMPTY_STRING_TITLE_AT, body.title, {:index => index}) elsif titles_to_body[title] fail(Puppet::Pops::Issues::DUPLICATE_TITLE, o, {:title => title}) end titles_to_body[title] = body end # Do not create a real instance from the :default case titles.delete(:default) body_to_titles[body] = titles # Store evaluated parameters in a hash associated with the body, but do not yet create resource # since the entry containing :defaults may appear later body_to_params[body] = body.operations.reduce({}) do |param_memo, op| params = evaluate(op, scope) params = [params] unless params.is_a?(Array) - params.each { |p| param_memo[p.name] = p } + params.each do |p| + if param_memo.include? p.name + fail(Puppet::Pops::Issues::DUPLICATE_ATTRIBUTE, o, {:attribute => p.name}) + end + param_memo[p.name] = p + end param_memo end end # Titles and Operations have now been evaluated and resources can be created # Each production is a PResource, and an array of all is produced as the result of # evaluating the ResourceExpression. # defaults_hash = body_to_params[titles_to_body[:default]] || {} o.bodies.map do | body | titles = body_to_titles[body] params = defaults_hash.merge(body_to_params[body] || {}) create_resources(o, scope, virtual, exported, type_name, titles, params.values) end.flatten.compact end def eval_ResourceOverrideExpression(o, scope) evaluated_resources = evaluate(o.resources, scope) evaluated_parameters = o.operations.map { |op| evaluate(op, scope) } create_resource_overrides(o, scope, [evaluated_resources].flatten, evaluated_parameters) evaluated_resources end # Produces 3x parameter def eval_AttributeOperation(o, scope) create_resource_parameter(o, scope, o.attribute_name, evaluate(o.value_expr, scope), o.operator) end def eval_AttributesOperation(o, scope) hashed_params = evaluate(o.expr, scope) unless hashed_params.is_a?(Hash) actual = type_calculator.generalize!(type_calculator.infer(hashed_params)).to_s fail(Puppet::Pops::Issues::TYPE_MISMATCH, o.expr, {:expected => 'Hash', :actual => actual}) end hashed_params.map { |k,v| create_resource_parameter(o, scope, k, v, :'=>') } end # Sets default parameter values for a type, produces the type # def eval_ResourceDefaultsExpression(o, scope) type = evaluate(o.type_ref, scope) type_name = if type.is_a?(Puppet::Pops::Types::PResourceType) && !type.type_name.nil? && type.title.nil? type.type_name # assume it is a valid name else actual = type_calculator.generalize!(type_calculator.infer(type)) fail(Issues::ILLEGAL_RESOURCE_TYPE, o.type_ref, {:actual => actual}) end evaluated_parameters = o.operations.map {|op| evaluate(op, scope) } create_resource_defaults(o, scope, type_name, evaluated_parameters) # Produce the type type end # Evaluates function call by name. # def eval_CallNamedFunctionExpression(o, scope) # The functor expression is not evaluated, it is not possible to select the function to call # via an expression like $a() case o.functor_expr when Puppet::Pops::Model::QualifiedName # ok when Puppet::Pops::Model::RenderStringExpression # helpful to point out this easy to make Epp error fail(Issues::ILLEGAL_EPP_PARAMETERS, o) else fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o}) end name = o.functor_expr.value evaluated_arguments = unfold([], o.arguments, scope) # wrap lambda in a callable block if it is present evaluated_arguments << Puppet::Pops::Evaluator::Closure.new(self, o.lambda, scope) if o.lambda call_function(name, evaluated_arguments, o, scope) end # Evaluation of CallMethodExpression handles a NamedAccessExpression functor (receiver.function_name) # def eval_CallMethodExpression(o, scope) unless o.functor_expr.is_a? Puppet::Pops::Model::NamedAccessExpression fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function accessor', :container => o}) end receiver = evaluate(o.functor_expr.left_expr, scope) name = o.functor_expr.right_expr unless name.is_a? Puppet::Pops::Model::QualifiedName fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o}) end name = name.value # the string function name evaluated_arguments = unfold([receiver], o.arguments || [], scope) # wrap lambda in a callable block if it is present evaluated_arguments << Puppet::Pops::Evaluator::Closure.new(self, o.lambda, scope) if o.lambda call_function(name, evaluated_arguments, o, scope) end # @example # $x ? { 10 => true, 20 => false, default => 0 } # def eval_SelectorExpression o, scope # memo scope level before evaluating test - don't want a match in the case test to leak $n match vars # to expressions after the selector expression. # with_guarded_scope(scope) do test = evaluate(o.left_expr, scope) the_default = nil selected = o.selectors.find do |s| me = s.matching_expr case me when Puppet::Pops::Model::LiteralDefault the_default = s.value_expr false when Puppet::Pops::Model::UnfoldExpression # not ideal for error reporting, since it is not known which unfolded result # that caused an error - the entire unfold expression is blamed (i.e. the var c, passed to is_match?) evaluate(me, scope).any? {|v| is_match?(test, v, me, scope) } else is_match?(test, evaluate(me, scope), me, scope) end end if selected evaluate(selected.value_expr, scope) elsif the_default evaluate(the_default, scope) else fail(Issues::UNMATCHED_SELECTOR, o.left_expr, :param_value => test) end end end # SubLocatable is simply an expression that holds location information def eval_SubLocatedExpression o, scope evaluate(o.expr, scope) end # Evaluates Puppet DSL Heredoc def eval_HeredocExpression o, scope result = evaluate(o.text_expr, scope) assert_external_syntax(scope, result, o.syntax, o.text_expr) result end # Evaluates Puppet DSL `if` def eval_IfExpression o, scope with_guarded_scope(scope) do if is_true?(evaluate(o.test, scope)) evaluate(o.then_expr, scope) else evaluate(o.else_expr, scope) end end end # Evaluates Puppet DSL `unless` def eval_UnlessExpression o, scope with_guarded_scope(scope) do unless is_true?(evaluate(o.test, scope)) evaluate(o.then_expr, scope) else evaluate(o.else_expr, scope) end end end # Evaluates a variable (getting its value) # The evaluator is lenient; any expression producing a String is used as a name # of a variable. # def eval_VariableExpression o, scope # Evaluator is not too fussy about what constitutes a name as long as the result # is a String and a valid variable name # name = evaluate(o.expr, scope) # Should be caught by validation, but make this explicit here as well, or mysterious evaluation issues # may occur for some evaluation use cases. case name when String when Numeric else fail(Issues::ILLEGAL_VARIABLE_EXPRESSION, o.expr) end get_variable_value(name, o, scope) end # Evaluates double quoted strings that may contain interpolation # def eval_ConcatenatedString o, scope o.segments.collect {|expr| string(evaluate(expr, scope), scope)}.join end # If the wrapped expression is a QualifiedName, it is taken as the name of a variable in scope. # Note that this is different from the 3.x implementation, where an initial qualified name # is accepted. (e.g. `"---${var + 1}---"` is legal. This implementation requires such concrete # syntax to be expressed in a model as `(TextExpression (+ (Variable var) 1)` - i.e. moving the decision to # the parser. # # Semantics; the result of an expression is turned into a string, nil is silently transformed to empty # string. # @return [String] the interpolated result # def eval_TextExpression o, scope if o.expr.is_a?(Puppet::Pops::Model::QualifiedName) string(get_variable_value(o.expr.value, o, scope), scope) else string(evaluate(o.expr, scope), scope) end end def string_Object(o, scope) o.to_s end def string_Symbol(o, scope) if :undef == o # optimized comparison 1.44 vs 1.95 EMPTY_STRING else o.to_s end end def string_Array(o, scope) "[#{o.map {|e| string(e, scope)}.join(COMMA_SEPARATOR)}]" end def string_Hash(o, scope) "{#{o.map {|k,v| "#{string(k, scope)} => #{string(v, scope)}"}.join(COMMA_SEPARATOR)}}" end def string_Regexp(o, scope) "/#{o.source}/" end def string_PAnyType(o, scope) @@type_calculator.string(o) end # Produces concatenation / merge of x and y. # # When x is an Array, y of type produces: # # * Array => concatenation `[1,2], [3,4] => [1,2,3,4]` # * Hash => concatenation of hash as array `[key, value, key, value, ...]` # * any other => concatenation of single value # # When x is a Hash, y of type produces: # # * Array => merge of array interpreted as `[key, value, key, value,...]` # * Hash => a merge, where entries in `y` overrides # * any other => error # # When x is something else, wrap it in an array first. # # When x is nil, an empty array is used instead. # # @note to concatenate an Array, nest the array - i.e. `[1,2], [[2,3]]` # # @overload concatenate(obj_x, obj_y) # @param obj_x [Object] object to wrap in an array and concatenate to; see other overloaded methods for return type # @param ary_y [Object] array to concatenate at end of `ary_x` # @return [Object] wraps obj_x in array before using other overloaded option based on type of obj_y # @overload concatenate(ary_x, ary_y) # @param ary_x [Array] array to concatenate to # @param ary_y [Array] array to concatenate at end of `ary_x` # @return [Array] new array with `ary_x` + `ary_y` # @overload concatenate(ary_x, hsh_y) # @param ary_x [Array] array to concatenate to # @param hsh_y [Hash] converted to array form, and concatenated to array # @return [Array] new array with `ary_x` + `hsh_y` converted to array # @overload concatenate (ary_x, obj_y) # @param ary_x [Array] array to concatenate to # @param obj_y [Object] non array or hash object to add to array # @return [Array] new array with `ary_x` + `obj_y` added as last entry # @overload concatenate(hsh_x, ary_y) # @param hsh_x [Hash] the hash to merge with # @param ary_y [Array] array interpreted as even numbered sequence of key, value merged with `hsh_x` # @return [Hash] new hash with `hsh_x` merged with `ary_y` interpreted as hash in array form # @overload concatenate(hsh_x, hsh_y) # @param hsh_x [Hash] the hash to merge to # @param hsh_y [Hash] hash merged with `hsh_x` # @return [Hash] new hash with `hsh_x` merged with `hsh_y` # @raise [ArgumentError] when `xxx_x` is neither an Array nor a Hash # @raise [ArgumentError] when `xxx_x` is a Hash, and `xxx_y` is neither Array nor Hash. # def concatenate(x, y) x = [x] unless x.is_a?(Array) || x.is_a?(Hash) case x when Array y = case y when Array then y when Hash then y.to_a else [y] end x + y # new array with concatenation when Hash y = case y when Hash then y when Array # Hash[[a, 1, b, 2]] => {} # Hash[a,1,b,2] => {a => 1, b => 2} # Hash[[a,1], [b,2]] => {[a,1] => [b,2]} # Hash[[[a,1], [b,2]]] => {a => 1, b => 2} # Use type calcultor to determine if array is Array[Array[?]], and if so use second form # of call t = @@type_calculator.infer(y) if t.element_type.is_a? Puppet::Pops::Types::PArrayType Hash[y] else Hash[*y] end else raise ArgumentError.new("Can only append Array or Hash to a Hash") end x.merge y # new hash with overwrite else raise ArgumentError.new("Can only append to an Array or a Hash.") end end # Produces the result x \ y (set difference) # When `x` is an Array, `y` is transformed to an array and then all matching elements removed from x. # When `x` is a Hash, all contained keys are removed from x as listed in `y` if it is an Array, or all its keys if it is a Hash. # The difference is returned. The given `x` and `y` are not modified by this operation. # @raise [ArgumentError] when `x` is neither an Array nor a Hash # def delete(x, y) result = x.dup case x when Array y = case y when Array then y when Hash then y.to_a else [y] end y.each {|e| result.delete(e) } when Hash y = case y when Array then y when Hash then y.keys else [y] end y.each {|e| result.delete(e) } else raise ArgumentError.new("Can only delete from an Array or Hash.") end result end # Implementation of case option matching. # # This is the type of matching performed in a case option, using == for every type # of value except regular expression where a match is performed. # def is_match? left, right, o, scope if right.is_a?(Regexp) return false unless left.is_a? String matched = right.match(left) set_match_data(matched, scope) # creates or clears ephemeral !!matched # convert to boolean elsif right.is_a?(Puppet::Pops::Types::PAnyType) # right is a type and left is not - check if left is an instance of the given type # (The reverse is not terribly meaningful - computing which of the case options that first produces # an instance of a given type). # @@type_calculator.instance?(right, left) else # Handle equality the same way as the language '==' operator (case insensitive etc.) @@compare_operator.equals(left,right) end end def with_guarded_scope(scope) scope_memo = get_scope_nesting_level(scope) begin yield ensure set_scope_nesting_level(scope, scope_memo) end end # Maps the expression in the given array to their product except for UnfoldExpressions which are first unfolded. # The result is added to the given result Array. # @param result [Array] Where to add the result (may contain information to add to) # @param array [Array[Puppet::Pops::Model::Expression] the expressions to map # @param scope [Puppet::Parser::Scope] the scope to evaluate in # @return [Array] the given result array with content added from the operation # def unfold(result, array, scope) array.each do |x| if x.is_a?(Puppet::Pops::Model::UnfoldExpression) result.concat(evaluate(x, scope)) else result << evaluate(x, scope) end end result end private :unfold end diff --git a/lib/puppet/pops/issues.rb b/lib/puppet/pops/issues.rb index 20bb68a8e..e93cbc76a 100644 --- a/lib/puppet/pops/issues.rb +++ b/lib/puppet/pops/issues.rb @@ -1,549 +1,553 @@ # Defines classes to deal with issues, and message formatting and defines constants with Issues. # @api public # module Puppet::Pops::Issues # Describes an issue, and can produce a message for an occurrence of the issue. # class Issue # The issue code # @return [Symbol] attr_reader :issue_code # A block producing the message # @return [Proc] attr_reader :message_block # Names that must be bound in an occurrence of the issue to be able to produce a message. # These are the names in addition to requirements stipulated by the Issue formatter contract; i.e. :label`, # and `:semantic`. # attr_reader :arg_names # If this issue can have its severity lowered to :warning, :deprecation, or :ignored attr_writer :demotable # Configures the Issue with required arguments (bound by occurrence), and a block producing a message. def initialize issue_code, *args, &block @issue_code = issue_code @message_block = block @arg_names = args @demotable = true end # Returns true if it is allowed to demote this issue def demotable? @demotable end # Formats a message for an occurrence of the issue with argument bindings passed in a hash. # The hash must contain a LabelProvider bound to the key `label` and the semantic model element # bound to the key `semantic`. All required arguments as specified by `arg_names` must be bound # in the given `hash`. # @api public # def format(hash ={}) # Create a Message Data where all hash keys become methods for convenient interpolation # in issue text. msgdata = MessageData.new(*arg_names) begin # Evaluate the message block in the msg data's binding msgdata.format(hash, &message_block) rescue StandardError => e Puppet::Pops::Issues::MessageData raise RuntimeError, "Error while reporting issue: #{issue_code}. #{e.message}", caller end end end # Provides a binding of arguments passed to Issue.format to method names available # in the issue's message producing block. # @api private # class MessageData def initialize *argnames singleton = class << self; self end argnames.each do |name| singleton.send(:define_method, name) do @data[name] end end end def format(hash, &block) @data = hash instance_eval &block end # Returns the label provider given as a key in the hash passed to #format. # If given an argument, calls #label on the label provider (caller would otherwise have to # call label.label(it) # def label(it = nil) raise "Label provider key :label must be set to produce the text of the message!" unless @data[:label] it.nil? ? @data[:label] : @data[:label].label(it) end # Returns the label provider given as a key in the hash passed to #format. # def semantic raise "Label provider key :semantic must be set to produce the text of the message!" unless @data[:semantic] @data[:semantic] end end # Defines an issue with the given `issue_code`, additional required parameters, and a block producing a message. # The block is evaluated in the context of a MessageData which provides convenient access to all required arguments # via accessor methods. In addition to accessors for specified arguments, these are also available: # * `label` - a `LabelProvider` that provides human understandable names for model elements and production of article (a/an/the). # * `semantic` - the model element for which the issue is reported # # @param issue_code [Symbol] the issue code for the issue used as an identifier, should be the same as the constant # the issue is bound to. # @param args [Symbol] required arguments that must be passed when formatting the message, may be empty # @param block [Proc] a block producing the message string, evaluated in a MessageData scope. The produced string # should not end with a period as additional information may be appended. # # @see MessageData # @api public # def self.issue (issue_code, *args, &block) Issue.new(issue_code, *args, &block) end # Creates a non demotable issue. # @see Issue.issue # def self.hard_issue(issue_code, *args, &block) result = Issue.new(issue_code, *args, &block) result.demotable = false result end # @comment Here follows definitions of issues. The intent is to provide a list from which yardoc can be generated # containing more detailed information / explanation of the issue. # These issues are set as constants, but it is unfortunately not possible for the created object to easily know which # name it is bound to. Instead the constant has to be repeated. (Alternatively, it could be done by instead calling # #const_set on the module, but the extra work required to get yardoc output vs. the extra effort to repeat the name # twice makes it not worth it (if doable at all, since there is no tag to artificially construct a constant, and # the parse tag does not produce any result for a constant assignment). # This is allowed (3.1) and has not yet been deprecated. # @todo configuration # NAME_WITH_HYPHEN = issue :NAME_WITH_HYPHEN, :name do "#{label.a_an_uc(semantic)} may not have a name containing a hyphen. The name '#{name}' is not legal" end # When a variable name contains a hyphen and these are illegal. # It is possible to control if a hyphen is legal in a name or not using the setting TODO # @todo describe the setting # @api public # @todo configuration if this is error or warning # VAR_WITH_HYPHEN = issue :VAR_WITH_HYPHEN, :name do "A variable name may not contain a hyphen. The name '#{name}' is not legal" end # A class, definition, or node may only appear at top level or inside other classes # @todo Is this really true for nodes? Can they be inside classes? Isn't that too late? # @api public # NOT_TOP_LEVEL = hard_issue :NOT_TOP_LEVEL do "Classes, definitions, and nodes may only appear at toplevel or inside other classes" end CROSS_SCOPE_ASSIGNMENT = hard_issue :CROSS_SCOPE_ASSIGNMENT, :name do "Illegal attempt to assign to '#{name}'. Cannot assign to variables in other namespaces" end # Assignment can only be made to certain types of left hand expressions such as variables. ILLEGAL_ASSIGNMENT = hard_issue :ILLEGAL_ASSIGNMENT do "Illegal attempt to assign to '#{label.a_an(semantic)}'. Not an assignable reference" end # Variables are immutable, cannot reassign in the same assignment scope ILLEGAL_REASSIGNMENT = hard_issue :ILLEGAL_REASSIGNMENT, :name do "Cannot reassign variable #{name}" end ILLEGAL_RESERVED_ASSIGNMENT = hard_issue :ILLEGAL_RESERVED_ASSIGNMENT, :name do "Attempt to assign to a reserved variable name: '#{name}'" end # Assignment cannot be made to numeric match result variables ILLEGAL_NUMERIC_ASSIGNMENT = issue :ILLEGAL_NUMERIC_ASSIGNMENT, :varname do "Illegal attempt to assign to the numeric match result variable '$#{varname}'. Numeric variables are not assignable" end APPEND_FAILED = issue :APPEND_FAILED, :message do "Append assignment += failed with error: #{message}" end DELETE_FAILED = issue :DELETE_FAILED, :message do "'Delete' assignment -= failed with error: #{message}" end # parameters cannot have numeric names, clashes with match result variables ILLEGAL_NUMERIC_PARAMETER = issue :ILLEGAL_NUMERIC_PARAMETER, :name do "The numeric parameter name '$#{varname}' cannot be used (clashes with numeric match result variables)" end # In certain versions of Puppet it may be allowed to assign to a not already assigned key # in an array or a hash. This is an optional validation that may be turned on to prevent accidental # mutation. # ILLEGAL_INDEXED_ASSIGNMENT = issue :ILLEGAL_INDEXED_ASSIGNMENT do "Illegal attempt to assign via [index/key]. Not an assignable reference" end # When indexed assignment ($x[]=) is allowed, the leftmost expression must be # a variable expression. # ILLEGAL_ASSIGNMENT_VIA_INDEX = hard_issue :ILLEGAL_ASSIGNMENT_VIA_INDEX do "Illegal attempt to assign to #{label.a_an(semantic)} via [index/key]. Not an assignable reference" end APPENDS_DELETES_NO_LONGER_SUPPORTED = hard_issue :APPENDS_DELETES_NO_LONGER_SUPPORTED, :operator do "The operator '#{operator}' is no longer supported. See http://links.puppetlabs.com/remove-plus-equals" end # For unsupported operators (e.g. += and -= in puppet 4). # UNSUPPORTED_OPERATOR = hard_issue :UNSUPPORTED_OPERATOR, :operator do "The operator '#{operator}' is not supported." end # For operators that are not supported in specific contexts (e.g. '* =>' in # resource defaults) # UNSUPPORTED_OPERATOR_IN_CONTEXT = hard_issue :UNSUPPORTED_OPERATOR_IN_CONTEXT, :operator do "The operator '#{operator}' in #{label.a_an(semantic)} is not supported." end # For non applicable operators (e.g. << on Hash). # OPERATOR_NOT_APPLICABLE = hard_issue :OPERATOR_NOT_APPLICABLE, :operator, :left_value do "Operator '#{operator}' is not applicable to #{label.a_an(left_value)}." end COMPARISON_NOT_POSSIBLE = hard_issue :COMPARISON_NOT_POSSIBLE, :operator, :left_value, :right_value, :detail do "Comparison of: #{label(left_value)} #{operator} #{label(right_value)}, is not possible. Caused by '#{detail}'." end MATCH_NOT_REGEXP = hard_issue :MATCH_NOT_REGEXP, :detail do "Can not convert right match operand to a regular expression. Caused by '#{detail}'." end MATCH_NOT_STRING = hard_issue :MATCH_NOT_STRING, :left_value do "Left match operand must result in a String value. Got #{label.a_an(left_value)}." end # Some expressions/statements may not produce a value (known as right-value, or rvalue). # This may vary between puppet versions. # NOT_RVALUE = issue :NOT_RVALUE do "Invalid use of expression. #{label.a_an_uc(semantic)} does not produce a value" end # Appending to attributes is only allowed in certain types of resource expressions. # ILLEGAL_ATTRIBUTE_APPEND = hard_issue :ILLEGAL_ATTRIBUTE_APPEND, :name, :parent do "Illegal +> operation on attribute #{name}. This operator can not be used in #{label.a_an(parent)}" end ILLEGAL_NAME = hard_issue :ILLEGAL_NAME, :name do "Illegal name. The given name #{name} does not conform to the naming rule /^((::)?[a-z_]\w*)(::[a-z]\w*)*$/" end ILLEGAL_VAR_NAME = hard_issue :ILLEGAL_VAR_NAME, :name do "Illegal variable name, The given name '#{name}' does not conform to the naming rule /^((::)?[a-z]\w*)*((::)?[a-z_]\w*)$/" end ILLEGAL_NUMERIC_VAR_NAME = hard_issue :ILLEGAL_NUMERIC_VAR_NAME, :name do "Illegal numeric variable name, The given name '#{name}' must be a decimal value if it starts with a digit 0-9" end # In case a model is constructed programmatically, it must create valid type references. # ILLEGAL_CLASSREF = hard_issue :ILLEGAL_CLASSREF, :name do "Illegal type reference. The given name '#{name}' does not conform to the naming rule" end # This is a runtime issue - storeconfigs must be on in order to collect exported. This issue should be # set to :ignore when just checking syntax. # @todo should be a :warning by default # RT_NO_STORECONFIGS = issue :RT_NO_STORECONFIGS do "You cannot collect exported resources without storeconfigs being set; the collection will be ignored" end # This is a runtime issue - storeconfigs must be on in order to export a resource. This issue should be # set to :ignore when just checking syntax. # @todo should be a :warning by default # RT_NO_STORECONFIGS_EXPORT = issue :RT_NO_STORECONFIGS_EXPORT do "You cannot collect exported resources without storeconfigs being set; the export is ignored" end # A hostname may only contain letters, digits, '_', '-', and '.'. # ILLEGAL_HOSTNAME_CHARS = hard_issue :ILLEGAL_HOSTNAME_CHARS, :hostname do "The hostname '#{hostname}' contains illegal characters (only letters, digits, '_', '-', and '.' are allowed)" end # A hostname may only contain letters, digits, '_', '-', and '.'. # ILLEGAL_HOSTNAME_INTERPOLATION = hard_issue :ILLEGAL_HOSTNAME_INTERPOLATION do "An interpolated expression is not allowed in a hostname of a node" end # Issues when an expression is used where it is not legal. # E.g. an arithmetic expression where a hostname is expected. # ILLEGAL_EXPRESSION = hard_issue :ILLEGAL_EXPRESSION, :feature, :container do "Illegal expression. #{label.a_an_uc(semantic)} is unacceptable as #{feature} in #{label.a_an(container)}" end # Issues when an expression is used where it is not legal. # E.g. an arithmetic expression where a hostname is expected. # ILLEGAL_VARIABLE_EXPRESSION = hard_issue :ILLEGAL_VARIABLE_EXPRESSION do "Illegal variable expression. #{label.a_an_uc(semantic)} did not produce a variable name (String or Numeric)." end # Issues when an expression is used illegaly in a query. # query only supports == and !=, and not <, > etc. # ILLEGAL_QUERY_EXPRESSION = hard_issue :ILLEGAL_QUERY_EXPRESSION do "Illegal query expression. #{label.a_an_uc(semantic)} cannot be used in a query" end # If an attempt is made to make a resource default virtual or exported. # NOT_VIRTUALIZEABLE = hard_issue :NOT_VIRTUALIZEABLE do "Resource Defaults are not virtualizable" end # When an attempt is made to use multiple keys (to produce a range in Ruby - e.g. $arr[2,-1]). # This is not supported in 3x, but it allowed in 4x. # UNSUPPORTED_RANGE = issue :UNSUPPORTED_RANGE, :count do "Attempt to use unsupported range in #{label.a_an(semantic)}, #{count} values given for max 1" end ILLEGAL_RELATIONSHIP_OPERAND_TYPE = issue :ILLEGAL_RELATIONSHIP_OPERAND_TYPE, :operand do "Illegal relationship operand, can not form a relationship with #{label.a_an(operand)}. A Catalog type is required." end NOT_CATALOG_TYPE = issue :NOT_CATALOG_TYPE, :type do "Illegal relationship operand, can not form a relationship with something of type #{type}. A Catalog type is required." end BAD_STRING_SLICE_ARITY = issue :BAD_STRING_SLICE_ARITY, :actual do "String supports [] with one or two arguments. Got #{actual}" end BAD_STRING_SLICE_TYPE = issue :BAD_STRING_SLICE_TYPE, :actual do "String-Type [] requires all arguments to be integers (or default). Got #{actual}" end BAD_ARRAY_SLICE_ARITY = issue :BAD_ARRAY_SLICE_ARITY, :actual do "Array supports [] with one or two arguments. Got #{actual}" end BAD_HASH_SLICE_ARITY = issue :BAD_HASH_SLICE_ARITY, :actual do "Hash supports [] with one or more arguments. Got #{actual}" end BAD_INTEGER_SLICE_ARITY = issue :BAD_INTEGER_SLICE_ARITY, :actual do "Integer-Type supports [] with one or two arguments (from, to). Got #{actual}" end BAD_INTEGER_SLICE_TYPE = issue :BAD_INTEGER_SLICE_TYPE, :actual do "Integer-Type [] requires all arguments to be integers (or default). Got #{actual}" end BAD_COLLECTION_SLICE_TYPE = issue :BAD_COLLECTION_SLICE_TYPE, :actual do "A Type's size constraint arguments must be a single Integer type, or 1-2 integers (or default). Got #{label.a_an(actual)}" end BAD_FLOAT_SLICE_ARITY = issue :BAD_INTEGER_SLICE_ARITY, :actual do "Float-Type supports [] with one or two arguments (from, to). Got #{actual}" end BAD_FLOAT_SLICE_TYPE = issue :BAD_INTEGER_SLICE_TYPE, :actual do "Float-Type [] requires all arguments to be floats, or integers (or default). Got #{actual}" end BAD_SLICE_KEY_TYPE = issue :BAD_SLICE_KEY_TYPE, :left_value, :expected_classes, :actual do expected_text = if expected_classes.size > 1 "one of #{expected_classes.join(', ')} are" else "#{expected_classes[0]} is" end "#{label.a_an_uc(left_value)}[] cannot use #{actual} where #{expected_text} expected" end BAD_TYPE_SLICE_TYPE = issue :BAD_TYPE_SLICE_TYPE, :base_type, :actual do "#{base_type}[] arguments must be types. Got #{actual}" end BAD_TYPE_SLICE_ARITY = issue :BAD_TYPE_SLICE_ARITY, :base_type, :min, :max, :actual do base_type_label = base_type.is_a?(String) ? base_type : label.a_an_uc(base_type) if max == -1 || max == 1.0 / 0.0 # Infinity "#{base_type_label}[] accepts #{min} or more arguments. Got #{actual}" elsif max && max != min "#{base_type_label}[] accepts #{min} to #{max} arguments. Got #{actual}" else "#{base_type_label}[] accepts #{min} #{label.plural_s(min, 'argument')}. Got #{actual}" end end BAD_TYPE_SPECIALIZATION = hard_issue :BAD_TYPE_SPECIALIZATION, :type, :message do "Error creating type specialization of #{label.a_an(type)}, #{message}" end ILLEGAL_TYPE_SPECIALIZATION = issue :ILLEGAL_TYPE_SPECIALIZATION, :kind do "Cannot specialize an already specialized #{kind} type" end ILLEGAL_RESOURCE_SPECIALIZATION = issue :ILLEGAL_RESOURCE_SPECIALIZATION, :actual do "First argument to Resource[] must be a resource type or a String. Got #{actual}." end EMPTY_RESOURCE_SPECIALIZATION = issue :EMPTY_RESOURCE_SPECIALIZATION do "Arguments to Resource[] are all empty/undefined" end ILLEGAL_HOSTCLASS_NAME = hard_issue :ILLEGAL_HOSTCLASS_NAME, :name do "Illegal Class name in class reference. #{label.a_an_uc(name)} cannot be used where a String is expected" end ILLEGAL_DEFINITION_NAME = hard_issue :ILLEGAL_DEFINTION_NAME, :name do "Unacceptable name. The name '#{name}' is unacceptable as the name of #{label.a_an(semantic)}" end CAPTURES_REST_NOT_LAST = hard_issue :CAPTURES_REST_NOT_LAST, :param_name do "Parameter $#{param_name} is not last, and has 'captures rest'" end CAPTURES_REST_NOT_SUPPORTED = hard_issue :CAPTURES_REST_NOT_SUPPORTED, :container, :param_name do "Parameter $#{param_name} has 'captures rest' - not supported in #{label.a_an(container)}" end REQUIRED_PARAMETER_AFTER_OPTIONAL = hard_issue :REQUIRED_PARAMETER_AFTER_OPTIONAL, :param_name do "Parameter $#{param_name} is required but appears after optional parameters" end MISSING_REQUIRED_PARAMETER = hard_issue :MISSING_REQUIRED_PARAMETER, :param_name do "Parameter $#{param_name} is required but no value was given" end NOT_NUMERIC = issue :NOT_NUMERIC, :value do "The value '#{value}' cannot be converted to Numeric." end UNKNOWN_FUNCTION = issue :UNKNOWN_FUNCTION, :name do "Unknown function: '#{name}'." end UNKNOWN_VARIABLE = issue :UNKNOWN_VARIABLE, :name do "Unknown variable: '#{name}'." end RUNTIME_ERROR = issue :RUNTIME_ERROR, :detail do "Error while evaluating #{label.a_an(semantic)}, #{detail}" end UNKNOWN_RESOURCE_TYPE = issue :UNKNOWN_RESOURCE_TYPE, :type_name do "Resource type not found: #{type_name.capitalize}" end ILLEGAL_RESOURCE_TYPE = hard_issue :ILLEGAL_RESOURCE_TYPE, :actual do "Illegal Resource Type expression, expected result to be a type name, or untitled Resource, got #{actual}" end DUPLICATE_TITLE = issue :DUPLICATE_TITLE, :title do "The title '#{title}' has already been used in this resource expression" end + DUPLICATE_ATTRIBUTE = issue :DUPLICATE_ATTRIBUE, :attribute do + "The attribute '#{attribute}' has already been set in this resource body" + end + MISSING_TITLE = hard_issue :MISSING_TITLE do "Missing title. The title expression resulted in undef" end MISSING_TITLE_AT = hard_issue :MISSING_TITLE_AT, :index do "Missing title at index #{index}. The title expression resulted in an undef title" end ILLEGAL_TITLE_TYPE_AT = hard_issue :ILLEGAL_TITLE_TYPE_AT, :index, :actual do "Illegal title type at index #{index}. Expected String, got #{actual}" end EMPTY_STRING_TITLE_AT = hard_issue :EMPTY_STRING_TITLE_AT, :index do "Empty string title at #{index}. Title strings must have a length greater than zero." end UNKNOWN_RESOURCE = issue :UNKNOWN_RESOURCE, :type_name, :title do "Resource not found: #{type_name.capitalize}['#{title}']" end UNKNOWN_RESOURCE_PARAMETER = issue :UNKNOWN_RESOURCE_PARAMETER, :type_name, :title, :param_name do "The resource #{type_name.capitalize}['#{title}'] does not have a parameter called '#{param_name}'" end DIV_BY_ZERO = hard_issue :DIV_BY_ZERO do "Division by 0" end RESULT_IS_INFINITY = hard_issue :RESULT_IS_INFINITY, :operator do "The result of the #{operator} expression is Infinity" end # TODO_HEREDOC EMPTY_HEREDOC_SYNTAX_SEGMENT = issue :EMPTY_HEREDOC_SYNTAX_SEGMENT, :syntax do "Heredoc syntax specification has empty segment between '+' : '#{syntax}'" end ILLEGAL_EPP_PARAMETERS = issue :ILLEGAL_EPP_PARAMETERS do "Ambiguous EPP parameter expression. Probably missing '<%-' before parameters to remove leading whitespace" end DISCONTINUED_IMPORT = hard_issue :DISCONTINUED_IMPORT do "Use of 'import' has been discontinued in favor of a manifest directory. See http://links.puppetlabs.com/puppet-import-deprecation" end IDEM_EXPRESSION_NOT_LAST = issue :IDEM_EXPRESSION_NOT_LAST do "This #{label.label(semantic)} is not productive. A non productive construct may only be placed last in a block/sequence" end IDEM_NOT_ALLOWED_LAST = hard_issue :IDEM_NOT_ALLOWED_LAST, :container do "This #{label.label(semantic)} is not productive. #{label.a_an_uc(container)} can not end with a non productive construct" end RESERVED_WORD = hard_issue :RESERVED_WORD, :word do "Use of reserved word: #{word}, must be quoted if intended to be a String value" end RESERVED_TYPE_NAME = hard_issue :RESERVED_TYPE_NAME, :name do "The name: '#{name}' is already defined by Puppet and can not be used as the name of #{label.a_an(semantic)}." end UNMATCHED_SELECTOR = hard_issue :UNMATCHED_SELECTOR, :param_value do "No matching entry for selector parameter with value '#{param_value}'" end ILLEGAL_NODE_INHERITANCE = issue :ILLEGAL_NODE_INHERITANCE do "Node inheritance is not supported in Puppet >= 4.0.0. See http://links.puppetlabs.com/puppet-node-inheritance-deprecation" end ILLEGAL_OVERRIDEN_TYPE = issue :ILLEGAL_OVERRIDEN_TYPE, :actual do "Resource Override can only operate on resources, got: #{label.label(actual)}" end RESERVED_PARAMETER = hard_issue :RESERVED_PARAMETER, :container, :param_name do "The parameter $#{param_name} redefines a built in parameter in #{label.the(container)}" end TYPE_MISMATCH = hard_issue :TYPE_MISMATCH, :expected, :actual do "Expected value of type #{expected}, got #{actual}" end end diff --git a/lib/puppet/pops/parser/egrammar.ra b/lib/puppet/pops/parser/egrammar.ra index 54ef2a9bc..54b183a81 100644 --- a/lib/puppet/pops/parser/egrammar.ra +++ b/lib/puppet/pops/parser/egrammar.ra @@ -1,755 +1,757 @@ # vim: syntax=ruby # Parser using the Pops model, expression based class Puppet::Pops::Parser::Parser token STRING DQPRE DQMID DQPOST token WORD token LBRACK RBRACK LBRACE RBRACE SYMBOL FARROW COMMA TRUE token FALSE EQUALS APPENDS DELETES LESSEQUAL NOTEQUAL DOT COLON LLCOLLECT RRCOLLECT token QMARK LPAREN RPAREN ISEQUAL GREATEREQUAL GREATERTHAN LESSTHAN token IF ELSE token DEFINE ELSIF VARIABLE CLASS INHERITS NODE BOOLEAN token NAME SEMIC CASE DEFAULT AT ATAT LCOLLECT RCOLLECT CLASSREF token NOT OR AND UNDEF PARROW PLUS MINUS TIMES DIV LSHIFT RSHIFT UMINUS token MATCH NOMATCH REGEX IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB token IN UNLESS PIPE token LAMBDA SELBRACE token NUMBER token HEREDOC SUBLOCATE token RENDER_STRING RENDER_EXPR EPP_START EPP_END EPP_END_TRIM token FUNCTION token PRIVATE ATTR TYPE token LOW prechigh left HIGH left SEMIC left PIPE left LPAREN left RPAREN left DOT nonassoc EPP_START left LBRACK LISTSTART left RBRACK left QMARK left LCOLLECT LLCOLLECT right NOT nonassoc SPLAT nonassoc UMINUS left IN left MATCH NOMATCH left TIMES DIV MODULO left MINUS PLUS left LSHIFT RSHIFT left NOTEQUAL ISEQUAL left GREATEREQUAL GREATERTHAN LESSTHAN LESSEQUAL left AND left OR left LBRACE left SELBRACE left RBRACE right AT ATAT right APPENDS DELETES EQUALS left IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB left FARROW left COMMA nonassoc RENDER_EXPR nonassoc RENDER_STRING left LOW preclow rule # Produces [Model::Program] with a body containing what was parsed program : statements { result = create_program(Factory.block_or_expression(*val[0])) } | epp_expression { result = create_program(Factory.block_or_expression(*val[0])) } | { result = create_empty_program() } # Produces a semantic model (non validated, but semantically adjusted). statements : syntactic_statements { result = transform_calls(val[0]) } # Collects sequence of elements into a list that the statements rule can transform # (Needed because language supports function calls without parentheses around arguments). # Produces Array # syntactic_statements : syntactic_statement { result = [val[0]]} | syntactic_statements SEMIC syntactic_statement { result = val[0].push val[2] } | syntactic_statements syntactic_statement { result = val[0].push val[1] } # Produce a single expression or Array of expression # This exists to handle multiple arguments to non parenthesized function call. If e is expression, # the a program can consists of e [e,e,e] where the first may be a name of a function to call. # syntactic_statement : assignment =LOW { result = val[0] } | syntactic_statement COMMA assignment =LOW { result = aryfy(val[0]).push val[2] } # Assignment (is right recursive since assignment is right associative) assignment : relationship =LOW | relationship EQUALS assignment { result = val[0].set(val[2]) ; loc result, val[1] } | relationship APPENDS assignment { result = val[0].plus_set(val[2]) ; loc result, val[1] } | relationship DELETES assignment { result = val[0].minus_set(val[2]); loc result, val[1] } assignments : assignment { result = [val[0]] } | assignments COMMA assignment { result = val[0].push(val[2]) } relationship : resource =LOW | relationship IN_EDGE resource { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship IN_EDGE_SUB resource { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship OUT_EDGE resource { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship OUT_EDGE_SUB resource { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } #-- RESOURCE # resource : expression = LOW #---VIRTUAL | AT resource { result = val[1] unless Factory.set_resource_form(result, :virtual) # This is equivalent to a syntax error - additional semantic restrictions apply error val[0], "Virtual (@) can only be applied to a Resource Expression" end # relocate the result loc result, val[0], val[1] } #---EXPORTED | ATAT resource { result = val[1] unless Factory.set_resource_form(result, :exported) # This is equivalent to a syntax error - additional semantic restrictions apply error val[0], "Exported (@@) can only be applied to a Resource Expression" end # relocate the result loc result, val[0], val[1] } #---RESOURCE TITLED 3x and 4x | resource LBRACE expression COLON attribute_operations additional_resource_bodies RBRACE { bodies = [Factory.RESOURCE_BODY(val[2], val[4])] + val[5] result = Factory.RESOURCE(val[0], bodies) loc result, val[0], val[6] } #---CLASS RESOURCE | CLASS LBRACE resource_bodies endsemi RBRACE { result = Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2]) loc result, val[0], val[4] } # --RESOURCE 3X Expression # Handles both 3x overrides and defaults (i.e. single resource_body without title colon) # Slated for possible deprecation since it requires transformation and mix static/evaluation check # | resource LBRACE attribute_operations endcomma RBRACE { result = case Factory.resource_shape(val[0]) when :resource, :class # This catches deprecated syntax. # If the attribute operations does not include +>, then the found expression # is actually a LEFT followed by LITERAL_HASH # unless tmp = transform_resource_wo_title(val[0], val[2]) error val[1], "Syntax error resource body without title or hash with +>" end tmp when :defaults Factory.RESOURCE_DEFAULTS(val[0], val[2]) when :override # This was only done for override in original - TODO should it be here at all Factory.RESOURCE_OVERRIDE(val[0], val[2]) else error val[0], "Expression is not valid as a resource, resource-default, or resource-override" end loc result, val[0], val[4] } resource_body : expression COLON attribute_operations endcomma { result = Factory.RESOURCE_BODY(val[0], val[2]) } resource_bodies : resource_body =HIGH { result = [val[0]] } | resource_bodies SEMIC resource_body =HIGH { result = val[0].push val[2] } # This is a rule for the intermediate state where RACC has seen enough tokens to understand that # what is expressed is a Resource Expression, it now has to get to the finishing line # additional_resource_bodies : endcomma { result = [] } | endcomma SEMIC { result = [] } | endcomma SEMIC resource_bodies endsemi { result = val[2] } #-- EXPRESSION # expression : primary_expression | call_function_expression | expression LBRACK expressions RBRACK =LBRACK { result = val[0][*val[2]] ; loc result, val[0], val[3] } | expression IN expression { result = val[0].in val[2] ; loc result, val[1] } | expression MATCH expression { result = val[0] =~ val[2] ; loc result, val[1] } | expression NOMATCH expression { result = val[0].mne val[2] ; loc result, val[1] } | expression PLUS expression { result = val[0] + val[2] ; loc result, val[1] } | expression MINUS expression { result = val[0] - val[2] ; loc result, val[1] } | expression DIV expression { result = val[0] / val[2] ; loc result, val[1] } | expression TIMES expression { result = val[0] * val[2] ; loc result, val[1] } | expression MODULO expression { result = val[0] % val[2] ; loc result, val[1] } | expression LSHIFT expression { result = val[0] << val[2] ; loc result, val[1] } | expression RSHIFT expression { result = val[0] >> val[2] ; loc result, val[1] } | MINUS expression =UMINUS { result = val[1].minus() ; loc result, val[0] } | TIMES expression =SPLAT { result = val[1].unfold() ; loc result, val[0] } | expression NOTEQUAL expression { result = val[0].ne val[2] ; loc result, val[1] } | expression ISEQUAL expression { result = val[0] == val[2] ; loc result, val[1] } | expression GREATERTHAN expression { result = val[0] > val[2] ; loc result, val[1] } | expression GREATEREQUAL expression { result = val[0] >= val[2] ; loc result, val[1] } | expression LESSTHAN expression { result = val[0] < val[2] ; loc result, val[1] } | expression LESSEQUAL expression { result = val[0] <= val[2] ; loc result, val[1] } | NOT expression { result = val[1].not ; loc result, val[0] } | expression AND expression { result = val[0].and val[2] ; loc result, val[1] } | expression OR expression { result = val[0].or val[2] ; loc result, val[1] } | expression QMARK selector_entries { result = val[0].select(*val[2]) ; loc result, val[0] } | LPAREN assignment RPAREN { result = val[1].paren() ; loc result, val[0] } #---EXPRESSIONS # (i.e. "argument list") # # This expression list can not contain function calls without parentheses around arguments # Produces Array # expressions : expression { result = [val[0]] } | expressions COMMA expression { result = val[0].push(val[2]) } primary_expression : variable | call_method_with_lambda_expression | collection_expression | case_expression | if_expression | unless_expression | definition_expression | hostclass_expression | node_definition_expression | epp_render_expression | reserved_word | array | hash | regex | quotedtext | type | NUMBER { result = Factory.NUMBER(val[0][:value]) ; loc result, val[0] } | BOOLEAN { result = Factory.literal(val[0][:value]) ; loc result, val[0] } | DEFAULT { result = Factory.literal(:default) ; loc result, val[0] } | UNDEF { result = Factory.literal(:undef) ; loc result, val[0] } | NAME { result = Factory.QNAME_OR_NUMBER(val[0][:value]) ; loc result, val[0] } #---CALL FUNCTION # # Produces Model::CallNamedFunction call_function_expression : expression LPAREN assignments endcomma RPAREN { result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] } | expression LPAREN RPAREN { result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] } | expression LPAREN assignments endcomma RPAREN lambda { result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] result.lambda = val[5] } | expression LPAREN RPAREN lambda { result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] result.lambda = val[3] } #---CALL METHOD # call_method_with_lambda_expression : call_method_expression =LOW { result = val[0] } | call_method_expression lambda { result = val[0]; val[0].lambda = val[1] } call_method_expression : named_access LPAREN assignments RPAREN { result = Factory.CALL_METHOD(val[0], val[2]); loc result, val[1], val[3] } | named_access LPAREN RPAREN { result = Factory.CALL_METHOD(val[0], []); loc result, val[1], val[3] } | named_access =LOW { result = Factory.CALL_METHOD(val[0], []); loc result, val[0] } named_access : expression DOT NAME { result = val[0].dot(Factory.fqn(val[2][:value])) loc result, val[1], val[2] } #---LAMBDA # lambda : lambda_parameter_list lambda_rest { result = Factory.LAMBDA(val[0][:value], val[1][:value]) loc result, val[0][:start], val[1][:end] } lambda_rest : LBRACE statements RBRACE { result = {:end => val[2], :value =>val[1] } } | LBRACE RBRACE { result = {:end => val[1], :value => nil } } lambda_parameter_list : PIPE PIPE { result = {:start => val[0], :value => [] } } | PIPE parameters endcomma PIPE { result = {:start => val[0], :value => val[1] } } #---CONDITIONALS #--IF # if_expression : IF if_part { result = val[1] loc(result, val[0], val[1]) } # Produces Model::IfExpression if_part : expression LBRACE statements RBRACE else { result = Factory.IF(val[0], Factory.block_or_expression(*val[2]), val[4]) loc(result, val[0], (val[4] ? val[4] : val[3])) } | expression LBRACE RBRACE else { result = Factory.IF(val[0], nil, val[3]) loc(result, val[0], (val[3] ? val[3] : val[2])) } # Produces [Model::Expression, nil] - nil if there is no else or elsif part else : # nothing | ELSIF if_part { result = val[1] loc(result, val[0], val[1]) } | ELSE LBRACE statements RBRACE { result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] } | ELSE LBRACE RBRACE { result = nil # don't think a nop is needed here either } #--UNLESS # unless_expression : UNLESS expression LBRACE statements RBRACE unless_else { result = Factory.UNLESS(val[1], Factory.block_or_expression(*val[3]), val[5]) loc result, val[0], val[4] } | UNLESS expression LBRACE RBRACE unless_else { result = Factory.UNLESS(val[1], nil, nil) loc result, val[0], val[4] } # Different from else part of if, since "elsif" is not supported, but 'else' is # # Produces [Model::Expression, nil] - nil if there is no else or elsif part unless_else : # nothing | ELSE LBRACE statements RBRACE { result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] } | ELSE LBRACE RBRACE { result = nil # don't think a nop is needed here either } #--- CASE EXPRESSION # case_expression : CASE expression LBRACE case_options RBRACE { result = Factory.CASE(val[1], *val[3]) loc result, val[0], val[4] } # Produces Array case_options : case_option { result = [val[0]] } | case_options case_option { result = val[0].push val[1] } # Produced Model::CaseOption (aka When) case_option : expressions COLON LBRACE options_statements RBRACE { result = Factory.WHEN(val[0], val[3]); loc result, val[1], val[4] } options_statements : nil | statements # This special construct is required or racc will produce the wrong result when the selector entry # LHS is generalized to any expression (LBRACE looks like a hash). Thus it is not possible to write # a selector with a single entry where the entry LHS is a hash. # The SELBRACE token is a LBRACE that follows a QMARK, and this is produced by the lexer with a lookback # Produces Array # selector_entries : selector_entry | SELBRACE selector_entry_list endcomma RBRACE { result = val[1] } # Produces Array selector_entry_list : selector_entry { result = [val[0]] } | selector_entry_list COMMA selector_entry { result = val[0].push val[2] } # Produces a Model::SelectorEntry # This FARROW wins over FARROW in Hash selector_entry : expression FARROW expression { result = Factory.MAP(val[0], val[2]) ; loc result, val[1] } #---COLLECTION # # A Collection is a predicate applied to a set of objects with an implied context (used variables are # attributes of the object. # i.e. this is equivalent to source.select(QUERY).apply(ATTRIBUTE_OPERATIONS) # collection_expression : expression collect_query LBRACE attribute_operations endcomma RBRACE { result = Factory.COLLECT(val[0], val[1], val[3]) loc result, val[0], val[5] } | expression collect_query =LOW { result = Factory.COLLECT(val[0], val[1], []) loc result, val[0], val[1] } collect_query : LCOLLECT optional_query RCOLLECT { result = Factory.VIRTUAL_QUERY(val[1]) ; loc result, val[0], val[2] } | LLCOLLECT optional_query RRCOLLECT { result = Factory.EXPORTED_QUERY(val[1]) ; loc result, val[0], val[2] } optional_query : nil | expression #---ATTRIBUTE OPERATIONS (Not an expression) # attribute_operations : { result = [] } - | TIMES FARROW expression { result = [tmp = Factory.ATTRIBUTES_OP(val[2])] ; loc tmp, val[0], val[2] } | attribute_operation { result = [val[0]] } | attribute_operations COMMA attribute_operation { result = val[0].push(val[2]) } # Produces String # QUESTION: Why is BOOLEAN valid as an attribute name? # attribute_name : NAME | keyword # | BOOLEAN # In this version, illegal combinations are validated instead of producing syntax errors # (Can give nicer error message "+> is not applicable to...") # Produces Model::AttributeOperation # attribute_operation : attribute_name FARROW expression { result = Factory.ATTRIBUTE_OP(val[0][:value], :'=>', val[2]) loc result, val[0], val[2] } | attribute_name PARROW expression { result = Factory.ATTRIBUTE_OP(val[0][:value], :'+>', val[2]) loc result, val[0], val[2] } + | TIMES FARROW expression { + result = Factory.ATTRIBUTES_OP(val[2]) ; loc result, val[0], val[2] + } #---DEFINE # # Produces Model::Definition # definition_expression : DEFINE classname parameter_list LBRACE opt_statements RBRACE { result = add_definition(Factory.DEFINITION(classname(val[1][:value]), val[2], val[4])) loc result, val[0], val[5] # New lexer does not keep track of this, this is done in validation if @lexer.respond_to?(:'indefine=') @lexer.indefine = false end } #---HOSTCLASS # # Produces Model::HostClassDefinition # hostclass_expression : CLASS stacked_classname parameter_list classparent LBRACE opt_statements RBRACE { # Remove this class' name from the namestack as all nested classes have been parsed namepop result = add_definition(Factory.HOSTCLASS(classname(val[1][:value]), val[2], token_text(val[3]), val[5])) loc result, val[0], val[6] } # Record the classname so nested classes gets a fully qualified name at parse-time # This is a separate rule since racc does not support intermediate actions. # stacked_classname : classname { namestack(val[0][:value]) ; result = val[0] } opt_statements : statements | nil # Produces String, name or nil result classparent : nil | INHERITS classnameordefault { result = val[1] } # Produces String (this construct allows a class to be named "default" and to be referenced as # the parent class. # TODO: Investigate the validity # Produces a String (classname), or a token (DEFAULT). # classnameordefault : classname | DEFAULT #---NODE # # Produces Model::NodeDefinition # node_definition_expression : NODE hostnames endcomma nodeparent LBRACE statements RBRACE { result = add_definition(Factory.NODE(val[1], val[3], val[5])) loc result, val[0], val[6] } | NODE hostnames endcomma nodeparent LBRACE RBRACE { result = add_definition(Factory.NODE(val[1], val[3], nil)) loc result, val[0], val[5] } # Hostnames is not a list of names, it is a list of name matchers (including a Regexp). # (The old implementation had a special "Hostname" object with some minimal validation) # # Produces Array # hostnames : hostname { result = [result] } | hostnames COMMA hostname { result = val[0].push(val[2]) } # Produces a LiteralExpression (string, :default, or regexp) # String with interpolation is validated for better error message hostname : dotted_name | quotedtext | DEFAULT { result = Factory.literal(:default); loc result, val[0] } | regex dotted_name : name_or_number { result = Factory.literal(val[0][:value]); loc result, val[0] } | dotted_name DOT name_or_number { result = Factory.concat(val[0], '.', val[2][:value]); loc result, val[0], val[2] } name_or_number : NAME | NUMBER # Produces Expression, since hostname is an Expression nodeparent : nil | INHERITS hostname { result = val[1] } #---FUNCTION DEFINITION # #function_definition # For now the function word will just be reserved, in the future it will # produce a function definition # FUNCTION classname parameter_list LBRACE opt_statements RBRACE { # result = add_definition(Factory.FUNCTION(val[1][:value], val[2], val[4])) # loc result, val[0], val[5] # } #---NAMES AND PARAMETERS COMMON TO SEVERAL RULES # Produces String # TODO: The error that "class" is not a valid classname is bad - classname rule is also used for other things classname : NAME | CLASS { error val[0], "'class' is not a valid classname" } # Produces Array parameter_list : nil { result = [] } | LPAREN RPAREN { result = [] } | LPAREN parameters endcomma RPAREN { result = val[1] } # Produces Array parameters : parameter { result = [val[0]] } | parameters COMMA parameter { result = val[0].push(val[2]) } # Produces Model::Parameter parameter : untyped_parameter | typed_parameter untyped_parameter : regular_parameter | splat_parameter regular_parameter : VARIABLE EQUALS expression { result = Factory.PARAM(val[0][:value], val[2]) ; loc result, val[0] } | VARIABLE { result = Factory.PARAM(val[0][:value]); loc result, val[0] } splat_parameter : TIMES regular_parameter { result = val[1]; val[1].captures_rest() } typed_parameter : parameter_type untyped_parameter { val[1].type_expr(val[0]) ; result = val[1] } parameter_type : type { result = val[0] } | type LBRACK expressions RBRACK { result = val[0][*val[2]] ; loc result, val[0], val[3] } #--VARIABLE # variable : VARIABLE { result = Factory.fqn(val[0][:value]).var ; loc result, val[0] } #---RESERVED WORDS # reserved_word : FUNCTION { result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] } | PRIVATE { result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] } | TYPE { result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] } | ATTR { result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] } #---LITERALS (dynamic and static) # array : LISTSTART assignments endcomma RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[3] } | LISTSTART RBRACK { result = Factory.literal([]) ; loc result, val[0] } | LBRACK assignments endcomma RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[3] } | LBRACK RBRACK { result = Factory.literal([]) ; loc result, val[0] } hash : LBRACE hashpairs RBRACE { result = Factory.HASH(val[1]); loc result, val[0], val[2] } | LBRACE hashpairs COMMA RBRACE { result = Factory.HASH(val[1]); loc result, val[0], val[3] } | LBRACE RBRACE { result = Factory.literal({}) ; loc result, val[0], val[3] } hashpairs : hashpair { result = [val[0]] } | hashpairs COMMA hashpair { result = val[0].push val[2] } hashpair : assignment FARROW assignment { result = Factory.KEY_ENTRY(val[0], val[2]); loc result, val[1] } quotedtext : string | dq_string | heredoc string : STRING { result = Factory.literal(val[0][:value]) ; loc result, val[0] } | WORD { result = Factory.literal(val[0][:value]) ; loc result, val[0] } dq_string : dqpre dqrval { result = Factory.string(val[0], *val[1]) ; loc result, val[0], val[1][-1] } dqpre : DQPRE { result = Factory.literal(val[0][:value]); loc result, val[0] } dqpost : DQPOST { result = Factory.literal(val[0][:value]); loc result, val[0] } dqmid : DQMID { result = Factory.literal(val[0][:value]); loc result, val[0] } dqrval : text_expression dqtail { result = [val[0]] + val[1] } text_expression : assignment { result = Factory.TEXT(val[0]) } dqtail : dqpost { result = [val[0]] } | dqmid dqrval { result = [val[0]] + val[1] } heredoc : HEREDOC sublocated_text { result = Factory.HEREDOC(val[0][:value], val[1]); loc result, val[0] } sublocated_text : SUBLOCATE string { result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] } | SUBLOCATE dq_string { result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] } epp_expression : EPP_START epp_parameters_list optional_statements { result = Factory.EPP(val[1], val[2]); loc result, val[0] } optional_statements : | statements epp_parameters_list : =LOW{ result = nil } | PIPE PIPE { result = [] } | PIPE parameters endcomma PIPE { result = val[1] } epp_render_expression : RENDER_STRING { result = Factory.RENDER_STRING(val[0][:value]); loc result, val[0] } | RENDER_EXPR expression epp_end { result = Factory.RENDER_EXPR(val[1]); loc result, val[0], val[2] } | RENDER_EXPR LBRACE statements RBRACE epp_end { result = Factory.RENDER_EXPR(Factory.block_or_expression(*val[2])); loc result, val[0], val[4] } epp_end : EPP_END | EPP_END_TRIM type : CLASSREF { result = Factory.QREF(val[0][:value]) ; loc result, val[0] } regex : REGEX { result = Factory.literal(val[0][:value]); loc result, val[0] } #---MARKERS, SPECIAL TOKENS, SYNTACTIC SUGAR, etc. endcomma : # | COMMA { result = nil } endsemi : # | SEMIC keyword : AND | CASE | CLASS | DEFAULT | DEFINE | ELSE | ELSIF | IF | IN | INHERITS | NODE | OR | UNDEF | UNLESS | TYPE | ATTR | FUNCTION | PRIVATE nil : { result = nil} end ---- header ---- require 'puppet' require 'puppet/pops' module Puppet class ParseError < Puppet::Error; end class ImportError < Racc::ParseError; end class AlreadyImportedError < ImportError; end end ---- inner ---- # Make emacs happy # Local Variables: # mode: ruby # End: diff --git a/lib/puppet/pops/parser/eparser.rb b/lib/puppet/pops/parser/eparser.rb index b5087d973..26ff778fe 100644 --- a/lib/puppet/pops/parser/eparser.rb +++ b/lib/puppet/pops/parser/eparser.rb @@ -1,2653 +1,2655 @@ # # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.4.9 # from Racc grammer file "". # require 'racc/parser.rb' require 'puppet' require 'puppet/pops' module Puppet class ParseError < Puppet::Error; end class ImportError < Racc::ParseError; end class AlreadyImportedError < ImportError; end end module Puppet module Pops module Parser class Parser < Racc::Parser -module_eval(<<'...end egrammar.ra/module_eval...', 'egrammar.ra', 751) +module_eval(<<'...end egrammar.ra/module_eval...', 'egrammar.ra', 753) # Make emacs happy # Local Variables: # mode: ruby # End: ...end egrammar.ra/module_eval... ##### State transition tables begin ### clist = [ -'58,61,388,275,59,53,317,54,-236,80,-238,-237,236,133,-130,-234,-239', +'58,61,388,275,59,53,317,54,-236,80,-238,-237,236,133,-129,-234,-239', '-225,256,255,318,392,278,101,18,104,278,99,100,333,42,373,45,237,47', '12,111,46,36,39,110,44,37,10,11,276,134,66,17,103,-236,38,-238,-237', -'15,16,-130,-234,-239,-225,58,61,67,334,59,53,236,54,43,277,79,81,35', +'15,16,-129,-234,-239,-225,58,61,67,334,59,53,236,54,43,277,79,81,35', '62,278,64,65,63,107,66,48,49,51,50,18,111,52,237,79,110,42,236,45,79', '47,113,236,46,36,39,252,44,37,253,66,312,111,66,17,66,110,38,237,254', '15,16,369,237,368,111,58,61,67,110,59,53,229,54,43,340,111,265,35,62', '110,64,65,359,267,268,48,49,51,50,18,111,52,307,71,110,42,369,45,368', '47,12,236,46,36,39,69,44,37,10,11,342,273,66,17,66,329,38,58,61,15,16', '59,237,254,326,58,61,67,249,59,53,249,54,43,72,73,74,35,62,350,64,65', '351,273,274,48,49,51,50,18,353,52,248,247,356,42,316,45,312,47,12,361', '46,36,39,362,44,37,10,11,236,225,66,17,228,226,38,366,313,15,16,370', '372,75,77,76,78,67,312,249,225,379,79,43,381,299,273,35,62,79,64,65', '215,214,71,48,49,51,50,58,61,52,153,59,53,385,54,310,150,119,79,273', '148,391,306,119,302,120,395,372,397,398,399,18,58,61,119,402,59,42,403', '45,404,47,12,300,46,36,39,79,44,37,10,11,71,412,66,17,68,414,38,415', '416,15,16,302,,,,,,67,,133,,,130,43,,,,35,62,,64,65,,,,48,49,51,50,58', '61,52,67,59,53,,54,408,80,,,,134,62,,,,,,,,,101,18,104,,99,100,,42,', '45,,47,12,,46,36,39,,44,37,10,11,,,66,17,103,,38,,,15,16,,,,,58,61,67', ',59,53,,54,43,,,81,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47', '113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54', '43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39', ',44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11', ',,66,17,,,38,,,15,16,,,,,,,67,,,,,,43,,,,35,62,,64,65,,,,48,49,51,50', '58,61,52,,59,53,,54,406,80,,,,,,,,,,,,,,101,18,104,,99,100,,42,,45,', '47,12,,46,36,39,,44,37,10,11,,,66,17,103,,38,,,15,16,,,,,58,61,67,,59', '53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46', '36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35', '62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,', ',,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,', '48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38', ',,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18', ',52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,', ',,,67,,,,,,43,,,,35,62,,64,65,,,,48,49,51,50,58,61,52,,59,53,,54,401', '80,,,,,,,,,,,,,,101,18,104,,99,100,,42,,45,,47,12,,46,36,39,,44,37,10', '11,,,66,17,103,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65', ',,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,', ',38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50', '18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,', ',58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42', ',45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59', '53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46', '36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,,,67,,,,,,43,,,,35,62,,64,65', ',,,48,49,51,50,58,61,52,,59,53,,54,320,,,,,,,,,,,,,,,,18,58,61,,,59', '42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,,,,,67,', '133,,,130,43,,,,35,62,,64,65,,,,48,49,51,50,58,61,52,67,59,53,,54,322', '80,,,,134,62,,,,,,,,,101,18,104,,99,100,,42,,45,,47,12,,46,36,39,,44', '37,10,11,,,66,17,103,,38,,,15,16,,,,,58,61,67,,59,53,137,54,43,,,,35', '62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10', '11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,139,54,43,,,,35,62,,64,65', ',,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17', ',,38,,,15,16,,,,,,,67,,,,,,43,,,,35,62,,64,65,,,,48,49,51,50,58,61,52', ',59,53,,54,141,80,,,,,,,,,,,,,,101,18,104,,99,100,,42,,45,,47,12,,46', '36,39,,44,37,10,11,,,66,17,103,,38,,,15,16,,,,,58,61,67,,59,53,,54,43', ',,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44', '37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64', '65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66', '17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49', '51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15', '16,,,,,58,61,67,,59,53,,152,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52', ',,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61', '67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47', '113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54', '43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39', ',44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,', '66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48', '49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38', ',,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18', ',52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,', ',58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42', ',45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67', ',59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12', ',46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54', '43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39', ',44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11', ',,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48', '49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38', ',,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18', ',52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,', ',58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,169', '183,175,184,47,176,186,177,36,168,,171,166,,,,,66,17,187,182,167,,,15', '165,,,,,,,67,,,,,185,170,,,,35,62,,64,65,,,,178,179,181,180,58,61,52', ',59,53,,54,,,,,,,,,,,,,,,,,18,,,,,,42,,45,,47,113,,46,36,39,,44,37,', ',,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,', '48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38', ',,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18', ',52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58', '61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45', ',47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53', ',54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36', '39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,', '66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48', '49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,', '15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,', '52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58', '61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45', ',47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53', ',54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36', '39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,', '66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48', '49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,', '15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,', '52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58', '61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45', ',47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53', ',54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36', '39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62', ',64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,', '66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48', '49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,', '15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,', '52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58', '61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45', ',47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53', ',54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36', '39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,211,35', '62,,64,65,,,,48,49,51,50,18,213,52,,,,42,,45,,47,12,,46,36,39,,44,37', '10,11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65', ',,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,', ',38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50', '18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,', ',58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42', ',45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59', '53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46', '36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,274', ',35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44', '37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65', ',,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17', ',,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51', '50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16', ',,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,', '42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,,,,,67,', ',,,,43,,,,35,62,,64,65,,,,48,49,51,50,58,61,52,,59,53,,54,335,,,,,,', ',,,,,,,,,18,58,61,,,59,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17', ',,38,,,15,16,,,,,,,67,,133,,,130,43,,,,35,62,,64,65,,,,48,49,51,50,58', '61,52,67,59,53,,54,374,,,,,134,62,,,,,,,,,,18,,,,,,42,,45,,47,113,,46', '36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35', '62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10', '11,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,', ',,48,49,51,50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17', ',,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51', '50,18,,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15', '16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52', ',,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,,,67,', ',,,,43,,,,35,62,,64,65,,,,48,49,51,50,58,61,52,,59,53,,54,141,,,,,,', ',,,,,,,,,18,,,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,', ',15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18', '241,52,,,,42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16', ',,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,', '42,,45,,47,12,,46,36,39,,44,37,10,11,,,66,17,,,38,,,15,16,,,,,58,61', '67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47', '113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54', '43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39', ',44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64', '65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17', ',,38,,,15,16,,,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51', '50,18,,52,,,,42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16', ',,,,58,61,67,,59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,', '42,,45,,47,113,,46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67', ',59,53,,54,43,,,,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113', ',46,36,39,,44,37,,,,,66,17,,,38,,,15,16,,,,,58,61,67,,59,53,,54,43,', ',,35,62,,64,65,,,,48,49,51,50,18,,52,,,,42,,45,,47,113,,46,36,39,,44', '37,,,,,66,17,,,38,,,15,16,,,,,,,67,,,,,,43,,,,35,62,,64,65,80,,,48,49', '51,50,,,52,,,96,91,101,,104,,99,100,,92,94,93,95,,58,61,,,59,,,,,,,', ',,103,,,,98,97,,,84,85,87,86,89,90,,82,83,80,,244,,,81,,,133,,,130,96', '91,101,,104,,99,100,,92,94,93,95,,88,,,,,67,,,,,,,,,103,134,62,,98,97', ',,84,85,87,86,89,90,,82,83,80,,243,,,81,,,,,,,96,91,101,,104,80,99,100', ',92,94,93,95,,88,,,,,101,,104,,99,100,,,,103,,,,98,97,,,84,85,87,86', '89,90,,82,83,103,,,,,81,,,,,87,86,,,,82,83,80,,242,,,81,,,,88,,,96,91', '101,,104,80,99,100,,92,94,93,95,,88,,,,,101,,104,,99,100,,,,103,,,,98', '97,,80,84,85,87,86,89,90,,82,83,103,,96,91,101,81,104,,99,100,,92,94', '93,95,82,83,,,,,,81,,,,88,,,,103,,,,98,97,,80,84,85,87,86,89,90,,82', '83,,,96,91,101,81,104,,99,100,,92,94,93,95,,,,,,,,,,,,88,,,,103,,,,98', '97,,,84,85,87,86,89,90,,82,83,,,,,,81,80,,,,,,,,,,267,268,96,91,101', '303,104,80,99,100,88,92,94,93,95,,,,,,,101,,104,,99,100,,,,103,,,,98', '97,,,84,85,87,86,89,90,,82,83,103,,,,,81,,,84,85,87,86,,,,82,83,80,', ',,,81,,,,88,,,96,91,101,,104,,99,100,,92,94,93,95,,88,,,,,,,,,,,,,,103', ',,,98,97,,,84,85,87,86,89,90,80,82,83,,,279,,,81,,,,96,91,101,,104,80', '99,100,,92,94,93,95,,,,,88,,101,,104,,99,100,,,,103,,,,98,97,,80,84', '85,87,86,89,90,,82,83,103,,96,91,101,81,104,,99,100,,92,94,93,95,82', '83,,,,,,81,,,,88,,,,103,,,,,97,,80,84,85,87,86,89,90,,82,83,,,96,91', '101,81,104,,99,100,,92,94,93,95,,,,,,,,,,,,88,,,,103,,,,98,97,,,84,85', '87,86,89,90,80,82,83,,,,,,81,,,,96,91,101,271,104,80,99,100,,92,94,93', '95,,,,,88,,101,,104,,99,100,,,,103,,,,98,97,,80,84,85,87,86,89,90,,82', '83,103,,96,91,101,81,104,,99,100,,92,94,93,95,82,83,,,,,,81,,,,88,,', ',103,,,,98,97,,80,84,85,87,86,89,90,,82,83,,,96,91,101,81,104,,99,100', ',92,94,93,95,,,,,,,,,,,,88,,,,103,,,,98,97,,80,84,85,87,86,89,90,,82', '83,,,96,91,101,81,104,,99,100,,92,94,93,95,80,,,,,,,,,,,88,,91,101,103', '104,,99,100,80,92,,84,85,87,86,89,90,,82,83,,,101,,104,81,99,100,103', ',,,,,,,84,85,87,86,89,90,,82,83,,88,,103,,81,,,,,,84,85,87,86,80,,,82', '83,,,,,,81,88,96,91,101,,104,,99,100,80,92,94,93,95,,,,,,,88,,,101,', '104,,99,100,103,,,,98,97,,,84,85,87,86,89,90,,82,83,,,,103,,81,,,,,', ',,87,86,80,,,82,83,,,,,,81,88,96,91,101,,104,,99,100,80,92,94,93,95', ',,,,,,88,,91,101,,104,,99,100,103,92,,,98,97,,,84,85,87,86,89,90,,82', '83,,,,103,,81,,,,,,84,85,87,86,89,90,80,82,83,,,,,,81,88,,,96,91,101', ',104,80,99,100,,92,94,93,95,,,,,88,,101,,104,,99,100,,,,103,,,,98,97', ',,84,85,87,86,89,90,,82,83,103,,,,,81,,,84,85,87,86,89,90,80,82,83,', ',,,,81,,,,88,,101,,104,80,99,100,,,,,,,,,,88,91,101,,104,,99,100,,92', ',103,,,,,,,,84,85,87,86,89,90,,82,83,103,,,,,81,,,84,85,87,86,89,90', '80,82,83,,,,,,81,,,,88,91,101,,104,,99,100,,92,,,,,,,,88,,,,,,,,,,,103', ',,,,,,,84,85,87,86,89,90,,82,83,,,,,,81,,,291,183,290,184,,288,186,292', -',286,,287,289,,,,,,88,187,182,293,,,,285,,,,,,,,,,,,185,294,,,,,,,,', -',,,297,298,296,295,291,183,290,184,,288,186,292,,286,,287,289,,,,,,', -'187,182,293,291,183,290,184,,288,186,292,,286,,287,289,,,185,294,,,187', -'182,293,,,,285,,,297,298,296,295,,,,,,185,294,,,,,,,,,,,,297,298,296', -'295,291,183,290,184,,288,186,292,,286,,287,289,,,,,,,187,182,293,,,', -'285,,,,,,,,,,,,185,294,,,,,,,,,,,,297,298,296,295' ] - racc_action_table = arr = ::Array.new(6777, nil) +',285,,287,289,,,,,,88,187,182,293,,,,286,,,,,,,,,,,,185,294,,,,,,,,', +',,,297,298,296,295,291,183,290,184,,288,186,292,,285,,287,289,,,,,,', +'187,182,293,,,,286,,,,,,,,,,,,185,294,,,,,,,,,,,,297,298,296,295,291', +'183,290,184,,288,186,292,,285,,287,289,,,,,,,187,182,293,,,,286,,,,', +',,,,,,,185,294,,,,,,,,,,,,297,298,296,295,291,183,290,184,,288,186,292', +',285,,287,289,,,,,,,187,182,293,,,,286,,,,,,,,,,,,185,294,,,,,,,,,,', +',297,298,296,295' ] + racc_action_table = arr = ::Array.new(6809, nil) idx = 0 clist.each do |str| str.split(',', -1).each do |i| arr[idx] = i.to_i unless i.empty? idx += 1 end end clist = [ '0,0,352,174,0,0,240,0,180,191,178,181,238,248,168,167,179,166,145,145', '240,365,323,191,0,191,365,191,191,250,0,323,0,238,0,0,113,0,0,0,113', '0,0,0,0,174,248,0,0,191,180,0,178,181,0,0,168,167,179,166,403,403,0', '251,403,403,312,403,0,189,161,191,0,0,189,0,0,0,12,312,0,0,0,0,403,45', '0,312,160,45,403,119,403,159,403,403,150,403,403,403,140,403,403,140', '119,264,12,403,403,150,12,403,119,269,403,403,320,150,320,175,4,4,403', '175,4,4,119,4,403,270,306,150,403,403,306,403,403,306,340,340,403,403', '403,403,4,176,403,225,154,176,4,366,4,366,4,4,225,4,4,4,4,4,4,4,4,272', '164,4,4,225,246,4,148,148,4,4,148,225,143,245,398,398,4,138,398,398', -'136,398,4,7,7,7,4,4,280,4,4,282,284,285,4,4,4,4,398,301,4,128,126,304', +'136,398,4,7,7,7,4,4,280,4,4,282,284,286,4,4,4,4,398,301,4,128,126,304', '398,239,398,308,398,398,309,398,398,398,311,398,398,398,398,237,125', '398,398,118,116,398,319,236,398,398,321,322,7,7,7,7,398,230,212,108', '327,106,398,339,217,341,398,398,105,398,398,102,101,70,398,398,398,398', '228,228,398,68,228,228,349,228,228,63,351,162,355,62,360,223,213,220', '41,369,370,372,373,376,228,177,177,40,383,177,228,384,228,390,228,228', '219,228,228,228,8,228,228,228,228,5,400,228,228,1,405,228,407,409,228', '228,413,,,,,,228,,177,,,177,228,,,,228,228,,228,228,,,,228,228,228,228', '397,397,228,177,397,397,,397,397,192,,,,177,177,,,,,,,,,192,397,192', ',192,192,,397,,397,,397,397,,397,397,397,,397,397,397,397,,,397,397', '192,,397,,,397,397,,,,,211,211,397,,211,211,,211,397,,,192,397,397,', '397,397,,,,397,397,397,397,211,,397,,,,211,,211,,211,211,,211,211,211', ',211,211,,,,,211,211,,,211,,,211,211,,,,,10,10,211,,10,10,,10,211,,', ',211,211,,211,211,,,,211,211,211,211,10,,211,,,,10,,10,,10,10,,10,10', '10,,10,10,10,10,,,10,10,,,10,,,10,10,,,,,11,11,10,,11,11,,11,10,,,,10', '10,,10,10,,,,10,10,10,10,11,,10,,,,11,,11,,11,11,,11,11,11,,11,11,11', '11,,,11,11,,,11,,,11,11,,,,,,,11,,,,,,11,,,,11,11,,11,11,,,,11,11,11', '11,395,395,11,,395,395,,395,395,114,,,,,,,,,,,,,,114,395,114,,114,114', ',395,,395,,395,395,,395,395,395,,395,395,395,395,,,395,395,114,,395', ',,395,395,,,,,15,15,395,,15,15,,15,395,,,,395,395,,395,395,,,,395,395', '395,395,15,,395,,,,15,,15,,15,15,,15,15,15,,15,15,,,,,15,15,,,15,,,15', '15,,,,,16,16,15,,16,16,,16,15,,,,15,15,,15,15,,,,15,15,15,15,16,,15', ',,,16,,16,,16,16,,16,16,16,,16,16,,,,,16,16,,,16,,,16,16,,,,,17,17,16', ',17,17,,17,16,,,,16,16,,16,16,,,,16,16,16,16,17,,16,,,,17,,17,,17,17', ',17,17,17,,17,17,,,,,17,17,,,17,,,17,17,,,,,18,18,17,,18,18,,18,17,', ',,17,17,,17,17,,,,17,17,17,17,18,,17,,,,18,,18,,18,18,,18,18,18,,18', '18,18,18,,,18,18,,,18,,,18,18,,,,,,,18,,,,,,18,,,,18,18,,18,18,,,,18', '18,18,18,379,379,18,,379,379,,379,379,115,,,,,,,,,,,,,,115,379,115,', '115,115,,379,,379,,379,379,,379,379,379,,379,379,379,379,,,379,379,115', ',379,,,379,379,,,,,368,368,379,,368,368,,368,379,,,,379,379,,379,379', ',,,379,379,379,379,368,,379,,,,368,,368,,368,368,,368,368,368,,368,368', ',,,,368,368,,,368,,,368,368,,,,,42,42,368,,42,42,,42,368,,,,368,368', ',368,368,,,,368,368,368,368,42,,368,,,,42,,42,,42,42,,42,42,42,,42,42', ',,,,42,42,,,42,,,42,42,,,,,43,43,42,,43,43,,43,42,,,,42,42,,42,42,,', ',42,42,42,42,43,,42,,,,43,,43,,43,43,,43,43,43,,43,43,,,,,43,43,,,43', ',,43,43,,,,,44,44,43,,44,44,,44,43,,,,43,43,,43,43,,,,43,43,43,43,44', ',43,,,,44,,44,,44,44,,44,44,44,,44,44,,,,,44,44,,,44,,,44,44,,,,,,,44', ',,,,,44,,,,44,44,,44,44,,,,44,44,44,44,242,242,44,,242,242,,242,242', ',,,,,,,,,,,,,,,242,46,46,,,46,242,,242,,242,242,,242,242,242,,242,242', '242,242,,,242,242,,,242,,,242,242,,,,,,,242,,46,,,46,242,,,,242,242', ',242,242,,,,242,242,242,242,243,243,242,46,243,243,,243,243,190,,,,46', '46,,,,,,,,,190,243,190,,190,190,,243,,243,,243,243,,243,243,243,,243', '243,243,243,,,243,243,190,,243,,,243,243,,,,,52,52,243,,52,52,52,52', '243,,,,243,243,,243,243,,,,243,243,243,243,52,,243,,,,52,,52,,52,52', ',52,52,52,,52,52,52,52,,,52,52,,,52,,,52,52,,,,,53,53,52,,53,53,53,53', '52,,,,52,52,,52,52,,,,52,52,52,52,53,,52,,,,53,,53,,53,53,,53,53,53', ',53,53,53,53,,,53,53,,,53,,,53,53,,,,,,,53,,,,,,53,,,,53,53,,53,53,', ',,53,53,53,53,54,54,53,,54,54,,54,54,112,,,,,,,,,,,,,,112,54,112,,112', '112,,54,,54,,54,54,,54,54,54,,54,54,54,54,,,54,54,112,,54,,,54,54,,', ',,60,60,54,,60,60,,60,54,,,,54,54,,54,54,,,,54,54,54,54,60,,54,,,,60', ',60,,60,60,,60,60,60,,60,60,60,60,,,60,60,,,60,,,60,60,,,,,356,356,60', ',356,356,,356,60,,,,60,60,,60,60,,,,60,60,60,60,356,,60,,,,356,,356', ',356,356,,356,356,356,,356,356,356,356,,,356,356,,,356,,,356,356,,,', ',350,350,356,,350,350,,350,356,,,,356,356,,356,356,,,,356,356,356,356', '350,,356,,,,350,,350,,350,350,,350,350,350,,350,350,,,,,350,350,,,350', ',,350,350,,,,,65,65,350,,65,65,,65,350,,,,350,350,,350,350,,,,350,350', '350,350,65,,350,,,,65,,65,,65,65,,65,65,65,,65,65,,,,,65,65,,,65,,,65', '65,,,,,244,244,65,,244,244,,244,65,,,,65,65,,65,65,,,,65,65,65,65,244', ',65,,,,244,,244,,244,244,,244,244,244,,244,244,,,,,244,244,,,244,,,244', '244,,,,,69,69,244,,69,69,,69,244,,,,244,244,,244,244,,,,244,244,244', '244,69,,244,,,,69,,69,,69,69,,69,69,69,,69,69,69,69,,,69,69,,,69,,,69', '69,,,,,171,171,69,,171,171,,171,69,,,,69,69,,69,69,,,,69,69,69,69,171', ',69,,,,171,,171,,171,171,,171,171,171,,171,171,,,,,171,171,,,171,,,171', '171,,,,,71,71,171,,71,71,,71,171,,,,171,171,,171,171,,,,171,171,171', '171,71,,171,,,,71,,71,,71,71,,71,71,71,,71,71,71,71,,,71,71,,,71,,,71', '71,,,,,72,72,71,,72,72,,72,71,,,,71,71,,71,71,,,,71,71,71,71,72,,71', ',,,72,,72,,72,72,,72,72,72,,72,72,72,72,,,72,72,,,72,,,72,72,,,,,73', '73,72,,73,73,,73,72,,,,72,72,,72,72,,,,72,72,72,72,73,,72,,,,73,,73', ',73,73,,73,73,73,,73,73,73,73,,,73,73,,,73,,,73,73,,,,,74,74,73,,74', '74,,74,73,,,,73,73,,73,73,,,,73,73,73,73,74,,73,,,,74,,74,,74,74,,74', '74,74,,74,74,74,74,,,74,74,,,74,,,74,74,,,,,75,75,74,,75,75,,75,74,', ',,74,74,,74,74,,,,74,74,74,74,75,,74,,,,75,,75,,75,75,,75,75,75,,75', '75,75,75,,,75,75,,,75,,,75,75,,,,,76,76,75,,76,76,,76,75,,,,75,75,,75', '75,,,,75,75,75,75,76,,75,,,,76,,76,,76,76,,76,76,76,,76,76,76,76,,,76', '76,,,76,,,76,76,,,,,77,77,76,,77,77,,77,76,,,,76,76,,76,76,,,,76,76', '76,76,77,,76,,,,77,,77,,77,77,,77,77,77,,77,77,77,77,,,77,77,,,77,,', '77,77,,,,,78,78,77,,78,78,,78,77,,,,77,77,,77,77,,,,77,77,77,77,78,', '77,,,,78,,78,,78,78,,78,78,78,,78,78,78,78,,,78,78,,,78,,,78,78,,,,', '79,79,78,,79,79,,79,78,,,,78,78,,78,78,,,,78,78,78,78,79,,78,,,,79,79', '79,79,79,79,79,79,79,79,,79,79,,,,,79,79,79,79,79,,,79,79,,,,,,,79,', ',,,79,79,,,,79,79,,79,79,,,,79,79,79,79,80,80,79,,80,80,,80,,,,,,,,', ',,,,,,,,80,,,,,,80,,80,,80,80,,80,80,80,,80,80,,,,,80,80,,,80,,,80,80', ',,,,81,81,80,,81,81,,81,80,,,,80,80,,80,80,,,,80,80,80,80,81,,80,,,', '81,,81,,81,81,,81,81,81,,81,81,,,,,81,81,,,81,,,81,81,,,,,82,82,81,', '82,82,,82,81,,,,81,81,,81,81,,,,81,81,81,81,82,,81,,,,82,,82,,82,82', ',82,82,82,,82,82,,,,,82,82,,,82,,,82,82,,,,,83,83,82,,83,83,,83,82,', ',,82,82,,82,82,,,,82,82,82,82,83,,82,,,,83,,83,,83,83,,83,83,83,,83', '83,,,,,83,83,,,83,,,83,83,,,,,84,84,83,,84,84,,84,83,,,,83,83,,83,83', ',,,83,83,83,83,84,,83,,,,84,,84,,84,84,,84,84,84,,84,84,,,,,84,84,,', '84,,,84,84,,,,,85,85,84,,85,85,,85,84,,,,84,84,,84,84,,,,84,84,84,84', '85,,84,,,,85,,85,,85,85,,85,85,85,,85,85,,,,,85,85,,,85,,,85,85,,,,', '86,86,85,,86,86,,86,85,,,,85,85,,85,85,,,,85,85,85,85,86,,85,,,,86,', '86,,86,86,,86,86,86,,86,86,,,,,86,86,,,86,,,86,86,,,,,87,87,86,,87,87', ',87,86,,,,86,86,,86,86,,,,86,86,86,86,87,,86,,,,87,,87,,87,87,,87,87', '87,,87,87,,,,,87,87,,,87,,,87,87,,,,,88,88,87,,88,88,,88,87,,,,87,87', ',87,87,,,,87,87,87,87,88,,87,,,,88,,88,,88,88,,88,88,88,,88,88,,,,,88', '88,,,88,,,88,88,,,,,89,89,88,,89,89,,89,88,,,,88,88,,88,88,,,,88,88', '88,88,89,,88,,,,89,,89,,89,89,,89,89,89,,89,89,,,,,89,89,,,89,,,89,89', ',,,,90,90,89,,90,90,,90,89,,,,89,89,,89,89,,,,89,89,89,89,90,,89,,,', '90,,90,,90,90,,90,90,90,,90,90,,,,,90,90,,,90,,,90,90,,,,,91,91,90,', '91,91,,91,90,,,,90,90,,90,90,,,,90,90,90,90,91,,90,,,,91,,91,,91,91', ',91,91,91,,91,91,,,,,91,91,,,91,,,91,91,,,,,92,92,91,,92,92,,92,91,', ',,91,91,,91,91,,,,91,91,91,91,92,,91,,,,92,,92,,92,92,,92,92,92,,92', '92,,,,,92,92,,,92,,,92,92,,,,,93,93,92,,93,93,,93,92,,,,92,92,,92,92', ',,,92,92,92,92,93,,92,,,,93,,93,,93,93,,93,93,93,,93,93,,,,,93,93,,', '93,,,93,93,,,,,94,94,93,,94,94,,94,93,,,,93,93,,93,93,,,,93,93,93,93', '94,,93,,,,94,,94,,94,94,,94,94,94,,94,94,,,,,94,94,,,94,,,94,94,,,,', '95,95,94,,95,95,,95,94,,,,94,94,,94,94,,,,94,94,94,94,95,,94,,,,95,', '95,,95,95,,95,95,95,,95,95,,,,,95,95,,,95,,,95,95,,,,,96,96,95,,96,96', ',96,95,,,,95,95,,95,95,,,,95,95,95,95,96,,95,,,,96,,96,,96,96,,96,96', '96,,96,96,,,,,96,96,,,96,,,96,96,,,,,97,97,96,,97,97,,97,96,,,,96,96', ',96,96,,,,96,96,96,96,97,,96,,,,97,,97,,97,97,,97,97,97,,97,97,,,,,97', '97,,,97,,,97,97,,,,,98,98,97,,98,98,,98,97,,,,97,97,,97,97,,,,97,97', '97,97,98,,97,,,,98,,98,,98,98,,98,98,98,,98,98,,,,,98,98,,,98,,,98,98', ',,,,99,99,98,,99,99,,99,98,,,,98,98,,98,98,,,,98,98,98,98,99,,98,,,', '99,,99,,99,99,,99,99,99,,99,99,,,,,99,99,,,99,,,99,99,,,,,100,100,99', ',100,100,,100,99,,,99,99,99,,99,99,,,,99,99,99,99,100,100,99,,,,100', ',100,,100,100,,100,100,100,,100,100,100,100,,,100,100,,,100,,,100,100', ',,,,278,278,100,,278,278,,278,100,,,,100,100,,100,100,,,,100,100,100', '100,278,,100,,,,278,,278,,278,278,,278,278,278,,278,278,,,,,278,278', ',,278,,,278,278,,,,,169,169,278,,169,169,,169,278,,,,278,278,,278,278', ',,,278,278,278,278,169,,278,,,,169,,169,,169,169,,169,169,169,,169,169', ',,,,169,169,,,169,,,169,169,,,,,103,103,169,,103,103,,103,169,,,,169', '169,,169,169,,,,169,169,169,169,103,,169,,,,103,,103,,103,103,,103,103', '103,,103,103,,,,,103,103,,,103,,,103,103,,,,,104,104,103,,104,104,,104', '103,,,,103,103,,103,103,,,,103,103,103,103,104,,103,,,,104,,104,,104', '104,,104,104,104,,104,104,,,,,104,104,,,104,,,104,104,,,,,165,165,104', ',165,165,,165,104,,165,,104,104,,104,104,,,,104,104,104,104,165,,104', ',,,165,,165,,165,165,,165,165,165,,165,165,,,,,165,165,,,165,,,165,165', ',,,,249,249,165,,249,249,,249,165,,,,165,165,,165,165,,,,165,165,165', '165,249,,165,,,,249,,249,,249,249,,249,249,249,,249,249,249,249,,,249', '249,,,249,,,249,249,,,,,107,107,249,,107,107,,107,249,,,,249,249,,249', '249,,,,249,249,249,249,107,,249,,,,107,,107,,107,107,,107,107,107,,107', '107,,,,,107,107,,,107,,,107,107,,,,,326,326,107,,326,326,,326,107,,', ',107,107,,107,107,,,,107,107,107,107,326,,107,,,,326,,326,,326,326,', '326,326,326,,326,326,326,326,,,326,326,,,326,,,326,326,,,,,,,326,,,', ',,326,,,,326,326,,326,326,,,,326,326,326,326,253,253,326,,253,253,,253', '253,,,,,,,,,,,,,,,,253,247,247,,,247,253,,253,,253,253,,253,253,253', ',253,253,253,253,,,253,253,,,253,,,253,253,,,,,,,253,,247,,,247,253', ',,,253,253,,253,253,,,,253,253,253,253,324,324,253,247,324,324,,324', '324,,,,,247,247,,,,,,,,,,324,,,,,,324,,324,,324,324,,324,324,324,,324', '324,,,,,324,324,,,324,,,324,324,,,,,254,254,324,,254,254,,254,324,,', ',324,324,,324,324,,,,324,324,324,324,254,,324,,,,254,,254,,254,254,', '254,254,254,,254,254,254,254,,,254,254,,,254,,,254,254,,,,,259,259,254', ',259,259,,259,254,,,,254,254,,254,254,,,,254,254,254,254,259,,254,,', ',259,,259,,259,259,,259,259,259,,259,259,259,259,,,259,259,,,259,,,259', '259,,,,,317,317,259,,317,317,,317,259,,,,259,259,,259,259,,,,259,259', '259,259,317,,259,,,,317,,317,,317,317,,317,317,317,,317,317,317,317', ',,317,317,,,317,,,317,317,,,,,316,316,317,,316,316,,316,317,,,,317,317', ',317,317,,,,317,317,317,317,316,,317,,,,316,,316,,316,316,,316,316,316', ',316,316,,,,,316,316,,,316,,,316,316,,,,,,,316,,,,,,316,,,,316,316,', '316,316,,,,316,316,316,316,152,152,316,,152,152,,152,152,,,,,,,,,,,', ',,,,152,,,,,,152,,152,,152,152,,152,152,152,,152,152,152,152,,,152,152', ',,152,,,152,152,,,,,120,120,152,,120,120,,120,152,,,,152,152,,152,152', ',,,152,152,152,152,120,120,152,,,,120,,120,,120,120,,120,120,120,,120', '120,120,120,,,120,120,,,120,,,120,120,,,,,149,149,120,,149,149,,149', '120,,,,120,120,,120,120,,,,120,120,120,120,149,,120,,,,149,,149,,149', '149,,149,149,149,,149,149,149,149,,,149,149,,,149,,,149,149,,,,,274', '274,149,,274,274,,274,149,,,,149,149,,149,149,,,,149,149,149,149,274', ',149,,,,274,,274,,274,274,,274,274,274,,274,274,,,,,274,274,,,274,,', '274,274,,,,,275,275,274,,275,275,,275,274,,,,274,274,,274,274,,,,274', '274,274,274,275,,274,,,,275,,275,,275,275,,275,275,275,,275,275,,,,', '275,275,,,275,,,275,275,,,,,313,313,275,,313,313,,313,275,,,,275,275', ',275,275,,,,275,275,275,275,313,,275,,,,313,,313,,313,313,,313,313,313', ',313,313,,,,,313,313,,,313,,,313,313,,,,,276,276,313,,276,276,,276,313', ',,,313,313,,313,313,,,,313,313,313,313,276,,313,,,,276,,276,,276,276', ',276,276,276,,276,276,,,,,276,276,,,276,,,276,276,,,,,302,302,276,,302', '302,,302,276,,,,276,276,,276,276,,,,276,276,276,276,302,,276,,,,302', ',302,,302,302,,302,302,302,,302,302,,,,,302,302,,,302,,,302,302,,,,', '279,279,302,,279,279,,279,302,,,,302,302,,302,302,,,,302,302,302,302', '279,,302,,,,279,,279,,279,279,,279,279,279,,279,279,,,,,279,279,,,279', ',,279,279,,,,,170,170,279,,170,170,,170,279,,,,279,279,,279,279,,,,279', '279,279,279,170,,279,,,,170,,170,,170,170,,170,170,170,,170,170,,,,', '170,170,,,170,,,170,170,,,,,,,170,,,,,,170,,,,170,170,,170,170,346,', ',170,170,170,170,,,170,,,346,346,346,,346,,346,346,,346,346,346,346', ',329,329,,,329,,,,,,,,,,346,,,,346,346,,,346,346,346,346,346,346,,346', '346,124,,124,,,346,,,329,,,329,124,124,124,,124,,124,124,,124,124,124', '124,,346,,,,,329,,,,,,,,,124,329,329,,124,124,,,124,124,124,124,124', '124,,124,124,123,,123,,,124,,,,,,,123,123,123,,123,193,123,123,,123', '123,123,123,,124,,,,,193,,193,,193,193,,,,123,,,,123,123,,,123,123,123', '123,123,123,,123,123,193,,,,,123,,,,,193,193,,,,193,193,121,,121,,,193', ',,,123,,,121,121,121,,121,195,121,121,,121,121,121,121,,193,,,,,195', ',195,,195,195,,,,121,,,,121,121,,216,121,121,121,121,121,121,,121,121', '195,,216,216,216,121,216,,216,216,,216,216,216,216,195,195,,,,,,195', ',,,121,,,,216,,,,216,216,,151,216,216,216,216,216,216,,216,216,,,151', '151,151,216,151,,151,151,,151,151,151,151,,,,,,,,,,,,216,,,,151,,,,151', '151,,,151,151,151,151,151,151,,151,151,,,,,,151,221,,,,,,,,,,151,151', '221,221,221,221,221,199,221,221,151,221,221,221,221,,,,,,,199,,199,', '199,199,,,,221,,,,221,221,,,221,221,221,221,221,221,,221,221,199,,,', ',221,,,199,199,199,199,,,,199,199,9,,,,,199,,,,221,,,9,9,9,,9,,9,9,', '9,9,9,9,,199,,,,,,,,,,,,,,9,,,,9,9,,,9,9,9,9,9,9,208,9,9,,,208,,,9,', ',,208,208,208,,208,196,208,208,,208,208,208,208,,,,,9,,196,,196,,196', '196,,,,208,,,,208,208,,207,208,208,208,208,208,208,,208,208,196,,207', '207,207,208,207,,207,207,,207,207,207,207,196,196,,,,,,196,,,,208,,', ',207,,,,,207,,364,207,207,207,207,207,207,,207,207,,,364,364,364,207', '364,,364,364,,364,364,364,364,,,,,,,,,,,,207,,,,364,,,,364,364,,,364', '364,364,364,364,364,163,364,364,,,,,,364,,,,163,163,163,163,163,197', '163,163,,163,163,163,163,,,,,364,,197,,197,,197,197,,,,163,,,,163,163', ',188,163,163,163,163,163,163,,163,163,197,,188,188,188,163,188,,188', '188,,188,188,188,188,197,197,,,,,,197,,,,163,,,,188,,,,188,188,,344', '188,188,188,188,188,188,,188,188,,,344,344,344,188,344,,344,344,,344', '344,344,344,,,,,,,,,,,,188,,,,344,,,,344,344,,206,344,344,344,344,344', '344,,344,344,,,206,206,206,344,206,,206,206,,206,206,206,206,205,,,', ',,,,,,,344,,205,205,206,205,,205,205,198,205,,206,206,206,206,206,206', ',206,206,,,198,,198,206,198,198,205,,,,,,,,205,205,205,205,205,205,', '205,205,,206,,198,,205,,,,,,198,198,198,198,345,,,198,198,,,,,,198,205', '345,345,345,,345,,345,345,194,345,345,345,345,,,,,,,198,,,194,,194,', '194,194,345,,,,345,345,,,345,345,345,345,345,345,,345,345,,,,194,,345', ',,,,,,,194,194,347,,,194,194,,,,,,194,345,347,347,347,,347,,347,347', '203,347,347,347,347,,,,,,,194,,203,203,,203,,203,203,347,203,,,347,347', ',,347,347,347,347,347,347,,347,347,,,,203,,347,,,,,,203,203,203,203', '203,203,348,203,203,,,,,,203,347,,,348,348,348,,348,200,348,348,,348', '348,348,348,,,,,203,,200,,200,,200,200,,,,348,,,,348,348,,,348,348,348', '348,348,348,,348,348,200,,,,,348,,,200,200,200,200,200,200,201,200,200', ',,,,,200,,,,348,,201,,201,202,201,201,,,,,,,,,,200,202,202,,202,,202', '202,,202,,201,,,,,,,,201,201,201,201,201,201,,201,201,202,,,,,201,,', '202,202,202,202,202,202,204,202,202,,,,,,202,,,,201,204,204,,204,,204', '204,,204,,,,,,,,202,,,,,,,,,,,204,,,,,,,,204,204,204,204,204,204,,204', '204,,,,,,204,,,271,271,271,271,,271,271,271,,271,,271,271,,,,,,204,271', '271,271,,,,271,,,,,,,,,,,,271,271,,,,,,,,,,,,271,271,271,271,273,273', -'273,273,,273,273,273,,273,,273,273,,,,,,,273,273,273,303,303,303,303', -',303,303,303,,303,,303,303,,,273,273,,,303,303,303,,,,303,,,273,273', -'273,273,,,,,,303,303,,,,,,,,,,,,303,303,303,303,215,215,215,215,,215', -'215,215,,215,,215,215,,,,,,,215,215,215,,,,215,,,,,,,,,,,,215,215,,', -',,,,,,,,,215,215,215,215' ] - racc_action_check = arr = ::Array.new(6777, nil) +'273,273,,273,273,273,,273,,273,273,,,,,,,273,273,273,,,,273,,,,,,,,', +',,,273,273,,,,,,,,,,,,273,273,273,273,303,303,303,303,,303,303,303,', +'303,,303,303,,,,,,,303,303,303,,,,303,,,,,,,,,,,,303,303,,,,,,,,,,,', +'303,303,303,303,215,215,215,215,,215,215,215,,215,,215,215,,,,,,,215', +'215,215,,,,215,,,,,,,,,,,,215,215,,,,,,,,,,,,215,215,215,215' ] + racc_action_check = arr = ::Array.new(6809, nil) idx = 0 clist.each do |str| str.split(',', -1).each do |i| arr[idx] = i.to_i unless i.empty? idx += 1 end end racc_action_pointer = [ -2, 313, nil, nil, 118, 296, nil, 173, 295, 5793, 466, 526, 69, nil, nil, 670, 730, 790, 850, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 220, 256, 1054, 1114, 1174, 48, 1283, nil, nil, nil, nil, nil, 1402, 1462, 1546, nil, nil, nil, nil, nil, 1606, nil, 201, 202, nil, 1786, nil, nil, 267, 1906, 246, 2026, 2086, 2146, 2206, 2266, 2326, 2386, 2446, 2506, 2590, 2650, 2710, 2770, 2830, 2890, 2950, 3010, 3070, 3130, 3190, 3250, 3310, 3370, 3430, 3490, 3550, 3610, 3670, 3730, 3790, 217, 248, 3970, 4030, 245, 238, 4210, 219, nil, nil, nil, 1550, -1, 614, 938, 203, nil, 220, 55, 4822, 5562, nil, 5488, 5431, 200, 195, nil, 186, nil, nil, nil, nil, nil, nil, nil, 173, nil, 170, nil, 90, nil, nil, 166, nil, 14, nil, nil, 170, 4882, 60, 5656, 4762, nil, 135, nil, nil, nil, nil, 84, 79, 61, 266, 5995, 153, 4090, 5, 3, 2, 3910, 5302, 1966, nil, nil, -9, 82, 108, 287, -2, 4, -4, -1, nil, nil, nil, nil, nil, nil, 6042, 61, 1346, 2, 350, 5505, 6253, 5579, 5864, 6012, 6181, 5736, 6396, 6450, 6467, 6325, 6521, 6161, 6136, 5894, 5847, nil, - nil, 406, 231, 209, nil, 6691, 5609, 202, nil, 276, + nil, 406, 231, 209, nil, 6723, 5609, 202, nil, 276, 239, 5719, nil, 241, nil, 120, nil, nil, 262, nil, 230, nil, nil, nil, nil, nil, 217, 189, -24, 204, -7, nil, 1258, 1342, 1846, 170, 132, 4379, -28, 4150, 21, 55, nil, 4354, 4498, nil, nil, nil, nil, 4558, nil, nil, nil, nil, 92, nil, nil, nil, nil, 101, 119, 6561, 155, 6615, 4942, 5002, 5122, nil, 3850, 5242, - 181, nil, 170, nil, 185, 187, nil, nil, nil, nil, + 181, nil, 170, nil, 185, nil, 187, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 195, 5182, 6637, 200, nil, 93, nil, 200, 206, + nil, 195, 5182, 6669, 200, nil, 93, nil, 200, 206, nil, 149, 30, 5062, nil, nil, 4678, 4618, nil, 222, 83, 226, 204, 9, 4438, nil, 4270, 237, nil, 5405, nil, nil, nil, nil, nil, nil, nil, nil, nil, 178, 58, 238, nil, nil, 6089, 6233, 5374, 6305, 6379, 260, 1726, 203, -8, nil, nil, 263, 1666, nil, nil, nil, 251, nil, nil, nil, 5941, 13, 118, nil, 994, 274, 251, nil, 276, 277, nil, nil, 277, nil, nil, 934, nil, nil, nil, 282, 253, nil, nil, nil, nil, nil, 287, nil, nil, nil, nil, 610, nil, 346, 178, nil, 300, nil, nil, 58, nil, 304, nil, 306, nil, 307, nil, nil, nil, 278, nil, nil, nil, nil ] racc_action_default = [ -3, -241, -1, -2, -4, -5, -8, -10, -16, -21, -241, -241, -241, -33, -34, -241, -241, -241, -241, -61, -62, -63, -64, -65, -66, -67, -68, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -86, -90, -241, -241, -241, -241, -241, -174, -175, -176, -177, -178, -241, -241, -241, -189, -190, -191, -192, -193, -241, -195, -241, -208, -211, -241, -216, -217, -241, -241, -7, -241, -241, -241, -241, -241, -241, -241, -241, -126, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -121, -240, -240, -22, -23, -241, -240, -136, -157, -158, -46, -241, -47, -54, -241, -87, -241, -241, -241, -241, -97, -241, -241, -240, -218, -145, -147, -148, -149, -150, -151, -153, -154, -14, -218, -180, -218, -182, -241, -185, -186, -241, -194, -241, -199, -202, -241, -206, -241, -241, -241, 418, -6, -9, -11, -12, -13, -17, -18, -19, -20, -241, -218, -241, -79, -80, -81, -229, - -235, -223, -128, -131, -241, -226, -224, -232, -175, -176, + -235, -223, -127, -130, -241, -226, -224, -232, -175, -176, -177, -178, -222, -227, -228, -230, -231, -233, -59, -241, -36, -37, -38, -39, -40, -41, -42, -43, -44, -45, -48, -49, -50, -51, -52, -53, -55, -56, -241, -57, -115, -241, -218, -83, -91, -126, -125, -241, -124, -241, -220, -241, -28, -240, -159, -241, -58, -92, -241, -95, -218, -162, -164, -165, -166, -167, -169, -241, -241, -172, -241, -89, -241, -241, -241, -241, -240, -219, -241, -219, -241, -241, -183, -241, -241, -196, -197, -198, -200, -241, -203, -204, -205, -207, -218, -209, -212, -214, -215, -8, -241, -126, -241, -219, -241, -241, -241, -35, -241, -241, - -218, -117, -241, -85, -218, -241, -130, -223, -224, -225, + -218, -117, -241, -85, -218, -129, -241, -223, -224, -225, -226, -229, -232, -234, -235, -236, -237, -238, -239, -122, -123, -241, -221, -126, -241, -139, -241, -160, -218, -241, -94, -241, -219, -241, -170, -171, -241, -241, -88, -241, -100, -241, -106, -241, -241, -110, -240, -241, -155, -241, -146, -152, -15, -179, -181, -184, -187, -188, -201, -241, - -241, -218, -26, -129, -127, -132, -133, -60, -119, -241, + -241, -218, -26, -128, -133, -131, -132, -60, -119, -241, -219, -82, -241, -25, -29, -218, -240, -140, -141, -142, -241, -93, -96, -163, -168, -241, -100, -99, -241, -241, -106, -105, -241, -241, -109, -111, -241, -137, -138, -241, -156, -210, -213, -241, -30, -116, -118, -84, -120, -27, -241, -161, -173, -98, -101, -241, -104, -241, -240, -134, -241, -144, -24, -31, -135, -241, -103, -241, -108, -241, -113, -114, -143, -220, -102, -107, -112, -32 ] racc_goto_table = [ 2, 112, 114, 115, 117, 116, 224, 220, 125, 129, 131, 189, 210, 144, 301, 266, 330, 230, 367, 325, 376, 239, 409, 224, 246, 164, 324, 70, 121, 123, 124, 280, 223, 394, 250, 343, 251, 105, 106, 135, 135, 143, 227, 136, 138, 209, 371, 146, 264, 245, 390, 151, 239, 217, 219, 354, 304, 357, 155, 156, 157, 158, 272, 327, 393, 163, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 383, 135, 331, 216, 216, 212, 154, 221, 396, 363, 315, 314, 380, 375, 336, 260, 159, 160, 161, 162, 261, 135, 3, 258, 282, 240, 259, 257, 147, 149, 262, 1, nil, nil, nil, 305, nil, 308, 281, nil, nil, 239, 311, nil, nil, nil, nil, nil, nil, nil, nil, nil, 125, 269, 129, 131, nil, nil, 328, nil, nil, nil, nil, 263, nil, 114, 270, nil, nil, 121, 123, 124, nil, nil, nil, 284, 339, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 283, 349, nil, nil, nil, 352, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 208, nil, nil, nil, nil, nil, nil, 382, nil, 360, 417, nil, nil, 129, 131, 338, nil, 239, nil, nil, 341, nil, nil, nil, nil, nil, nil, 378, nil, nil, nil, 309, nil, 188, nil, nil, nil, nil, nil, 332, nil, nil, 384, 143, 337, 319, 321, nil, nil, 146, 365, nil, 355, nil, nil, nil, 389, 378, nil, nil, nil, nil, nil, 344, 345, 346, 386, 347, 348, nil, nil, nil, 358, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, nil, 129, 131, nil, nil, 410, nil, nil, 364, nil, nil, 188, 413, 332, nil, nil, nil, nil, nil, 188, nil, nil, nil, nil, 387, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 208, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 121, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 400, nil, nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, nil, nil, nil, 405, nil, 407, 411 ] racc_goto_check = [ 2, 10, 10, 10, 37, 6, 49, 13, 57, 35, 34, 19, 50, 80, 14, 88, 65, 42, 44, 47, 59, 36, 48, 49, 15, 11, 46, 5, 10, 10, 10, 51, 58, 43, 15, 54, 15, 9, 9, 6, 6, 6, 41, 8, 8, 20, 45, 6, 42, 58, 59, 10, 36, 53, 53, 16, 61, 62, 6, 6, 6, 6, 15, 64, 44, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 6, 67, 10, 10, 8, 5, 10, 45, 68, 69, 71, 65, 47, 75, 76, 9, 9, 9, 9, 77, 6, 3, 81, 15, 8, 82, 84, 85, 86, 87, 1, nil, nil, nil, 49, nil, 42, 50, nil, nil, 36, 15, nil, nil, nil, nil, nil, nil, nil, nil, nil, 57, 6, 35, 34, nil, nil, 49, nil, nil, nil, nil, 2, nil, 10, 2, nil, nil, 10, 10, 10, nil, nil, nil, 11, 15, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, 15, nil, nil, nil, 15, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, nil, nil, 88, nil, 15, 14, nil, nil, 35, 34, 80, nil, 36, nil, nil, 11, nil, nil, nil, nil, nil, nil, 49, nil, nil, nil, 2, nil, 10, nil, nil, nil, nil, nil, 6, nil, nil, 15, 6, 6, 2, 2, nil, nil, 6, 19, nil, 11, nil, nil, nil, 15, 49, nil, nil, nil, nil, nil, 10, 10, 10, 50, 10, 10, nil, nil, nil, 57, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, 35, 34, nil, nil, 49, nil, nil, 10, nil, nil, 10, 13, 6, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, nil, 2, nil, 2, 2 ] racc_goto_pointer = [ nil, 117, 0, 108, nil, 23, -13, nil, -9, 27, -14, -54, -255, -100, -206, -102, -247, nil, nil, -69, -54, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -36, -37, -98, -36, nil, nil, nil, -76, -102, -335, -302, -276, -218, -225, -376, -102, -87, -180, nil, -50, -238, nil, nil, -37, -76, -306, nil, -167, -249, nil, -183, -231, nil, -160, -217, -142, nil, -140, nil, nil, nil, -153, -47, -42, nil, nil, -47, -36, -33, nil, -32, 52, 52, -33, -136 ] racc_goto_default = [ nil, nil, 377, nil, 4, 5, 6, 7, nil, 8, 9, nil, nil, nil, nil, nil, 222, 13, 14, 323, nil, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, nil, 40, 41, 118, nil, nil, 122, nil, nil, nil, nil, nil, 218, nil, nil, 102, nil, 172, 174, 173, 109, nil, nil, 108, nil, nil, 126, nil, 127, 128, 132, 231, 232, 233, 234, 235, 238, 140, 142, 55, 56, 57, 60, nil, nil, nil, 145, nil, nil, nil, nil, nil ] racc_reduce_table = [ 0, 0, :racc_error, 1, 92, :_reduce_1, 1, 92, :_reduce_2, 0, 92, :_reduce_3, 1, 93, :_reduce_4, 1, 95, :_reduce_5, 3, 95, :_reduce_6, 2, 95, :_reduce_7, 1, 96, :_reduce_8, 3, 96, :_reduce_9, 1, 97, :_reduce_none, 3, 97, :_reduce_11, 3, 97, :_reduce_12, 3, 97, :_reduce_13, 1, 99, :_reduce_14, 3, 99, :_reduce_15, 1, 98, :_reduce_none, 3, 98, :_reduce_17, 3, 98, :_reduce_18, 3, 98, :_reduce_19, 3, 98, :_reduce_20, 1, 100, :_reduce_none, 2, 100, :_reduce_22, 2, 100, :_reduce_23, 7, 100, :_reduce_24, 5, 100, :_reduce_25, 5, 100, :_reduce_26, 4, 107, :_reduce_27, 1, 104, :_reduce_28, 3, 104, :_reduce_29, 1, 103, :_reduce_30, 2, 103, :_reduce_31, 4, 103, :_reduce_32, 1, 101, :_reduce_none, 1, 101, :_reduce_none, 4, 101, :_reduce_35, 3, 101, :_reduce_36, 3, 101, :_reduce_37, 3, 101, :_reduce_38, 3, 101, :_reduce_39, 3, 101, :_reduce_40, 3, 101, :_reduce_41, 3, 101, :_reduce_42, 3, 101, :_reduce_43, 3, 101, :_reduce_44, 3, 101, :_reduce_45, 2, 101, :_reduce_46, 2, 101, :_reduce_47, 3, 101, :_reduce_48, 3, 101, :_reduce_49, 3, 101, :_reduce_50, 3, 101, :_reduce_51, 3, 101, :_reduce_52, 3, 101, :_reduce_53, 2, 101, :_reduce_54, 3, 101, :_reduce_55, 3, 101, :_reduce_56, 3, 101, :_reduce_57, 3, 101, :_reduce_58, 1, 110, :_reduce_59, 3, 110, :_reduce_60, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_none, 1, 108, :_reduce_77, 1, 108, :_reduce_78, 1, 108, :_reduce_79, 1, 108, :_reduce_80, 1, 108, :_reduce_81, 5, 109, :_reduce_82, 3, 109, :_reduce_83, 6, 109, :_reduce_84, 4, 109, :_reduce_85, 1, 113, :_reduce_86, 2, 113, :_reduce_87, 4, 129, :_reduce_88, 3, 129, :_reduce_89, 1, 129, :_reduce_90, 3, 130, :_reduce_91, 2, 128, :_reduce_92, 3, 132, :_reduce_93, 2, 132, :_reduce_94, 2, 131, :_reduce_95, 4, 131, :_reduce_96, 2, 116, :_reduce_97, 5, 134, :_reduce_98, 4, 134, :_reduce_99, 0, 135, :_reduce_none, 2, 135, :_reduce_101, 4, 135, :_reduce_102, 3, 135, :_reduce_103, 6, 117, :_reduce_104, 5, 117, :_reduce_105, 0, 136, :_reduce_none, 4, 136, :_reduce_107, 3, 136, :_reduce_108, 5, 115, :_reduce_109, 1, 137, :_reduce_110, 2, 137, :_reduce_111, 5, 138, :_reduce_112, 1, 139, :_reduce_none, 1, 139, :_reduce_none, 1, 111, :_reduce_none, 4, 111, :_reduce_116, 1, 142, :_reduce_117, 3, 142, :_reduce_118, 3, 141, :_reduce_119, 6, 114, :_reduce_120, 2, 114, :_reduce_121, 3, 143, :_reduce_122, 3, 143, :_reduce_123, 1, 144, :_reduce_none, 1, 144, :_reduce_none, 0, 102, :_reduce_126, - 3, 102, :_reduce_127, - 1, 102, :_reduce_128, - 3, 102, :_reduce_129, + 1, 102, :_reduce_127, + 3, 102, :_reduce_128, 1, 146, :_reduce_none, 1, 146, :_reduce_none, + 3, 145, :_reduce_131, 3, 145, :_reduce_132, 3, 145, :_reduce_133, 6, 118, :_reduce_134, 7, 119, :_reduce_135, 1, 151, :_reduce_136, 1, 150, :_reduce_none, 1, 150, :_reduce_none, 1, 152, :_reduce_none, 2, 152, :_reduce_140, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 7, 120, :_reduce_143, 6, 120, :_reduce_144, 1, 154, :_reduce_145, 3, 154, :_reduce_146, 1, 156, :_reduce_none, 1, 156, :_reduce_none, 1, 156, :_reduce_149, 1, 156, :_reduce_none, 1, 157, :_reduce_151, 3, 157, :_reduce_152, 1, 158, :_reduce_none, 1, 158, :_reduce_none, 1, 155, :_reduce_none, 2, 155, :_reduce_156, 1, 148, :_reduce_none, 1, 148, :_reduce_158, 1, 149, :_reduce_159, 2, 149, :_reduce_160, 4, 149, :_reduce_161, 1, 133, :_reduce_162, 3, 133, :_reduce_163, 1, 159, :_reduce_none, 1, 159, :_reduce_none, 1, 160, :_reduce_none, 1, 160, :_reduce_none, 3, 162, :_reduce_168, 1, 162, :_reduce_169, 2, 163, :_reduce_170, 2, 161, :_reduce_171, 1, 164, :_reduce_172, 4, 164, :_reduce_173, 1, 112, :_reduce_174, 1, 122, :_reduce_175, 1, 122, :_reduce_176, 1, 122, :_reduce_177, 1, 122, :_reduce_178, 4, 123, :_reduce_179, 2, 123, :_reduce_180, 4, 123, :_reduce_181, 2, 123, :_reduce_182, 3, 124, :_reduce_183, 4, 124, :_reduce_184, 2, 124, :_reduce_185, 1, 165, :_reduce_186, 3, 165, :_reduce_187, 3, 166, :_reduce_188, 1, 126, :_reduce_none, 1, 126, :_reduce_none, 1, 126, :_reduce_none, 1, 167, :_reduce_192, 1, 167, :_reduce_193, 2, 168, :_reduce_194, 1, 170, :_reduce_195, 1, 172, :_reduce_196, 1, 173, :_reduce_197, 2, 171, :_reduce_198, 1, 174, :_reduce_199, 1, 175, :_reduce_200, 2, 175, :_reduce_201, 2, 169, :_reduce_202, 2, 176, :_reduce_203, 2, 176, :_reduce_204, 3, 94, :_reduce_205, 0, 178, :_reduce_none, 1, 178, :_reduce_none, 0, 177, :_reduce_208, 2, 177, :_reduce_209, 4, 177, :_reduce_210, 1, 121, :_reduce_211, 3, 121, :_reduce_212, 5, 121, :_reduce_213, 1, 179, :_reduce_none, 1, 179, :_reduce_none, 1, 127, :_reduce_216, 1, 125, :_reduce_217, 0, 106, :_reduce_none, 1, 106, :_reduce_219, 0, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 1, 147, :_reduce_none, 0, 140, :_reduce_240 ] racc_reduce_n = 241 racc_shift_n = 418 racc_token_table = { false => 0, :error => 1, :STRING => 2, :DQPRE => 3, :DQMID => 4, :DQPOST => 5, :WORD => 6, :LBRACK => 7, :RBRACK => 8, :LBRACE => 9, :RBRACE => 10, :SYMBOL => 11, :FARROW => 12, :COMMA => 13, :TRUE => 14, :FALSE => 15, :EQUALS => 16, :APPENDS => 17, :DELETES => 18, :LESSEQUAL => 19, :NOTEQUAL => 20, :DOT => 21, :COLON => 22, :LLCOLLECT => 23, :RRCOLLECT => 24, :QMARK => 25, :LPAREN => 26, :RPAREN => 27, :ISEQUAL => 28, :GREATEREQUAL => 29, :GREATERTHAN => 30, :LESSTHAN => 31, :IF => 32, :ELSE => 33, :DEFINE => 34, :ELSIF => 35, :VARIABLE => 36, :CLASS => 37, :INHERITS => 38, :NODE => 39, :BOOLEAN => 40, :NAME => 41, :SEMIC => 42, :CASE => 43, :DEFAULT => 44, :AT => 45, :ATAT => 46, :LCOLLECT => 47, :RCOLLECT => 48, :CLASSREF => 49, :NOT => 50, :OR => 51, :AND => 52, :UNDEF => 53, :PARROW => 54, :PLUS => 55, :MINUS => 56, :TIMES => 57, :DIV => 58, :LSHIFT => 59, :RSHIFT => 60, :UMINUS => 61, :MATCH => 62, :NOMATCH => 63, :REGEX => 64, :IN_EDGE => 65, :OUT_EDGE => 66, :IN_EDGE_SUB => 67, :OUT_EDGE_SUB => 68, :IN => 69, :UNLESS => 70, :PIPE => 71, :LAMBDA => 72, :SELBRACE => 73, :NUMBER => 74, :HEREDOC => 75, :SUBLOCATE => 76, :RENDER_STRING => 77, :RENDER_EXPR => 78, :EPP_START => 79, :EPP_END => 80, :EPP_END_TRIM => 81, :FUNCTION => 82, :PRIVATE => 83, :ATTR => 84, :TYPE => 85, :LOW => 86, :HIGH => 87, :LISTSTART => 88, :SPLAT => 89, :MODULO => 90 } racc_nt_base = 91 racc_use_result_var = true Racc_arg = [ racc_action_table, racc_action_check, racc_action_default, racc_action_pointer, racc_goto_table, racc_goto_check, racc_goto_default, racc_goto_pointer, racc_nt_base, racc_reduce_table, racc_token_table, racc_shift_n, racc_reduce_n, racc_use_result_var ] Racc_token_to_s_table = [ "$end", "error", "STRING", "DQPRE", "DQMID", "DQPOST", "WORD", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "SYMBOL", "FARROW", "COMMA", "TRUE", "FALSE", "EQUALS", "APPENDS", "DELETES", "LESSEQUAL", "NOTEQUAL", "DOT", "COLON", "LLCOLLECT", "RRCOLLECT", "QMARK", "LPAREN", "RPAREN", "ISEQUAL", "GREATEREQUAL", "GREATERTHAN", "LESSTHAN", "IF", "ELSE", "DEFINE", "ELSIF", "VARIABLE", "CLASS", "INHERITS", "NODE", "BOOLEAN", "NAME", "SEMIC", "CASE", "DEFAULT", "AT", "ATAT", "LCOLLECT", "RCOLLECT", "CLASSREF", "NOT", "OR", "AND", "UNDEF", "PARROW", "PLUS", "MINUS", "TIMES", "DIV", "LSHIFT", "RSHIFT", "UMINUS", "MATCH", "NOMATCH", "REGEX", "IN_EDGE", "OUT_EDGE", "IN_EDGE_SUB", "OUT_EDGE_SUB", "IN", "UNLESS", "PIPE", "LAMBDA", "SELBRACE", "NUMBER", "HEREDOC", "SUBLOCATE", "RENDER_STRING", "RENDER_EXPR", "EPP_START", "EPP_END", "EPP_END_TRIM", "FUNCTION", "PRIVATE", "ATTR", "TYPE", "LOW", "HIGH", "LISTSTART", "SPLAT", "MODULO", "$start", "program", "statements", "epp_expression", "syntactic_statements", "syntactic_statement", "assignment", "relationship", "assignments", "resource", "expression", "attribute_operations", "additional_resource_bodies", "resource_bodies", "endsemi", "endcomma", "resource_body", "primary_expression", "call_function_expression", "expressions", "selector_entries", "variable", "call_method_with_lambda_expression", "collection_expression", "case_expression", "if_expression", "unless_expression", "definition_expression", "hostclass_expression", "node_definition_expression", "epp_render_expression", "reserved_word", "array", "hash", "regex", "quotedtext", "type", "lambda", "call_method_expression", "named_access", "lambda_parameter_list", "lambda_rest", "parameters", "if_part", "else", "unless_else", "case_options", "case_option", "options_statements", "nil", "selector_entry", "selector_entry_list", "collect_query", "optional_query", "attribute_operation", "attribute_name", "keyword", "classname", "parameter_list", "opt_statements", "stacked_classname", "classparent", "classnameordefault", "hostnames", "nodeparent", "hostname", "dotted_name", "name_or_number", "parameter", "untyped_parameter", "typed_parameter", "regular_parameter", "splat_parameter", "parameter_type", "hashpairs", "hashpair", "string", "dq_string", "heredoc", "dqpre", "dqrval", "dqpost", "dqmid", "text_expression", "dqtail", "sublocated_text", "epp_parameters_list", "optional_statements", "epp_end" ] Racc_debug_parser = false ##### State transition tables end ##### # reduce 0 omitted module_eval(<<'.,.,', 'egrammar.ra', 65) def _reduce_1(val, _values, result) result = create_program(Factory.block_or_expression(*val[0])) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 66) def _reduce_2(val, _values, result) result = create_program(Factory.block_or_expression(*val[0])) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 67) def _reduce_3(val, _values, result) result = create_empty_program() result end .,., module_eval(<<'.,.,', 'egrammar.ra', 71) def _reduce_4(val, _values, result) result = transform_calls(val[0]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 78) def _reduce_5(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 79) def _reduce_6(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 80) def _reduce_7(val, _values, result) result = val[0].push val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 87) def _reduce_8(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 88) def _reduce_9(val, _values, result) result = aryfy(val[0]).push val[2] result end .,., # reduce 10 omitted module_eval(<<'.,.,', 'egrammar.ra', 93) def _reduce_11(val, _values, result) result = val[0].set(val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 94) def _reduce_12(val, _values, result) result = val[0].plus_set(val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 95) def _reduce_13(val, _values, result) result = val[0].minus_set(val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 98) def _reduce_14(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 99) def _reduce_15(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 16 omitted module_eval(<<'.,.,', 'egrammar.ra', 103) def _reduce_17(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 104) def _reduce_18(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 105) def _reduce_19(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 106) def _reduce_20(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., # reduce 21 omitted module_eval(<<'.,.,', 'egrammar.ra', 115) def _reduce_22(val, _values, result) result = val[1] unless Factory.set_resource_form(result, :virtual) # This is equivalent to a syntax error - additional semantic restrictions apply error val[0], "Virtual (@) can only be applied to a Resource Expression" end # relocate the result loc result, val[0], val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 126) def _reduce_23(val, _values, result) result = val[1] unless Factory.set_resource_form(result, :exported) # This is equivalent to a syntax error - additional semantic restrictions apply error val[0], "Exported (@@) can only be applied to a Resource Expression" end # relocate the result loc result, val[0], val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 137) def _reduce_24(val, _values, result) bodies = [Factory.RESOURCE_BODY(val[2], val[4])] + val[5] result = Factory.RESOURCE(val[0], bodies) loc result, val[0], val[6] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 144) def _reduce_25(val, _values, result) result = Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 153) def _reduce_26(val, _values, result) result = case Factory.resource_shape(val[0]) when :resource, :class # This catches deprecated syntax. # If the attribute operations does not include +>, then the found expression # is actually a LEFT followed by LITERAL_HASH # unless tmp = transform_resource_wo_title(val[0], val[2]) error val[1], "Syntax error resource body without title or hash with +>" end tmp when :defaults Factory.RESOURCE_DEFAULTS(val[0], val[2]) when :override # This was only done for override in original - TODO should it be here at all Factory.RESOURCE_OVERRIDE(val[0], val[2]) else error val[0], "Expression is not valid as a resource, resource-default, or resource-override" end loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 175) def _reduce_27(val, _values, result) result = Factory.RESOURCE_BODY(val[0], val[2]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 178) def _reduce_28(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 179) def _reduce_29(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 185) def _reduce_30(val, _values, result) result = [] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 186) def _reduce_31(val, _values, result) result = [] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 187) def _reduce_32(val, _values, result) result = val[2] result end .,., # reduce 33 omitted # reduce 34 omitted module_eval(<<'.,.,', 'egrammar.ra', 194) def _reduce_35(val, _values, result) result = val[0][*val[2]] ; loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 195) def _reduce_36(val, _values, result) result = val[0].in val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 196) def _reduce_37(val, _values, result) result = val[0] =~ val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 197) def _reduce_38(val, _values, result) result = val[0].mne val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 198) def _reduce_39(val, _values, result) result = val[0] + val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 199) def _reduce_40(val, _values, result) result = val[0] - val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 200) def _reduce_41(val, _values, result) result = val[0] / val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 201) def _reduce_42(val, _values, result) result = val[0] * val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 202) def _reduce_43(val, _values, result) result = val[0] % val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 203) def _reduce_44(val, _values, result) result = val[0] << val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 204) def _reduce_45(val, _values, result) result = val[0] >> val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 205) def _reduce_46(val, _values, result) result = val[1].minus() ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 206) def _reduce_47(val, _values, result) result = val[1].unfold() ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 207) def _reduce_48(val, _values, result) result = val[0].ne val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 208) def _reduce_49(val, _values, result) result = val[0] == val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 209) def _reduce_50(val, _values, result) result = val[0] > val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 210) def _reduce_51(val, _values, result) result = val[0] >= val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 211) def _reduce_52(val, _values, result) result = val[0] < val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 212) def _reduce_53(val, _values, result) result = val[0] <= val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 213) def _reduce_54(val, _values, result) result = val[1].not ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 214) def _reduce_55(val, _values, result) result = val[0].and val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 215) def _reduce_56(val, _values, result) result = val[0].or val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 216) def _reduce_57(val, _values, result) result = val[0].select(*val[2]) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 217) def _reduce_58(val, _values, result) result = val[1].paren() ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 227) def _reduce_59(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 228) def _reduce_60(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 61 omitted # reduce 62 omitted # reduce 63 omitted # reduce 64 omitted # reduce 65 omitted # reduce 66 omitted # reduce 67 omitted # reduce 68 omitted # reduce 69 omitted # reduce 70 omitted # reduce 71 omitted # reduce 72 omitted # reduce 73 omitted # reduce 74 omitted # reduce 75 omitted # reduce 76 omitted module_eval(<<'.,.,', 'egrammar.ra', 247) def _reduce_77(val, _values, result) result = Factory.NUMBER(val[0][:value]) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 248) def _reduce_78(val, _values, result) result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 249) def _reduce_79(val, _values, result) result = Factory.literal(:default) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 250) def _reduce_80(val, _values, result) result = Factory.literal(:undef) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 251) def _reduce_81(val, _values, result) result = Factory.QNAME_OR_NUMBER(val[0][:value]) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 260) def _reduce_82(val, _values, result) result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 264) def _reduce_83(val, _values, result) result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 268) def _reduce_84(val, _values, result) result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] result.lambda = val[5] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 273) def _reduce_85(val, _values, result) result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] result.lambda = val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 281) def _reduce_86(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 282) def _reduce_87(val, _values, result) result = val[0]; val[0].lambda = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 285) def _reduce_88(val, _values, result) result = Factory.CALL_METHOD(val[0], val[2]); loc result, val[1], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 286) def _reduce_89(val, _values, result) result = Factory.CALL_METHOD(val[0], []); loc result, val[1], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 287) def _reduce_90(val, _values, result) result = Factory.CALL_METHOD(val[0], []); loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 291) def _reduce_91(val, _values, result) result = val[0].dot(Factory.fqn(val[2][:value])) loc result, val[1], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 299) def _reduce_92(val, _values, result) result = Factory.LAMBDA(val[0][:value], val[1][:value]) loc result, val[0][:start], val[1][:end] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 304) def _reduce_93(val, _values, result) result = {:end => val[2], :value =>val[1] } result end .,., module_eval(<<'.,.,', 'egrammar.ra', 305) def _reduce_94(val, _values, result) result = {:end => val[1], :value => nil } result end .,., module_eval(<<'.,.,', 'egrammar.ra', 309) def _reduce_95(val, _values, result) result = {:start => val[0], :value => [] } result end .,., module_eval(<<'.,.,', 'egrammar.ra', 310) def _reduce_96(val, _values, result) result = {:start => val[0], :value => val[1] } result end .,., module_eval(<<'.,.,', 'egrammar.ra', 318) def _reduce_97(val, _values, result) result = val[1] loc(result, val[0], val[1]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 325) def _reduce_98(val, _values, result) result = Factory.IF(val[0], Factory.block_or_expression(*val[2]), val[4]) loc(result, val[0], (val[4] ? val[4] : val[3])) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 329) def _reduce_99(val, _values, result) result = Factory.IF(val[0], nil, val[3]) loc(result, val[0], (val[3] ? val[3] : val[2])) result end .,., # reduce 100 omitted module_eval(<<'.,.,', 'egrammar.ra', 337) def _reduce_101(val, _values, result) result = val[1] loc(result, val[0], val[1]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 341) def _reduce_102(val, _values, result) result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 345) def _reduce_103(val, _values, result) result = nil # don't think a nop is needed here either result end .,., module_eval(<<'.,.,', 'egrammar.ra', 352) def _reduce_104(val, _values, result) result = Factory.UNLESS(val[1], Factory.block_or_expression(*val[3]), val[5]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 356) def _reduce_105(val, _values, result) result = Factory.UNLESS(val[1], nil, nil) loc result, val[0], val[4] result end .,., # reduce 106 omitted module_eval(<<'.,.,', 'egrammar.ra', 366) def _reduce_107(val, _values, result) result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 370) def _reduce_108(val, _values, result) result = nil # don't think a nop is needed here either result end .,., module_eval(<<'.,.,', 'egrammar.ra', 377) def _reduce_109(val, _values, result) result = Factory.CASE(val[1], *val[3]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 383) def _reduce_110(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 384) def _reduce_111(val, _values, result) result = val[0].push val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 389) def _reduce_112(val, _values, result) result = Factory.WHEN(val[0], val[3]); loc result, val[1], val[4] result end .,., # reduce 113 omitted # reduce 114 omitted # reduce 115 omitted module_eval(<<'.,.,', 'egrammar.ra', 405) def _reduce_116(val, _values, result) result = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 410) def _reduce_117(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 411) def _reduce_118(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 416) def _reduce_119(val, _values, result) result = Factory.MAP(val[0], val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 426) def _reduce_120(val, _values, result) result = Factory.COLLECT(val[0], val[1], val[3]) loc result, val[0], val[5] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 430) def _reduce_121(val, _values, result) result = Factory.COLLECT(val[0], val[1], []) loc result, val[0], val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 435) def _reduce_122(val, _values, result) result = Factory.VIRTUAL_QUERY(val[1]) ; loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 436) def _reduce_123(val, _values, result) result = Factory.EXPORTED_QUERY(val[1]) ; loc result, val[0], val[2] result end .,., # reduce 124 omitted # reduce 125 omitted module_eval(<<'.,.,', 'egrammar.ra', 445) def _reduce_126(val, _values, result) result = [] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 446) def _reduce_127(val, _values, result) - result = [tmp = Factory.ATTRIBUTES_OP(val[2])] ; loc tmp, val[0], val[2] + result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 447) def _reduce_128(val, _values, result) - result = [val[0]] - result - end -.,., - -module_eval(<<'.,.,', 'egrammar.ra', 448) - def _reduce_129(val, _values, result) result = val[0].push(val[2]) result end .,., -# reduce 130 omitted +# reduce 129 omitted -# reduce 131 omitted +# reduce 130 omitted -module_eval(<<'.,.,', 'egrammar.ra', 464) - def _reduce_132(val, _values, result) +module_eval(<<'.,.,', 'egrammar.ra', 463) + def _reduce_131(val, _values, result) result = Factory.ATTRIBUTE_OP(val[0][:value], :'=>', val[2]) loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 468) - def _reduce_133(val, _values, result) +module_eval(<<'.,.,', 'egrammar.ra', 467) + def _reduce_132(val, _values, result) result = Factory.ATTRIBUTE_OP(val[0][:value], :'+>', val[2]) loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 478) +module_eval(<<'.,.,', 'egrammar.ra', 471) + def _reduce_133(val, _values, result) + result = Factory.ATTRIBUTES_OP(val[2]) ; loc result, val[0], val[2] + + result + end +.,., + +module_eval(<<'.,.,', 'egrammar.ra', 480) def _reduce_134(val, _values, result) result = add_definition(Factory.DEFINITION(classname(val[1][:value]), val[2], val[4])) loc result, val[0], val[5] # New lexer does not keep track of this, this is done in validation if @lexer.respond_to?(:'indefine=') @lexer.indefine = false end result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 492) +module_eval(<<'.,.,', 'egrammar.ra', 494) def _reduce_135(val, _values, result) # Remove this class' name from the namestack as all nested classes have been parsed namepop result = add_definition(Factory.HOSTCLASS(classname(val[1][:value]), val[2], token_text(val[3]), val[5])) loc result, val[0], val[6] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 502) +module_eval(<<'.,.,', 'egrammar.ra', 504) def _reduce_136(val, _values, result) namestack(val[0][:value]) ; result = val[0] result end .,., # reduce 137 omitted # reduce 138 omitted # reduce 139 omitted -module_eval(<<'.,.,', 'egrammar.ra', 511) +module_eval(<<'.,.,', 'egrammar.ra', 513) def _reduce_140(val, _values, result) result = val[1] result end .,., # reduce 141 omitted # reduce 142 omitted -module_eval(<<'.,.,', 'egrammar.ra', 528) +module_eval(<<'.,.,', 'egrammar.ra', 530) def _reduce_143(val, _values, result) result = add_definition(Factory.NODE(val[1], val[3], val[5])) loc result, val[0], val[6] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 532) +module_eval(<<'.,.,', 'egrammar.ra', 534) def _reduce_144(val, _values, result) result = add_definition(Factory.NODE(val[1], val[3], nil)) loc result, val[0], val[5] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 542) +module_eval(<<'.,.,', 'egrammar.ra', 544) def _reduce_145(val, _values, result) result = [result] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 543) +module_eval(<<'.,.,', 'egrammar.ra', 545) def _reduce_146(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 147 omitted # reduce 148 omitted -module_eval(<<'.,.,', 'egrammar.ra', 550) +module_eval(<<'.,.,', 'egrammar.ra', 552) def _reduce_149(val, _values, result) result = Factory.literal(:default); loc result, val[0] result end .,., # reduce 150 omitted -module_eval(<<'.,.,', 'egrammar.ra', 554) +module_eval(<<'.,.,', 'egrammar.ra', 556) def _reduce_151(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 555) +module_eval(<<'.,.,', 'egrammar.ra', 557) def _reduce_152(val, _values, result) result = Factory.concat(val[0], '.', val[2][:value]); loc result, val[0], val[2] result end .,., # reduce 153 omitted # reduce 154 omitted # reduce 155 omitted -module_eval(<<'.,.,', 'egrammar.ra', 564) +module_eval(<<'.,.,', 'egrammar.ra', 566) def _reduce_156(val, _values, result) result = val[1] result end .,., # reduce 157 omitted -module_eval(<<'.,.,', 'egrammar.ra', 581) +module_eval(<<'.,.,', 'egrammar.ra', 583) def _reduce_158(val, _values, result) error val[0], "'class' is not a valid classname" result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 585) +module_eval(<<'.,.,', 'egrammar.ra', 587) def _reduce_159(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 586) +module_eval(<<'.,.,', 'egrammar.ra', 588) def _reduce_160(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 587) +module_eval(<<'.,.,', 'egrammar.ra', 589) def _reduce_161(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 591) +module_eval(<<'.,.,', 'egrammar.ra', 593) def _reduce_162(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 592) +module_eval(<<'.,.,', 'egrammar.ra', 594) def _reduce_163(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 164 omitted # reduce 165 omitted # reduce 166 omitted # reduce 167 omitted -module_eval(<<'.,.,', 'egrammar.ra', 604) +module_eval(<<'.,.,', 'egrammar.ra', 606) def _reduce_168(val, _values, result) result = Factory.PARAM(val[0][:value], val[2]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 605) +module_eval(<<'.,.,', 'egrammar.ra', 607) def _reduce_169(val, _values, result) result = Factory.PARAM(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 608) +module_eval(<<'.,.,', 'egrammar.ra', 610) def _reduce_170(val, _values, result) result = val[1]; val[1].captures_rest() result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 611) +module_eval(<<'.,.,', 'egrammar.ra', 613) def _reduce_171(val, _values, result) val[1].type_expr(val[0]) ; result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 614) +module_eval(<<'.,.,', 'egrammar.ra', 616) def _reduce_172(val, _values, result) result = val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 615) +module_eval(<<'.,.,', 'egrammar.ra', 617) def _reduce_173(val, _values, result) result = val[0][*val[2]] ; loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 620) +module_eval(<<'.,.,', 'egrammar.ra', 622) def _reduce_174(val, _values, result) result = Factory.fqn(val[0][:value]).var ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 625) +module_eval(<<'.,.,', 'egrammar.ra', 627) def _reduce_175(val, _values, result) result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 626) +module_eval(<<'.,.,', 'egrammar.ra', 628) def _reduce_176(val, _values, result) result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 627) +module_eval(<<'.,.,', 'egrammar.ra', 629) def _reduce_177(val, _values, result) result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 628) +module_eval(<<'.,.,', 'egrammar.ra', 630) def _reduce_178(val, _values, result) result = Factory.RESERVED(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 634) +module_eval(<<'.,.,', 'egrammar.ra', 636) def _reduce_179(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 635) +module_eval(<<'.,.,', 'egrammar.ra', 637) def _reduce_180(val, _values, result) result = Factory.literal([]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 636) +module_eval(<<'.,.,', 'egrammar.ra', 638) def _reduce_181(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 637) +module_eval(<<'.,.,', 'egrammar.ra', 639) def _reduce_182(val, _values, result) result = Factory.literal([]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 640) +module_eval(<<'.,.,', 'egrammar.ra', 642) def _reduce_183(val, _values, result) result = Factory.HASH(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 641) +module_eval(<<'.,.,', 'egrammar.ra', 643) def _reduce_184(val, _values, result) result = Factory.HASH(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 642) +module_eval(<<'.,.,', 'egrammar.ra', 644) def _reduce_185(val, _values, result) result = Factory.literal({}) ; loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 645) +module_eval(<<'.,.,', 'egrammar.ra', 647) def _reduce_186(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 646) +module_eval(<<'.,.,', 'egrammar.ra', 648) def _reduce_187(val, _values, result) result = val[0].push val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 649) +module_eval(<<'.,.,', 'egrammar.ra', 651) def _reduce_188(val, _values, result) result = Factory.KEY_ENTRY(val[0], val[2]); loc result, val[1] result end .,., # reduce 189 omitted # reduce 190 omitted # reduce 191 omitted -module_eval(<<'.,.,', 'egrammar.ra', 657) +module_eval(<<'.,.,', 'egrammar.ra', 659) def _reduce_192(val, _values, result) result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 658) +module_eval(<<'.,.,', 'egrammar.ra', 660) def _reduce_193(val, _values, result) result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 660) +module_eval(<<'.,.,', 'egrammar.ra', 662) def _reduce_194(val, _values, result) result = Factory.string(val[0], *val[1]) ; loc result, val[0], val[1][-1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 661) +module_eval(<<'.,.,', 'egrammar.ra', 663) def _reduce_195(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 662) +module_eval(<<'.,.,', 'egrammar.ra', 664) def _reduce_196(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 663) +module_eval(<<'.,.,', 'egrammar.ra', 665) def _reduce_197(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 664) +module_eval(<<'.,.,', 'egrammar.ra', 666) def _reduce_198(val, _values, result) result = [val[0]] + val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 665) +module_eval(<<'.,.,', 'egrammar.ra', 667) def _reduce_199(val, _values, result) result = Factory.TEXT(val[0]) result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 668) +module_eval(<<'.,.,', 'egrammar.ra', 670) def _reduce_200(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 669) +module_eval(<<'.,.,', 'egrammar.ra', 671) def _reduce_201(val, _values, result) result = [val[0]] + val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 672) +module_eval(<<'.,.,', 'egrammar.ra', 674) def _reduce_202(val, _values, result) result = Factory.HEREDOC(val[0][:value], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 675) +module_eval(<<'.,.,', 'egrammar.ra', 677) def _reduce_203(val, _values, result) result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 676) +module_eval(<<'.,.,', 'egrammar.ra', 678) def _reduce_204(val, _values, result) result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 679) +module_eval(<<'.,.,', 'egrammar.ra', 681) def _reduce_205(val, _values, result) result = Factory.EPP(val[1], val[2]); loc result, val[0] result end .,., # reduce 206 omitted # reduce 207 omitted -module_eval(<<'.,.,', 'egrammar.ra', 686) +module_eval(<<'.,.,', 'egrammar.ra', 688) def _reduce_208(val, _values, result) result = nil result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 687) +module_eval(<<'.,.,', 'egrammar.ra', 689) def _reduce_209(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 688) +module_eval(<<'.,.,', 'egrammar.ra', 690) def _reduce_210(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 691) +module_eval(<<'.,.,', 'egrammar.ra', 693) def _reduce_211(val, _values, result) result = Factory.RENDER_STRING(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 692) +module_eval(<<'.,.,', 'egrammar.ra', 694) def _reduce_212(val, _values, result) result = Factory.RENDER_EXPR(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 693) +module_eval(<<'.,.,', 'egrammar.ra', 695) def _reduce_213(val, _values, result) result = Factory.RENDER_EXPR(Factory.block_or_expression(*val[2])); loc result, val[0], val[4] result end .,., # reduce 214 omitted # reduce 215 omitted -module_eval(<<'.,.,', 'egrammar.ra', 699) +module_eval(<<'.,.,', 'egrammar.ra', 701) def _reduce_216(val, _values, result) result = Factory.QREF(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 702) +module_eval(<<'.,.,', 'egrammar.ra', 704) def _reduce_217(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., # reduce 218 omitted -module_eval(<<'.,.,', 'egrammar.ra', 708) +module_eval(<<'.,.,', 'egrammar.ra', 710) def _reduce_219(val, _values, result) result = nil result end .,., # reduce 220 omitted # reduce 221 omitted # reduce 222 omitted # reduce 223 omitted # reduce 224 omitted # reduce 225 omitted # reduce 226 omitted # reduce 227 omitted # reduce 228 omitted # reduce 229 omitted # reduce 230 omitted # reduce 231 omitted # reduce 232 omitted # reduce 233 omitted # reduce 234 omitted # reduce 235 omitted # reduce 236 omitted # reduce 237 omitted # reduce 238 omitted # reduce 239 omitted -module_eval(<<'.,.,', 'egrammar.ra', 735) +module_eval(<<'.,.,', 'egrammar.ra', 737) def _reduce_240(val, _values, result) result = nil result end .,., def _reduce_none(val, _values, result) val[0] end end # class Parser end # module Parser end # module Pops end # module Puppet diff --git a/spec/integration/parser/resource_expressions_spec.rb b/spec/integration/parser/resource_expressions_spec.rb index 95da60b4d..a7d42a6ad 100644 --- a/spec/integration/parser/resource_expressions_spec.rb +++ b/spec/integration/parser/resource_expressions_spec.rb @@ -1,242 +1,262 @@ require 'spec_helper' require 'puppet_spec/language' describe "Puppet resource expressions" do extend PuppetSpec::Language describe "future parser" do before :each do Puppet[:parser] = 'future' end produces( "$a = notify; $b = example; $c = { message => hello }; @@$a { $b: * => $c } realize(Resource[$a, $b])" => "Notify[example][message] == 'hello'") context "resource titles" do produces( "notify { thing: }" => "defined(Notify[thing])", "$x = thing notify { $x: }" => "defined(Notify[thing])", "notify { [thing]: }" => "defined(Notify[thing])", "$x = [thing] notify { $x: }" => "defined(Notify[thing])", "notify { [[nested, array]]: }" => "defined(Notify[nested]) and defined(Notify[array])", "$x = [[nested, array]] notify { $x: }" => "defined(Notify[nested]) and defined(Notify[array])", "notify { []: }" => [], # this asserts nothing added "$x = [] notify { $x: }" => [], # this asserts nothing added "notify { default: }" => "!defined(Notify['default'])", # nothing created because this is just a local default "$x = default notify { $x: }" => "!defined(Notify['default'])") fails( "notify { '': }" => /Empty string title/, "$x = '' notify { $x: }" => /Empty string title/, "notify { 1: }" => /Illegal title type.*Expected String, got Integer/, "$x = 1 notify { $x: }" => /Illegal title type.*Expected String, got Integer/, "notify { [1]: }" => /Illegal title type.*Expected String, got Integer/, "$x = [1] notify { $x: }" => /Illegal title type.*Expected String, got Integer/, "notify { 3.0: }" => /Illegal title type.*Expected String, got Float/, "$x = 3.0 notify { $x: }" => /Illegal title type.*Expected String, got Float/, "notify { [3.0]: }" => /Illegal title type.*Expected String, got Float/, "$x = [3.0] notify { $x: }" => /Illegal title type.*Expected String, got Float/, "notify { true: }" => /Illegal title type.*Expected String, got Boolean/, "$x = true notify { $x: }" => /Illegal title type.*Expected String, got Boolean/, "notify { [true]: }" => /Illegal title type.*Expected String, got Boolean/, "$x = [true] notify { $x: }" => /Illegal title type.*Expected String, got Boolean/, "notify { [false]: }" => /Illegal title type.*Expected String, got Boolean/, "$x = [false] notify { $x: }" => /Illegal title type.*Expected String, got Boolean/, "notify { undef: }" => /Missing title.*undef/, "$x = undef notify { $x: }" => /Missing title.*undef/, "notify { [undef]: }" => /Missing title.*undef/, "$x = [undef] notify { $x: }" => /Missing title.*undef/, "notify { {nested => hash}: }" => /Illegal title type.*Expected String, got Hash/, "$x = {nested => hash} notify { $x: }" => /Illegal title type.*Expected String, got Hash/, "notify { [{nested => hash}]: }" => /Illegal title type.*Expected String, got Hash/, "$x = [{nested => hash}] notify { $x: }" => /Illegal title type.*Expected String, got Hash/, "notify { /regexp/: }" => /Illegal title type.*Expected String, got Regexp/, "$x = /regexp/ notify { $x: }" => /Illegal title type.*Expected String, got Regexp/, "notify { [/regexp/]: }" => /Illegal title type.*Expected String, got Regexp/, "$x = [/regexp/] notify { $x: }" => /Illegal title type.*Expected String, got Regexp/, "notify { [dupe, dupe]: }" => /The title 'dupe' has already been used/, "notify { dupe:; dupe: }" => /The title 'dupe' has already been used/, "notify { [dupe]:; dupe: }" => /The title 'dupe' has already been used/, "notify { [default, default]:}" => /The title 'default' has already been used/, "notify { default:; default:}" => /The title 'default' has already been used/, "notify { [default]:; default:}" => /The title 'default' has already been used/) end context "type names" do produces( "notify { testing: }" => "defined(Notify[testing])", "$a = notify; $a { testing: }" => "defined(Notify[testing])", "'notify' { testing: }" => "defined(Notify[testing])", "sprintf('%s', 'notify') { testing: }" => "defined(Notify[testing])", "$a = ify; \"not$a\" { testing: }" => "defined(Notify[testing])", "Notify { testing: }" => "defined(Notify[testing])", "Resource[Notify] { testing: }" => "defined(Notify[testing])", "'Notify' { testing: }" => "defined(Notify[testing])", "class a { notify { testing: } } class { a: }" => "defined(Notify[testing])", "class a { notify { testing: } } Class { a: }" => "defined(Notify[testing])", "class a { notify { testing: } } 'class' { a: }" => "defined(Notify[testing])", "define a::b { notify { testing: } } a::b { title: }" => "defined(Notify[testing])", "define a::b { notify { testing: } } A::B { title: }" => "defined(Notify[testing])", "define a::b { notify { testing: } } 'a::b' { title: }" => "defined(Notify[testing])", "define a::b { notify { testing: } } Resource['a::b'] { title: }" => "defined(Notify[testing])") fails( "'' { testing: }" => /Illegal type reference/, "1 { testing: }" => /Illegal Resource Type expression.*got Integer/, "3.0 { testing: }" => /Illegal Resource Type expression.*got Float/, "true { testing: }" => /Illegal Resource Type expression.*got Boolean/, "'not correct' { testing: }" => /Illegal type reference/, "Notify[hi] { testing: }" => /Illegal Resource Type expression.*got Notify\['hi'\]/, "[Notify, File] { testing: }" => /Illegal Resource Type expression.*got Array\[Type\[Resource\]\]/, "Does::Not::Exist { title: }" => /Invalid resource type does::not::exist/) end context "local defaults" do produces( "notify { example:; default: message => defaulted }" => "Notify[example][message] == 'defaulted'", "notify { example: message => specific; default: message => defaulted }" => "Notify[example][message] == 'specific'", "notify { example: message => undef; default: message => defaulted }" => "Notify[example][message] == undef", "notify { [example, other]: ; default: message => defaulted }" => "Notify[example][message] == 'defaulted' and Notify[other][message] == 'defaulted'", "notify { [example, default]: message => set; other: }" => "Notify[example][message] == 'set' and Notify[other][message] == 'set'") end context "order of evaluation" do fails("notify { hi: message => value; bye: message => Notify[hi][message] }" => /Resource not found: Notify\['hi'\]/) produces("notify { hi: message => (notify { param: message => set }); bye: message => Notify[param][message] }" => "defined(Notify[hi]) and Notify[bye][message] == 'set'") fails("notify { bye: message => Notify[param][message]; hi: message => (notify { param: message => set }) }" => /Resource not found: Notify\['param'\]/) end context "parameters" do produces( - "notify { title: message => set }" => "Notify[title][message] == 'set'", - "$x = set notify { title: message => $x }" => "Notify[title][message] == 'set'", + "notify { title: message => set }" => "Notify[title][message] == 'set'", + "$x = set notify { title: message => $x }" => "Notify[title][message] == 'set'", - "notify { title: *=> { message => set } }" => "Notify[title][message] == 'set'", - "$x = { message => set } notify { title: * => $x }" => "Notify[title][message] == 'set'") + "notify { title: *=> { message => set } }" => "Notify[title][message] == 'set'", + + "$x = { message => set } notify { title: * => $x }" => "Notify[title][message] == 'set'", + + "$x = { owner => the_x } + $y = { mode => '0666' } + $t = '/tmp/x' + file { $t: + path => '/somewhere', + * => $x, + * => $y }" => "File[$t][mode] == '0666' and File[$t][owner] == 'the_x' and File[$t][path] == '/somewhere'") fails( "notify { title: unknown => value }" => /Invalid parameter unknown/, #BUG "notify { title: * => { hash => value }, message => oops }" => /Invalid parameter hash/, # this really needs to be a better error message. - "notify { title: message => oops, * => { hash => value } }" => /Syntax error/, # should this be a better error message? - - "notify { title: * => { unknown => value } }" => /Invalid parameter unknown/) + "notify { title: message => oops, * => { hash => value } }" => /Invalid parameter hash/, # should this be a better error message? + + "notify { title: * => { unknown => value } }" => /Invalid parameter unknown/, + "$x = { owner => the_x } + $y = { owner => the_y } + $t = '/tmp/x' + file { $t: + * => $x, + * => $y }" => /The attribute 'owner' has already been set/) end context "virtual" do produces( - "@notify { example: }" => "!defined(Notify[example])", - "@notify { example: } realize(Notify[example])" => "defined(Notify[example])", - "@notify { virtual: message => set } notify { real: message => Notify[virtual][message] }" => "Notify[real][message] == 'set'") + "@notify { example: }" => "!defined(Notify[example])", + + "@notify { example: } + realize(Notify[example])" => "defined(Notify[example])", + + "@notify { virtual: message => set } + notify { real: + message => Notify[virtual][message] }" => "Notify[real][message] == 'set'") end context "exported" do produces( "@@notify { example: }" => "!defined(Notify[example])", "@@notify { example: } realize(Notify[example])" => "defined(Notify[example])", "@@notify { exported: message => set } notify { real: message => Notify[exported][message] }" => "Notify[real][message] == 'set'") end end describe "current parser" do before :each do Puppet[:parser] = 'current' end produces( "notify { thing: }" => ["Notify[thing]"], "$x = thing notify { $x: }" => ["Notify[thing]"], "notify { [thing]: }" => ["Notify[thing]"], "$x = [thing] notify { $x: }" => ["Notify[thing]"], "notify { [[nested, array]]: }" => ["Notify[nested]", "Notify[array]"], "$x = [[nested, array]] notify { $x: }" => ["Notify[nested]", "Notify[array]"], # deprecate? "notify { 1: }" => ["Notify[1]"], "$x = 1 notify { $x: }" => ["Notify[1]"], # deprecate? "notify { [1]: }" => ["Notify[1]"], "$x = [1] notify { $x: }" => ["Notify[1]"], # deprecate? "notify { 3.0: }" => ["Notify[3.0]"], "$x = 3.0 notify { $x: }" => ["Notify[3.0]"], # deprecate? "notify { [3.0]: }" => ["Notify[3.0]"], "$x = [3.0] notify { $x: }" => ["Notify[3.0]"]) # :( fails( "notify { true: }" => /Syntax error/) produces("$x = true notify { $x: }" => ["Notify[true]"]) # this makes no sense given the [false] case produces( "notify { [true]: }" => ["Notify[true]"], "$x = [true] notify { $x: }" => ["Notify[true]"]) # *sigh* fails( "notify { false: }" => /Syntax error/, "$x = false notify { $x: }" => /No title provided and :notify is not a valid resource reference/, "notify { [false]: }" => /No title provided and :notify is not a valid resource reference/, "$x = [false] notify { $x: }" => /No title provided and :notify is not a valid resource reference/) # works for variable value, not for literal. deprecate? fails("notify { undef: }" => /Syntax error/) produces( "$x = undef notify { $x: }" => ["Notify[undef]"], # deprecate? "notify { [undef]: }" => ["Notify[undef]"], "$x = [undef] notify { $x: }" => ["Notify[undef]"]) fails("notify { {nested => hash}: }" => /Syntax error/) #produces("$x = {nested => hash} notify { $x: }" => ["Notify[{nested => hash}]"]) #it is created, but isn't possible to reference the resource. deprecate? #produces("notify { [{nested => hash}]: }" => ["Notify[{nested => hash}]"]) #it is created, but isn't possible to reference the resource. deprecate? #produces("$x = [{nested => hash}] notify { $x: }" => ["Notify[{nested => hash}]"]) #it is created, but isn't possible to reference the resource. deprecate? fails( "notify { /regexp/: }" => /Syntax error/, "$x = /regexp/ notify { $x: }" => /Syntax error/, "notify { [/regexp/]: }" => /Syntax error/, "$x = [/regexp/] notify { $x: }" => /Syntax error/, "notify { default: }" => /Syntax error/, "$x = default notify { $x: }" => /Syntax error/, "notify { [default]: }" => /Syntax error/, "$x = [default] notify { $x: }" => /Syntax error/) end end