diff --git a/lib/puppet/loaders.rb b/lib/puppet/loaders.rb index 1880fabb2..e85b5e3fc 100644 --- a/lib/puppet/loaders.rb +++ b/lib/puppet/loaders.rb @@ -1,21 +1,20 @@ module Puppet module Pops require 'puppet/pops/loaders' module Loader require 'puppet/pops/loader/loader' require 'puppet/pops/loader/base_loader' require 'puppet/pops/loader/gem_support' require 'puppet/pops/loader/module_loaders' require 'puppet/pops/loader/dependency_loader' require 'puppet/pops/loader/null_loader' require 'puppet/pops/loader/static_loader' - require 'puppet/pops/loader/puppet_function_instantiator' require 'puppet/pops/loader/ruby_function_instantiator' require 'puppet/pops/loader/ruby_legacy_function_instantiator' require 'puppet/pops/loader/loader_paths' require 'puppet/pops/loader/simple_environment_loader' end end -end \ No newline at end of file +end diff --git a/lib/puppet/parser/ast/pops_bridge.rb b/lib/puppet/parser/ast/pops_bridge.rb index 740e8ecf9..77d06da9d 100644 --- a/lib/puppet/parser/ast/pops_bridge.rb +++ b/lib/puppet/parser/ast/pops_bridge.rb @@ -1,213 +1,209 @@ require 'puppet/parser/ast/top_level_construct' require 'puppet/pops' # The AST::Bridge contains classes that bridges between the new Pops based model # and the 3.x AST. This is required to be able to reuse the Puppet::Resource::Type which is # fundamental for the rest of the logic. # class Puppet::Parser::AST::PopsBridge # Bridges to one Pops Model Expression # The @value is the expression # This is used to represent the body of a class, definition, or node, and for each parameter's default value # expression. # class Expression < Puppet::Parser::AST::Leaf def initialize args super @@evaluator ||= Puppet::Pops::Parser::EvaluatingParser::Transitional.new() end def to_s Puppet::Pops::Model::ModelTreeDumper.new.dump(@value) end def evaluate(scope) @@evaluator.evaluate(scope, @value) end # Adapts to 3x where top level constructs needs to have each to iterate over children. Short circuit this # by yielding self. By adding this there is no need to wrap a pops expression inside an AST::BlockExpression # def each yield self end def sequence_with(other) if value.nil? # This happens when testing and not having a complete setup other else # When does this happen ? Ever ? raise "sequence_with called on Puppet::Parser::AST::PopsBridge::Expression - please report use case" # What should be done if the above happens (We don't want this to happen). # Puppet::Parser::AST::BlockExpression.new(:children => [self] + other.children) end end # The 3x requires code plugged in to an AST to have this in certain positions in the tree. The purpose # is to either print the content, or to look for things that needs to be defined. This implementation # cheats by always returning an empty array. (This allows simple files to not require a "Program" at the top. # def children [] end end class NilAsUndefExpression < Expression def evaluate(scope) result = super result.nil? ? :undef : result end end # Bridges the top level "Program" produced by the pops parser. # Its main purpose is to give one point where all definitions are instantiated (actually defined since the # Puppet 3x terminology is somewhat misleading - the definitions are instantiated, but instances of the created types # are not created, that happens when classes are included / required, nodes are matched and when resources are instantiated # by a resource expression (which is also used to instantiate a host class). # class Program < Puppet::Parser::AST::TopLevelConstruct attr_reader :program_model, :context def initialize(program_model, context = {}) @program_model = program_model @context = context @ast_transformer ||= Puppet::Pops::Model::AstTransformer.new(@context[:file]) @@evaluator ||= Puppet::Pops::Parser::EvaluatingParser::Transitional.new() end # This is the 3x API, the 3x AST searches through all code to find the instructions that can be instantiated. # This Pops-model based instantiation relies on the parser to build this list while parsing (which is more # efficient as it avoids one full scan of all logic via recursive enumeration/yield) # def instantiate(modname) @program_model.definitions.collect do |d| case d when Puppet::Pops::Model::HostClassDefinition instantiate_HostClassDefinition(d, modname) when Puppet::Pops::Model::ResourceTypeDefinition instantiate_ResourceTypeDefinition(d, modname) when Puppet::Pops::Model::NodeDefinition instantiate_NodeDefinition(d, modname) - when Puppet::Pops::Model::FunctionDefinition - instantiate_FunctionDefinition(d, modname) - # The 3x logic calling this will not know what to do with the result, it is compacted away at the end - next else raise Puppet::ParseError, "Internal Error: Unknown type of definition - got '#{d.class}'" end end.flatten().compact() # flatten since node definition may have returned an array # Compact since functions are not understood by compiler end def evaluate(scope) @@evaluator.evaluate(scope, program_model) end # Adapts to 3x where top level constructs needs to have each to iterate over children. Short circuit this # by yielding self. This means that the HostClass container will call this bridge instance with `instantiate`. # def each yield self end private def instantiate_Parameter(o) # 3x needs parameters as an array of `[name]` or `[name, value_expr]` # One problem is that the parameter evaluation takes place in the wrong context in 3x (the caller's and # can thus reference all sorts of information. Here the value expression is wrapped in an AST Bridge to a Pops # expression since the Pops side can not control the evaluation if o.value [ o.name, NilAsUndefExpression.new(:value => o.value) ] else [ o.name ] end end # Produces a hash with data for Definition and HostClass def args_from_definition(o, modname) args = { :arguments => o.parameters.collect {|p| instantiate_Parameter(p) }, :module_name => modname } unless is_nop?(o.body) args[:code] = Expression.new(:value => o.body) end @ast_transformer.merge_location(args, o) end def instantiate_HostClassDefinition(o, modname) args = args_from_definition(o, modname) args[:parent] = o.parent_class Puppet::Resource::Type.new(:hostclass, o.name, @context.merge(args)) end def instantiate_ResourceTypeDefinition(o, modname) Puppet::Resource::Type.new(:definition, o.name, @context.merge(args_from_definition(o, modname))) end def instantiate_NodeDefinition(o, modname) args = { :module_name => modname } unless is_nop?(o.body) args[:code] = Expression.new(:value => o.body) end unless is_nop?(o.parent) args[:parent] = @ast_transformer.hostname(o.parent) end host_matches = @ast_transformer.hostname(o.host_matches) @ast_transformer.merge_location(args, o) host_matches.collect do |name| Puppet::Resource::Type.new(:node, name, @context.merge(args)) end end # Propagates a found Function to the appropriate loader. # This is for 4x future-evaluator/loader # def instantiate_FunctionDefinition(function_definition, modname) loaders = (Puppet.lookup(:loaders) { nil }) unless loaders raise Puppet::ParseError, "Internal Error: Puppet Context ':loaders' missing - cannot define any functions" end loader = if modname.nil? || modname == "" # TODO : Later when functions can be private, a decision is needed regarding what that means. # A private environment loader could be used for logic outside of modules, then only that logic # would see the function. # # Use the private loader, this function may see the environment's dependencies (currently, all modules) loaders.private_environment_loader() else # TODO : Later check if function is private, and then add it to # private_loader_for_module # loaders.public_loader_for_module(modname) end unless loader raise Puppet::ParseError, "Internal Error: did not find public loader for module: '#{modname}'" end # Instantiate Function, and store it in the environment loader typed_name, f = Puppet::Pops::Loader::PuppetFunctionInstantiator.create_from_model(function_definition, loader) loader.set_entry(typed_name, f, Puppet::Pops::Adapters::SourcePosAdapter.adapt(function_definition).to_uri) nil # do not want the function to inadvertently leak into 3x end def code() Expression.new(:value => @value) end def is_nop?(o) @ast_transformer.is_nop?(o) end end end diff --git a/lib/puppet/pops/loader/loader_paths.rb b/lib/puppet/pops/loader/loader_paths.rb index fed0eecf7..a431a4801 100644 --- a/lib/puppet/pops/loader/loader_paths.rb +++ b/lib/puppet/pops/loader/loader_paths.rb @@ -1,165 +1,137 @@ # LoaderPaths # === # The central loader knowledge about paths, what they represent and how to instantiate from them. # Contains helpers (*smart paths*) to deal with lazy resolution of paths. # # TODO: Currently only supports loading of functions (3 kinds) # module Puppet::Pops::Loader::LoaderPaths # Returns an array of SmartPath, each instantiated with a reference to the given loader (for root path resolution # and existence checks). The smart paths in the array appear in precedence order. The returned array may be # mutated. # def self.relative_paths_for_type(type, loader) #, start_index_in_name) result = case type # typed_name.type when :function if Puppet[:biff] == true - [FunctionPath4x.new(loader), FunctionPath3x.new(loader), FunctionPathPP.new(loader)] + [FunctionPath4x.new(loader), FunctionPath3x.new(loader)] else - [FunctionPath4x.new(loader), FunctionPathPP.new(loader)] + [FunctionPath4x.new(loader)] end # when :xxx # TODO: Add all other types else # unknown types, simply produce an empty result; no paths to check, nothing to find... move along... [] end result end # # DO NOT REMOVE YET. needed later? when there is the need to decamel a classname # def de_camel(fq_name) # fq_name.to_s.gsub(/::/, '/'). # gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). # gsub(/([a-z\d])([A-Z])/,'\1_\2'). # tr("-", "_"). # downcase # end class SmartPath # Generic path, in the sense of "if there are any entities of this kind to load, where are they?" attr_reader :generic_path # Creates SmartPath for the given loader (loader knows how to check for existence etc.) def initialize(loader) @loader = loader end def generic_path() return @generic_path unless @generic_path.nil? root_path = @loader.path @generic_path = (root_path.nil? ? relative_path : File.join(root_path, relative_path)) end # Effective path is the generic path + the name part(s) + extension. # def effective_path(typed_name, start_index_in_name) -# "#{File.join(generic_path, typed_name.name_parts[ start_index_in_name..-1 ])}#{extension}" "#{File.join(generic_path, typed_name.name_parts)}#{extension}" end def relative_path() raise NotImplementedError.new end def instantiator() raise NotImplementedError.new end end class RubySmartPath < SmartPath def extension ".rb" end # Duplication of extension information, but avoids one call def effective_path(typed_name, start_index_in_name) -# "#{File.join(generic_path, typed_name.name_parts[ start_index_in_name..-1 ])}.rb" "#{File.join(generic_path, typed_name.name_parts)}.rb" end end - class PuppetSmartPath < SmartPath - def extension - ".pp" - end - - # Duplication of extension information, but avoids one call - def effective_path(typed_name, start_index_in_name) - # Puppet name to path always skips the name-space as that is part of the generic path - # i.e. /mumodule/functions/foo.pp is the function mymodule::foo - "#{File.join(generic_path, typed_name.name_parts[ 1..-1 ])}.pp" -# "#{File.join(generic_path, typed_name.name_parts)}.pp" - end - end - class FunctionPath4x < RubySmartPath FUNCTION_PATH_4X = File.join('lib', 'puppet', 'functions') def relative_path FUNCTION_PATH_4X end def instantiator() Puppet::Pops::Loader::RubyFunctionInstantiator end end class FunctionPath3x < RubySmartPath FUNCTION_PATH_3X = File.join('lib', 'puppet', 'parser', 'functions') def relative_path FUNCTION_PATH_3X end def instantiator() Puppet::Pops::Loader::RubyLegacyFunctionInstantiator end end - class FunctionPathPP < PuppetSmartPath - FUNCTION_PATH_PP = 'functions' - - def relative_path - FUNCTION_PATH_PP - end - - def instantiator() - Puppet::Pops::Loader::PuppetFunctionInstantiator - end - end - # SmartPaths # === # Holds effective SmartPath instances per type # class SmartPaths def initialize(path_based_loader) @loader = path_based_loader @smart_paths = {} end # Ensures that the paths for the type have been probed and pruned to what is existing relative to # the given root. # # @param type [Symbol] the entity type to load # @return [Array] array of effective paths for type (may be empty) # def effective_paths(type) smart_paths = @smart_paths loader = @loader unless effective_paths = smart_paths[type] # type not yet processed, does the various directories for the type exist ? # Get the relative dirs for the type paths_for_type = Puppet::Pops::Loader::LoaderPaths.relative_paths_for_type(type, loader) # Check which directories exist in the loader's content/index effective_paths = smart_paths[type] = paths_for_type.select { |sp| loader.meaningful_to_search?(sp) } end effective_paths end end end diff --git a/lib/puppet/pops/loader/puppet_function_instantiator.rb b/lib/puppet/pops/loader/puppet_function_instantiator.rb deleted file mode 100644 index b39477f52..000000000 --- a/lib/puppet/pops/loader/puppet_function_instantiator.rb +++ /dev/null @@ -1,113 +0,0 @@ -# The PuppetFunctionInstantiator instantiates a Puppet::Functions::Function given a Puppet Programming language -# source that when called evaluates the Puppet logic it contains. -# -class Puppet::Pops::Loader::PuppetFunctionInstantiator - # Produces an instance of the Function class with the given typed_name, or fails with an error if the - # given puppet source does not produce this instance when evaluated. - # - # @param loader [Puppet::Pops::Loader::Loader] The loader the function is associated with - # @param typed_name [Puppet::Pops::Loader::TypedName] the type / name of the function to load - # @param source_ref [URI, String] a reference to the source / origin of the puppet code to evaluate - # @param pp_code_string [String] puppet code in a string - # - # @return [Puppet::Pops::Functions.Function] - an instantiated function with global scope closure associated with the given loader - # - def self.create(loader, typed_name, source_ref, pp_code_string) - parser = Puppet::Pops::Parser::EvaluatingParser::Transitional.new() - - # parse and validate - result = parser.parse_string(pp_code_string, source_ref) - # Only one function is allowed (and no other definitions) - case result.model.definitions.size - when 0 - raise ArgumentError, "The code loaded from #{source_ref} does not define the function #{typed_name.name} - it is empty." - when 1 - # ok - else - raise ArgumentError, "The code loaded from #{source_ref} must contain only the function #{typed_name.name} - it has additional definitions." - end - the_function_definition = result.model.definitions[0] - - unless the_function_definition.is_a?(Puppet::Pops::Model::FunctionDefinition) - raise ArgumentError, "The code loaded from #{source_ref} does not define the function #{typed_name.name} - no function found." - end - unless the_function_definition.name == typed_name.name - expected = typed_name.name - actual = the_function_definition.name - raise ArgumentError, "The code loaded from #{source_ref} produced function with the wrong name, expected #{expected}, actual #{actual}" - end - unless result.model().body == the_function_definition - raise ArgumentError, "The code loaded from #{source_ref} contains additional logic - can only contain the function #{typed_name.name}" - end - - # Adapt the function definition with loader - this is used from logic contained in it body to find the - # loader to use when making calls to the new function API. Such logic have a hard time finding the closure (where - # the loader is known - hence this mechanism - Puppet::Pops::Adapters::LoaderAdapter.adapt(the_function_definition).loader = loader - - # TODO: Cheating wrt. scope - assuming it is found in the context - closure_scope = Puppet.lookup(:global_scope) { {} } - - created = create_function_class(the_function_definition, closure_scope) - # create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things - # when calling functions etc. - # It should be bound to global scope - - created.new(closure_scope, loader) - end - - # Creates Function class and instantiates it based on a FunctionDefinition model - # @return [Array] - array of - # typed name, and an instantiated function with global scope closure associated with the given loader - # - def self.create_from_model(function_definition, loader) - closure_scope = Puppet.lookup(:global_scope) { {} } - created = create_function_class(function_definition, closure_scope) - typed_name = Puppet::Pops::Loader::Loader::TypedName.new(:function, function_definition.name) - [typed_name, created.new(closure_scope, loader)] - end - - def self.create_function_class(function_definition, closure_scope) - method_name = :"#{function_definition.name.split(/::/).slice(-1)}" - closure = Puppet::Pops::Evaluator::Closure.new( - Puppet::Pops::Evaluator::EvaluatorImpl.new(), - function_definition, - closure_scope) - required_optional = function_definition.parameters.reduce([0, 0]) do |memo, p| - if p.value.nil? - memo[0] += 1 - else - memo[1] += 1 - end - memo - end - min_arg_count = required_optional[0] - max_arg_count = required_optional[0] + required_optional[1] - - # Create a 4x function wrapper around the Puppet Function - created_function_class = Puppet::Functions.create_function(function_definition.name) do - # Define the method that is called from dispatch - this method just changes a call - # with multiple unknown arguments to passing all in an array (since this is expected in the closure API. - # - # TODO: The closure will call the evaluator.call method which will again match args with parameters. - # This can be done a better way later - unifying the two concepts - a function instance is really the same - # as the current evaluator closure for lambdas, only that it also binds an evaluator. This could perhaps - # be a specialization of Function... with a special dispatch - # - define_method(:__relay__call__) do |*args| - closure.call(nil, *args) - end - - # Define a dispatch that performs argument type/count checking - # - dispatch :__relay__call__ do - # Use Puppet Type Object (not Optional[Object] since the 3x API passes undef as empty string). - param(optional(object), 'args') - # Specify arg count (transformed from FunctionDefinition.parameters, no types, or varargs yet) - arg_count(min_arg_count, max_arg_count) - end - end - created_function_class - - end -end \ No newline at end of file diff --git a/lib/puppet/pops/loader/ruby_function_instantiator.rb b/lib/puppet/pops/loader/ruby_function_instantiator.rb index 0b66ac126..d298eec2e 100644 --- a/lib/puppet/pops/loader/ruby_function_instantiator.rb +++ b/lib/puppet/pops/loader/ruby_function_instantiator.rb @@ -1,34 +1,34 @@ # The RubyFunctionInstantiator instantiates a Puppet::Functions::Function given the ruby source # that calls Puppet::Functions.create_function. # class Puppet::Pops::Loader::RubyFunctionInstantiator # Produces an instance of the Function class with the given typed_name, or fails with an error if the # given ruby source does not produce this instance when evaluated. # # @param loader [Puppet::Pops::Loader::Loader] The loader the function is associated with # @param typed_name [Puppet::Pops::Loader::TypedName] the type / name of the function to load # @param source_ref [URI, String] a reference to the source / origin of the ruby code to evaluate # @param ruby_code_string [String] ruby code in a string # # @return [Puppet::Pops::Functions.Function] - an instantiated function with global scope closure associated with the given loader # def self.create(loader, typed_name, source_ref, ruby_code_string) unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet\:\:Functions\.create_function/ raise ArgumentError, "The code loaded from #{source_ref} does not seem to be a Puppet 4x API function - no create_function call." end created = eval(ruby_code_string) unless created.is_a?(Class) raise ArgumentError, "The code loaded from #{source_ref} did not produce a Function class when evaluated. Got '#{created.class}'" end unless created.name.to_s == typed_name.name() raise ArgumentError, "The code loaded from #{source_ref} produced mis-matched name, expected '#{typed_name.name}', got #{created.name}" end # create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things # when calling functions etc. # It should be bound to global scope # TODO: Cheating wrt. scope - assuming it is found in the context closure_scope = Puppet.lookup(:global_scope) { {} } created.new(closure_scope, loader) end -end \ No newline at end of file +end diff --git a/lib/puppet/pops/model/factory.rb b/lib/puppet/pops/model/factory.rb index 5f2b6c2d4..c97fb5051 100644 --- a/lib/puppet/pops/model/factory.rb +++ b/lib/puppet/pops/model/factory.rb @@ -1,981 +1,977 @@ # Factory is a helper class that makes construction of a Pops Model # much more convenient. It can be viewed as a small internal DSL for model # constructions. # For usage see tests using the factory. # # @todo All those uppercase methods ... they look bad in one way, but stand out nicely in the grammar... # decide if they should change into lower case names (some of the are lower case)... # class Puppet::Pops::Model::Factory Model = Puppet::Pops::Model attr_accessor :current alias_method :model, :current # Shared build_visitor, since there are many instances of Factory being used @@build_visitor = Puppet::Pops::Visitor.new(self, "build") @@interpolation_visitor = Puppet::Pops::Visitor.new(self, "interpolate") # Initialize a factory with a single object, or a class with arguments applied to build of # created instance # def initialize o, *args @current = case o when Model::PopsObject o when Puppet::Pops::Model::Factory o.current else build(o, *args) end end # Polymorphic build def build(o, *args) begin @@build_visitor.visit_this(self, o, *args) rescue =>e # debug here when in trouble... raise e end end # Polymorphic interpolate def interpolate() begin @@interpolation_visitor.visit_this_0(self, current) rescue =>e # debug here when in trouble... raise e end end # Building of Model classes def build_ArithmeticExpression(o, op, a, b) o.operator = op build_BinaryExpression(o, a, b) end def build_AssignmentExpression(o, op, a, b) o.operator = op build_BinaryExpression(o, a, b) end def build_AttributeOperation(o, name, op, value) o.operator = op o.attribute_name = name.to_s # BOOLEAN is allowed in the grammar o.value_expr = build(value) o end def build_AccessExpression(o, left, *keys) o.left_expr = to_ops(left) keys.each {|expr| o.addKeys(to_ops(expr)) } o end def build_BinaryExpression(o, left, right) o.left_expr = to_ops(left) o.right_expr = to_ops(right) o end def build_BlockExpression(o, *args) args.each {|expr| o.addStatements(to_ops(expr)) } o end def build_CollectExpression(o, type_expr, query_expr, attribute_operations) o.type_expr = to_ops(type_expr) o.query = build(query_expr) attribute_operations.each {|op| o.addOperations(build(op)) } o end def build_ComparisonExpression(o, op, a, b) o.operator = op build_BinaryExpression(o, a, b) end def build_ConcatenatedString(o, *args) args.each {|expr| o.addSegments(build(expr)) } o end def build_CreateTypeExpression(o, name, super_name = nil) o.name = name o.super_name = super_name o end def build_CreateEnumExpression(o, *args) o.name = args.slice(0) if args.size == 2 o.values = build(args.last) o end def build_CreateAttributeExpression(o, name, datatype_expr) o.name = name o.type = to_ops(datatype_expr) o end def build_HeredocExpression(o, name, expr) o.syntax = name o.text_expr = build(expr) o end # @param name [String] a valid classname # @param parameters [Array] may be empty # @param parent_class_name [String, nil] a valid classname referencing a parent class, optional. # @param body [Array, Expression, nil] expression that constitute the body # @return [Model::HostClassDefinition] configured from the parameters # def build_HostClassDefinition(o, name, parameters, parent_class_name, body) build_NamedDefinition(o, name, parameters, body) o.parent_class = parent_class_name if parent_class_name o end def build_ResourceOverrideExpression(o, resources, attribute_operations) o.resources = build(resources) attribute_operations.each {|ao| o.addOperations(build(ao)) } o end def build_KeyedEntry(o, k, v) o.key = to_ops(k) o.value = to_ops(v) o end def build_LiteralHash(o, *keyed_entries) keyed_entries.each {|entry| o.addEntries build(entry) } o end def build_LiteralList(o, *values) values.each {|v| o.addValues build(v) } o end def build_LiteralFloat(o, val) o.value = val o end def build_LiteralInteger(o, val, radix) o.value = val o.radix = radix o end def build_IfExpression(o, t, ift, els) o.test = build(t) o.then_expr = build(ift) o.else_expr= build(els) o end def build_MatchExpression(o, op, a, b) o.operator = op build_BinaryExpression(o, a, b) end # Builds body :) from different kinds of input # @overload f_build_body(nothing) # @param nothing [nil] unchanged, produces nil # @overload f_build_body(array) # @param array [Array] turns into a BlockExpression # @overload f_build_body(expr) # @param expr [Expression] produces the given expression # @overload f_build_body(obj) # @param obj [Object] produces the result of calling #build with body as argument def f_build_body(body) case body when NilClass nil when Array Puppet::Pops::Model::Factory.new(Model::BlockExpression, *body) else build(body) end end def build_LambdaExpression(o, parameters, body) parameters.each {|p| o.addParameters(build(p)) } b = f_build_body(body) o.body = to_ops(b) if b o end def build_NamedDefinition(o, name, parameters, body) parameters.each {|p| o.addParameters(build(p)) } b = f_build_body(body) o.body = b.current if b o.name = name o end # @param o [Model::NodeDefinition] # @param hosts [Array] host matches # @param parent [Expression] parent node matcher # @param body [Object] see {#f_build_body} def build_NodeDefinition(o, hosts, parent, body) hosts.each {|h| o.addHost_matches(build(h)) } o.parent = build(parent) if parent # no nop here b = f_build_body(body) o.body = b.current if b o end def build_Parameter(o, name, expr) o.name = name o.value = build(expr) if expr # don't build a nil/nop o end def build_QualifiedReference(o, name) o.value = name.to_s.downcase o end def build_RelationshipExpression(o, op, a, b) o.operator = op build_BinaryExpression(o, a, b) end def build_ResourceExpression(o, type_name, bodies) o.type_name = build(type_name) bodies.each {|b| o.addBodies(build(b)) } o end def build_RenderStringExpression(o, string) o.value = string; o end def build_ResourceBody(o, title_expression, attribute_operations) o.title = build(title_expression) attribute_operations.each {|ao| o.addOperations(build(ao)) } o end def build_ResourceDefaultsExpression(o, type_ref, attribute_operations) o.type_ref = build(type_ref) attribute_operations.each {|ao| o.addOperations(build(ao)) } o end def build_SelectorExpression(o, left, *selectors) o.left_expr = to_ops(left) selectors.each {|s| o.addSelectors(build(s)) } o end # Builds a SubLocatedExpression - this wraps the expression in a sublocation configured # from the given token # A SubLocated holds its own locator that is used for subexpressions holding positions relative # to what it describes. # def build_SubLocatedExpression(o, token, expression) o.expr = build(expression) o.offset = token.offset o.length = token.length locator = token.locator o.locator = locator o.leading_line_count = locator.leading_line_count o.leading_line_offset = locator.leading_line_offset # Index is held in sublocator's parent locator - needed to be able to reconstruct o.line_offsets = locator.locator.line_index o end def build_SelectorEntry(o, matching, value) o.matching_expr = build(matching) o.value_expr = build(value) o end def build_QueryExpression(o, expr) ops = to_ops(expr) o.expr = ops unless Puppet::Pops::Model::Factory.nop? ops o end def build_UnaryExpression(o, expr) ops = to_ops(expr) o.expr = ops unless Puppet::Pops::Model::Factory.nop? ops o end def build_Program(o, body, definitions, locator) o.body = to_ops(body) # non containment definitions.each { |d| o.addDefinitions(d) } o.source_ref = locator.file o.source_text = locator.string o.line_offsets = locator.line_index o.locator = locator o end def build_QualifiedName(o, name) o.value = name.to_s o end # Puppet::Pops::Model::Factory helpers def f_build_unary(klazz, expr) Puppet::Pops::Model::Factory.new(build(klazz.new, expr)) end def f_build_binary_op(klazz, op, left, right) Puppet::Pops::Model::Factory.new(build(klazz.new, op, left, right)) end def f_build_binary(klazz, left, right) Puppet::Pops::Model::Factory.new(build(klazz.new, left, right)) end def f_build_vararg(klazz, left, *arg) Puppet::Pops::Model::Factory.new(build(klazz.new, left, *arg)) end def f_arithmetic(op, r) f_build_binary_op(Model::ArithmeticExpression, op, current, r) end def f_comparison(op, r) f_build_binary_op(Model::ComparisonExpression, op, current, r) end def f_match(op, r) f_build_binary_op(Model::MatchExpression, op, current, r) end # Operator helpers def in(r) f_build_binary(Model::InExpression, current, r); end def or(r) f_build_binary(Model::OrExpression, current, r); end def and(r) f_build_binary(Model::AndExpression, current, r); end def not(); f_build_unary(Model::NotExpression, self); end def minus(); f_build_unary(Model::UnaryMinusExpression, self); end def text(); f_build_unary(Model::TextExpression, self); end def var(); f_build_unary(Model::VariableExpression, self); end def [](*r); f_build_vararg(Model::AccessExpression, current, *r); end def dot r; f_build_binary(Model::NamedAccessExpression, current, r); end def + r; f_arithmetic(:+, r); end def - r; f_arithmetic(:-, r); end def / r; f_arithmetic(:/, r); end def * r; f_arithmetic(:*, r); end def % r; f_arithmetic(:%, r); end def << r; f_arithmetic(:<<, r); end def >> r; f_arithmetic(:>>, r); end def < r; f_comparison(:<, r); end def <= r; f_comparison(:<=, r); end def > r; f_comparison(:>, r); end def >= r; f_comparison(:>=, r); end def == r; f_comparison(:==, r); end def ne r; f_comparison(:'!=', r); end def =~ r; f_match(:'=~', r); end def mne r; f_match(:'!~', r); end def paren(); f_build_unary(Model::ParenthesizedExpression, current); end def relop op, r f_build_binary_op(Model::RelationshipExpression, op.to_sym, current, r) end def select *args Puppet::Pops::Model::Factory.new(build(Model::SelectorExpression, current, *args)) end # For CaseExpression, setting the default for an already build CaseExpression def default r current.addOptions(Puppet::Pops::Model::Factory.WHEN(:default, r).current) self end def lambda=(lambda) current.lambda = lambda.current self end # Assignment = def set(r) f_build_binary_op(Model::AssignmentExpression, :'=', current, r) end # Assignment += def plus_set(r) f_build_binary_op(Model::AssignmentExpression, :'+=', current, r) end # Assignment -= def minus_set(r) f_build_binary_op(Model::AssignmentExpression, :'-=', current, r) end def attributes(*args) args.each {|a| current.addAttributes(build(a)) } self end # Catch all delegation to current def method_missing(meth, *args, &block) if current.respond_to?(meth) current.send(meth, *args, &block) else super end end def respond_to?(meth, include_all=false) current.respond_to?(meth, include_all) || super end def self.record_position(o, start_locatable, end_locateable) new(o).record_position(start_locatable, end_locateable) end # Records the position (start -> end) and computes the resulting length. # def record_position(start_locatable, end_locatable) from = start_locatable.is_a?(Puppet::Pops::Model::Factory) ? start_locatable.current : start_locatable to = end_locatable.is_a?(Puppet::Pops::Model::Factory) ? end_locatable.current : end_locatable to = from if to.nil? || to.offset.nil? o = current # record information directly in the Model::Positioned object o.offset = from.offset o.length ||= to.offset - from.offset + to.length self end # @return [Puppet::Pops::Adapters::SourcePosAdapter] with location information def loc() Puppet::Pops::Adapters::SourcePosAdapter.adapt(current) end # Returns symbolic information about an expected share of a resource expression given the LHS of a resource expr. # # * `name { }` => `:resource`, create a resource of the given type # * `Name { }` => ':defaults`, set defaults for the referenced type # * `Name[] { }` => `:override`, overrides instances referenced by LHS # * _any other_ => ':error', all other are considered illegal # def self.resource_shape(expr) expr = expr.current if expr.is_a?(Puppet::Pops::Model::Factory) case expr when Model::QualifiedName :resource when Model::QualifiedReference :defaults when Model::AccessExpression :override when 'class' :class else :error end end # Factory starting points def self.literal(o); new(o); end def self.minus(o); new(o).minus; end def self.var(o); new(o).var; end def self.block(*args); new(Model::BlockExpression, *args); end def self.string(*args); new(Model::ConcatenatedString, *args); end def self.text(o); new(o).text; end def self.IF(test_e,then_e,else_e); new(Model::IfExpression, test_e, then_e, else_e); end def self.UNLESS(test_e,then_e,else_e); new(Model::UnlessExpression, test_e, then_e, else_e); end def self.CASE(test_e,*options); new(Model::CaseExpression, test_e, *options); end def self.WHEN(values_list, block); new(Model::CaseOption, values_list, block); end def self.MAP(match, value); new(Model::SelectorEntry, match, value); end def self.TYPE(name, super_name=nil); new(Model::CreateTypeExpression, name, super_name); end def self.ATTR(name, type_expr=nil); new(Model::CreateAttributeExpression, name, type_expr); end def self.ENUM(*args); new(Model::CreateEnumExpression, *args); end def self.KEY_ENTRY(key, val); new(Model::KeyedEntry, key, val); end def self.HASH(entries); new(Model::LiteralHash, *entries); end # TODO_HEREDOC def self.HEREDOC(name, expr); new(Model::HeredocExpression, name, expr); end def self.SUBLOCATE(token, expr) new(Model::SubLocatedExpression, token, expr); end def self.LIST(entries); new(Model::LiteralList, *entries); end def self.PARAM(name, expr=nil); new(Model::Parameter, name, expr); end def self.NODE(hosts, parent, body); new(Model::NodeDefinition, hosts, parent, body); end # Creates a QualifiedName representation of o, unless o already represents a QualifiedName in which # case it is returned. # def self.fqn(o) o = o.current if o.is_a?(Puppet::Pops::Model::Factory) o = new(Model::QualifiedName, o) unless o.is_a? Model::QualifiedName o end # Creates a QualifiedName representation of o, unless o already represents a QualifiedName in which # case it is returned. # def self.fqr(o) o = o.current if o.is_a?(Puppet::Pops::Model::Factory) o = new(Model::QualifiedReference, o) unless o.is_a? Model::QualifiedReference o end def self.TEXT(expr) new(Model::TextExpression, new(expr).interpolate) end # TODO_EPP def self.RENDER_STRING(o) new(Model::RenderStringExpression, o) end def self.RENDER_EXPR(expr) new(Model::RenderExpression, expr) end def self.EPP(parameters, body) see_scope = false params = parameters if parameters.nil? params = [] see_scope = true end LAMBDA(params, new(Model::EppExpression, see_scope, body)) end # TODO: This is the same a fqn factory method, don't know if callers to fqn and QNAME can live with the # same result or not yet - refactor into one method when decided. # def self.QNAME(name) new(Model::QualifiedName, name) end def self.NUMBER(name_or_numeric) if n_radix = Puppet::Pops::Utils.to_n_with_radix(name_or_numeric) val, radix = n_radix if val.is_a?(Float) new(Model::LiteralFloat, val) else new(Model::LiteralInteger, val, radix) end else # Bad number should already have been caught by lexer - this should never happen raise ArgumentError, "Internal Error, NUMBER token does not contain a valid number, #{name_or_numeric}" end end # Convert input string to either a qualified name, a LiteralInteger with radix, or a LiteralFloat # def self.QNAME_OR_NUMBER(name) if n_radix = Puppet::Pops::Utils.to_n_with_radix(name) val, radix = n_radix if val.is_a?(Float) new(Model::LiteralFloat, val) else new(Model::LiteralInteger, val, radix) end else new(Model::QualifiedName, name) end end def self.QREF(name) new(Model::QualifiedReference, name) end def self.VIRTUAL_QUERY(query_expr) new(Model::VirtualQuery, query_expr) end def self.EXPORTED_QUERY(query_expr) new(Model::ExportedQuery, query_expr) end def self.ATTRIBUTE_OP(name, op, expr) new(Model::AttributeOperation, name, op, expr) end def self.CALL_NAMED(name, rval_required, argument_list) unless name.kind_of?(Model::PopsObject) name = Puppet::Pops::Model::Factory.fqn(name) unless name.is_a?(Puppet::Pops::Model::Factory) end new(Model::CallNamedFunctionExpression, name, rval_required, *argument_list) end def self.CALL_METHOD(functor, argument_list) new(Model::CallMethodExpression, functor, true, nil, *argument_list) end def self.COLLECT(type_expr, query_expr, attribute_operations) new(Model::CollectExpression, type_expr, query_expr, attribute_operations) end def self.NAMED_ACCESS(type_name, bodies) new(Model::NamedAccessExpression, type_name, bodies) end def self.RESOURCE(type_name, bodies) new(Model::ResourceExpression, type_name, bodies) end def self.RESOURCE_DEFAULTS(type_name, attribute_operations) new(Model::ResourceDefaultsExpression, type_name, attribute_operations) end def self.RESOURCE_OVERRIDE(resource_ref, attribute_operations) new(Model::ResourceOverrideExpression, resource_ref, attribute_operations) end def self.RESOURCE_BODY(resource_title, attribute_operations) new(Model::ResourceBody, resource_title, attribute_operations) end def self.PROGRAM(body, definitions, locator) new(Model::Program, body, definitions, locator) end # Builds a BlockExpression if args size > 1, else the single expression/value in args def self.block_or_expression(*args) if args.size > 1 new(Model::BlockExpression, *args) else new(args[0]) end end def self.HOSTCLASS(name, parameters, parent, body) new(Model::HostClassDefinition, name, parameters, parent, body) end def self.DEFINITION(name, parameters, body) new(Model::ResourceTypeDefinition, name, parameters, body) end - def self.FUNCTION(name, parameters, body) - new(Model::FunctionDefinition, name, parameters, body) - end - def self.LAMBDA(parameters, body) new(Model::LambdaExpression, parameters, body) end def self.nop? o o.nil? || o.is_a?(Puppet::Pops::Model::Nop) end - STATEMENT_CALLS = { - 'require' => true, - 'realize' => true, + STATEMENT_CALLS = { + 'require' => true, + 'realize' => true, 'include' => true, 'contain' => true, 'debug' => true, 'info' => true, 'notice' => true, 'warning' => true, 'error' => true, 'fail' => true, } # Returns true if the given name is a "statement keyword" (require, include, contain, # error, notice, info, debug # def name_is_statement(name) STATEMENT_CALLS[name] end # Transforms an array of expressions containing literal name expressions to calls if followed by an # expression, or expression list. # def self.transform_calls(expressions) expressions.reduce([]) do |memo, expr| expr = expr.current if expr.is_a?(Puppet::Pops::Model::Factory) name = memo[-1] if name.is_a?(Model::QualifiedName) && STATEMENT_CALLS[name.value] the_call = Puppet::Pops::Model::Factory.CALL_NAMED(name, false, expr.is_a?(Array) ? expr : [expr]) # last positioned is last arg if there are several record_position(the_call, name, expr.is_a?(Array) ? expr[-1] : expr) memo[-1] = the_call if expr.is_a?(Model::CallNamedFunctionExpression) # Patch statement function call to expression style # This is needed because it is first parsed as a "statement" and the requirement changes as it becomes # an argument to the name to call transform above. expr.rval_required = true end else memo << expr if expr.is_a?(Model::CallNamedFunctionExpression) # Patch rvalue expression function call to statement style. # This is not really required but done to be AST model compliant expr.rval_required = false end end memo end end # Transforms a left expression followed by an untitled resource (in the form of attribute_operations) # @param left [Factory, Expression] the lhs followed what may be a hash def self.transform_resource_wo_title(left, attribute_ops) return nil unless attribute_ops.is_a? Array # return nil if attribute_ops.find { |ao| ao.operator == :'+>' } keyed_entries = attribute_ops.map do |ao| return nil if ao.operator == :'+>' KEY_ENTRY(ao.attribute_name, ao.value_expr) end result = block_or_expression(*transform_calls([left, HASH(keyed_entries)])) result end # Building model equivalences of Ruby objects # Allows passing regular ruby objects to the factory to produce instructions # that when evaluated produce the same thing. def build_String(o) x = Model::LiteralString.new x.value = o; x end def build_NilClass(o) x = Model::Nop.new x end def build_TrueClass(o) x = Model::LiteralBoolean.new x.value = o x end def build_FalseClass(o) x = Model::LiteralBoolean.new x.value = o x end def build_Fixnum(o) x = Model::LiteralInteger.new x.value = o; x end def build_Float(o) x = Model::LiteralFloat.new x.value = o; x end def build_Regexp(o) x = Model::LiteralRegularExpression.new x.value = o; x end def build_EppExpression(o, see_scope, body) o.see_scope = see_scope b = f_build_body(body) o.body = b.current if b o end # If building a factory, simply unwrap the model oject contained in the factory. def build_Factory(o) o.current end # Creates a String literal, unless the symbol is one of the special :undef, or :default # which instead creates a LiterlUndef, or a LiteralDefault. def build_Symbol(o) case o when :undef Model::LiteralUndef.new when :default Model::LiteralDefault.new else build_String(o.to_s) end end # Creates a LiteralList instruction from an Array, where the entries are built. def build_Array(o) x = Model::LiteralList.new o.each { |v| x.addValues(build(v)) } x end # Create a LiteralHash instruction from a hash, where keys and values are built # The hash entries are added in sorted order based on key.to_s # def build_Hash(o) x = Model::LiteralHash.new (o.sort_by {|k,v| k.to_s}).each {|k,v| x.addEntries(build(Model::KeyedEntry.new, k, v)) } x end # @param rval_required [Boolean] if the call must produce a value def build_CallExpression(o, functor, rval_required, *args) o.functor_expr = to_ops(functor) o.rval_required = rval_required args.each {|x| o.addArguments(to_ops(x)) } o end def build_CallMethodExpression(o, functor, rval_required, lambda, *args) build_CallExpression(o, functor, rval_required, *args) o.lambda = lambda o end def build_CaseExpression(o, test, *args) o.test = build(test) args.each {|opt| o.addOptions(build(opt)) } o end def build_CaseOption(o, value_list, then_expr) value_list = [value_list] unless value_list.is_a? Array value_list.each { |v| o.addValues(build(v)) } b = f_build_body(then_expr) o.then_expr = to_ops(b) if b o end # Build a Class by creating an instance of it, and then calling build on the created instance # with the given arguments def build_Class(o, *args) build(o.new(), *args) end def interpolate_Factory(o) interpolate(o.current) end def interpolate_LiteralInteger(o) # convert number to a variable self.class.new(o).var end def interpolate_Object(o) o end def interpolate_QualifiedName(o) self.class.new(o).var end # rewrite left expression to variable if it is name, number, and recurse if it is an access expression # this is for interpolation support in new lexer (${NAME}, ${NAME[}}, ${NUMBER}, ${NUMBER[]} - all # other expressions requires variables to be preceded with $ # def interpolate_AccessExpression(o) if is_interop_rewriteable?(o.left_expr) o.left_expr = to_ops(self.class.new(o.left_expr).interpolate) end o end def interpolate_NamedAccessExpression(o) if is_interop_rewriteable?(o.left_expr) o.left_expr = to_ops(self.class.new(o.left_expr).interpolate) end o end # Rewrite method calls on the form ${x.each ...} to ${$x.each} def interpolate_CallMethodExpression(o) if is_interop_rewriteable?(o.functor_expr) o.functor_expr = to_ops(self.class.new(o.functor_expr).interpolate) end o end def is_interop_rewriteable?(o) case o when Model::AccessExpression, Model::QualifiedName, Model::NamedAccessExpression, Model::CallMethodExpression true when Model::LiteralInteger # Only decimal integers can represent variables, else it is a number o.radix == 10 else false end end # Checks if the object is already a model object, or build it def to_ops(o, *args) case o when Model::PopsObject o when Puppet::Pops::Model::Factory o.current else build(o, *args) end end def self.concat(*args) new(args.map do |e| e = e.current if e.is_a?(self) case e when Model::LiteralString e.value when String e else raise ArgumentError, "can only concatenate strings, got #{e.class}" end end.join('')) end end diff --git a/lib/puppet/pops/model/model.rb b/lib/puppet/pops/model/model.rb index 5337ce264..b186aca3f 100644 --- a/lib/puppet/pops/model/model.rb +++ b/lib/puppet/pops/model/model.rb @@ -1,610 +1,606 @@ # # The Puppet Pops Metamodel # # This module contains a formal description of the Puppet Pops (*P*uppet *OP*eration instruction*S*). # It describes a Metamodel containing DSL instructions, a description of PuppetType and related # classes needed to evaluate puppet logic. # The metamodel resembles the existing AST model, but it is a semantic model of instructions and # the types that they operate on rather than an Abstract Syntax Tree, although closely related. # # The metamodel is anemic (has no behavior) except basic datatype and type # assertions and reference/containment assertions. # The metamodel is also a generalized description of the Puppet DSL to enable the # same metamodel to be used to express Puppet DSL models (instances) with different semantics as # the language evolves. # # The metamodel is concretized by a validator for a particular version of # the Puppet DSL language. # # This metamodel is expressed using RGen. # require 'rgen/metamodel_builder' module Puppet::Pops::Model extend RGen::MetamodelBuilder::ModuleExtension # A base class for modeled objects that makes them Visitable, and Adaptable. # class PopsObject < RGen::MetamodelBuilder::MMBase include Puppet::Pops::Visitable include Puppet::Pops::Adaptable include Puppet::Pops::Containment abstract end # A Positioned object has an offset measured in an opaque unit (representing characters) from the start # of a source text (starting # from 0), and a length measured in the same opaque unit. The resolution of the opaque unit requires the # aid of a Locator instance that knows about the measure. This information is stored in the model's # root node - a Program. # # The offset and length are optional if the source of the model is not from parsed text. # class Positioned < PopsObject abstract has_attr 'offset', Integer has_attr 'length', Integer end # @abstract base class for expressions class Expression < Positioned abstract end # A Nop - the "no op" expression. # @note not really needed since the evaluator can evaluate nil with the meaning of NoOp # @todo deprecate? May be useful if there is the need to differentiate between nil and Nop when transforming model. # class Nop < Expression end # A binary expression is abstract and has a left and a right expression. The order of evaluation # and semantics are determined by the concrete subclass. # class BinaryExpression < Expression abstract # # @!attribute [rw] left_expr # @return [Expression] contains_one_uni 'left_expr', Expression, :lowerBound => 1 contains_one_uni 'right_expr', Expression, :lowerBound => 1 end # An unary expression is abstract and contains one expression. The semantics are determined by # a concrete subclass. # class UnaryExpression < Expression abstract contains_one_uni 'expr', Expression, :lowerBound => 1 end # A class that simply evaluates to the contained expression. # It is of value in order to preserve user entered parentheses in transformations, and # transformations from model to source. # class ParenthesizedExpression < UnaryExpression; end # A boolean not expression, reversing the truth of the unary expr. # class NotExpression < UnaryExpression; end # An arithmetic expression reversing the polarity of the numeric unary expr. # class UnaryMinusExpression < UnaryExpression; end # An assignment expression assigns a value to the lval() of the left_expr. # class AssignmentExpression < BinaryExpression has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'=', :'+=', :'-=']), :lowerBound => 1 end # An arithmetic expression applies an arithmetic operator on left and right expressions. # class ArithmeticExpression < BinaryExpression has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'+', :'-', :'*', :'%', :'/', :'<<', :'>>' ]), :lowerBound => 1 end # A relationship expression associates the left and right expressions # class RelationshipExpression < BinaryExpression has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'->', :'<-', :'~>', :'<~']), :lowerBound => 1 end # A binary expression, that accesses the value denoted by right in left. i.e. typically # expressed concretely in a language as left[right]. # class AccessExpression < Expression contains_one_uni 'left_expr', Expression, :lowerBound => 1 contains_many_uni 'keys', Expression, :lowerBound => 1 end # A comparison expression compares left and right using a comparison operator. # class ComparisonExpression < BinaryExpression has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'==', :'!=', :'<', :'>', :'<=', :'>=' ]), :lowerBound => 1 end # A match expression matches left and right using a matching operator. # class MatchExpression < BinaryExpression has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'!~', :'=~']), :lowerBound => 1 end # An 'in' expression checks if left is 'in' right # class InExpression < BinaryExpression; end # A boolean expression applies a logical connective operator (and, or) to left and right expressions. # class BooleanExpression < BinaryExpression abstract end # An and expression applies the logical connective operator and to left and right expression # and does not evaluate the right expression if the left expression is false. # class AndExpression < BooleanExpression; end # An or expression applies the logical connective operator or to the left and right expression # and does not evaluate the right expression if the left expression is true # class OrExpression < BooleanExpression; end # A literal list / array containing 0:M expressions. # class LiteralList < Expression contains_many_uni 'values', Expression end # A Keyed entry has a key and a value expression. It is typically used as an entry in a Hash. # class KeyedEntry < Positioned contains_one_uni 'key', Expression, :lowerBound => 1 contains_one_uni 'value', Expression, :lowerBound => 1 end # A literal hash is a collection of KeyedEntry objects # class LiteralHash < Expression contains_many_uni 'entries', KeyedEntry end # A block contains a list of expressions # class BlockExpression < Expression contains_many_uni 'statements', Expression end # A case option entry in a CaseStatement # class CaseOption < Expression contains_many_uni 'values', Expression, :lowerBound => 1 contains_one_uni 'then_expr', Expression, :lowerBound => 1 end # A case expression has a test, a list of options (multi values => block map). # One CaseOption may contain a LiteralDefault as value. This option will be picked if nothing # else matched. # class CaseExpression < Expression contains_one_uni 'test', Expression, :lowerBound => 1 contains_many_uni 'options', CaseOption end # A query expression is an expression that is applied to some collection. # The contained optional expression may contain different types of relational expressions depending # on what the query is applied to. # class QueryExpression < Expression abstract contains_one_uni 'expr', Expression, :lowerBound => 0 end # An exported query is a special form of query that searches for exported objects. # class ExportedQuery < QueryExpression end # A virtual query is a special form of query that searches for virtual objects. # class VirtualQuery < QueryExpression end # An attribute operation sets or appends a value to a named attribute. # class AttributeOperation < Positioned has_attr 'attribute_name', String, :lowerBound => 1 has_attr 'operator', RGen::MetamodelBuilder::DataTypes::Enum.new([:'=>', :'+>', ]), :lowerBound => 1 contains_one_uni 'value_expr', Expression, :lowerBound => 1 end # An object that collects stored objects from the central cache and returns # them to the current host. Operations may optionally be applied. # class CollectExpression < Expression contains_one_uni 'type_expr', Expression, :lowerBound => 1 contains_one_uni 'query', QueryExpression, :lowerBound => 1 contains_many_uni 'operations', AttributeOperation end class Parameter < Positioned has_attr 'name', String, :lowerBound => 1 contains_one_uni 'value', Expression end # Abstract base class for definitions. # class Definition < Expression abstract end # Abstract base class for named and parameterized definitions. class NamedDefinition < Definition abstract has_attr 'name', String, :lowerBound => 1 contains_many_uni 'parameters', Parameter contains_one_uni 'body', Expression end - # A function written in the Puppet Langauge - class FunctionDefinition < NamedDefinition - end - # A resource type definition (a 'define' in the DSL). # class ResourceTypeDefinition < NamedDefinition end # A node definition matches hosts using Strings, or Regular expressions. It may inherit from # a parent node (also using a String or Regular expression). # class NodeDefinition < Definition contains_one_uni 'parent', Expression contains_many_uni 'host_matches', Expression, :lowerBound => 1 contains_one_uni 'body', Expression end class LocatableExpression < Expression has_many_attr 'line_offsets', Integer has_attr 'locator', Object, :lowerBound => 1, :transient => true module ClassModule # Go through the gymnastics of making either value or pattern settable # with synchronization to the other form. A derived value cannot be serialized # and we want to serialize the pattern. When recreating the object we need to # recreate it from the pattern string. # The below sets both values if one is changed. # def locator unless result = getLocator setLocator(result = Puppet::Pops::Parser::Locator.locator(source_text, source_ref(), line_offsets)) end result end end end # Contains one expression which has offsets reported virtually (offset against the Program's # overall locator). # class SubLocatedExpression < Expression contains_one_uni 'expr', Expression, :lowerBound => 1 # line offset index for contained expressions has_many_attr 'line_offsets', Integer # Number of preceding lines (before the line_offsets) has_attr 'leading_line_count', Integer # The offset of the leading source line (i.e. size of "left margin"). has_attr 'leading_line_offset', Integer # The locator for the sub-locatable's children (not for the sublocator itself) # The locator is not serialized and is recreated on demand from the indexing information # in self. # has_attr 'locator', Object, :lowerBound => 1, :transient => true module ClassModule def locator unless result = getLocator # Adapt myself to get the Locator for me adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(self) # Get the program (root), and deal with case when not contained in a program program = eAllContainers.find {|c| c.is_a?(Program) } source_ref = program.nil? ? '' : program.source_ref # An outer locator is needed since SubLocator only deals with offsets. This outer locator # has 0,0 as origin. outer_locator = Puppet::Pops::Parser::Locator.locator(adpater.extract_text, source_ref, line_offsets) # Create a sublocator that describes an offset from the outer # NOTE: the offset of self is the same as the sublocator's leading_offset result = Puppet::Pops::Parser::Locator::SubLocator.new(outer_locator, leading_line_count, offset, leading_line_offset) setLocator(result) end result end end end # A heredoc is a wrapper around a LiteralString or a ConcatenatedStringExpression with a specification # of syntax. The expectation is that "syntax" has meaning to a validator. A syntax of nil or '' means # "unspecified syntax". # class HeredocExpression < Expression has_attr 'syntax', String contains_one_uni 'text_expr', Expression, :lowerBound => 1 end # A class definition # class HostClassDefinition < NamedDefinition has_attr 'parent_class', String end # i.e {|parameters| body } class LambdaExpression < Expression contains_many_uni 'parameters', Parameter contains_one_uni 'body', Expression end # If expression. If test is true, the then_expr part should be evaluated, else the (optional) # else_expr. An 'elsif' is simply an else_expr = IfExpression, and 'else' is simply else == Block. # a 'then' is typically a Block. # class IfExpression < Expression contains_one_uni 'test', Expression, :lowerBound => 1 contains_one_uni 'then_expr', Expression, :lowerBound => 1 contains_one_uni 'else_expr', Expression end # An if expression with boolean reversed test. # class UnlessExpression < IfExpression end # An abstract call. # class CallExpression < Expression abstract # A bit of a crutch; functions are either procedures (void return) or has an rvalue # this flag tells the evaluator that it is a failure to call a function that is void/procedure # where a value is expected. # has_attr 'rval_required', Boolean, :defaultValueLiteral => "false" contains_one_uni 'functor_expr', Expression, :lowerBound => 1 contains_many_uni 'arguments', Expression contains_one_uni 'lambda', Expression end # A function call where the functor_expr should evaluate to something callable. # class CallFunctionExpression < CallExpression; end # A function call where the given functor_expr should evaluate to the name # of a function. # class CallNamedFunctionExpression < CallExpression; end # A method/function call where the function expr is a NamedAccess and with support for # an optional lambda block # class CallMethodExpression < CallExpression end # Abstract base class for literals. # class Literal < Expression abstract end # A literal value is an abstract value holder. The type of the contained value is # determined by the concrete subclass. # class LiteralValue < Literal abstract end # A Regular Expression Literal. # class LiteralRegularExpression < LiteralValue has_attr 'value', Object, :lowerBound => 1, :transient => true has_attr 'pattern', String, :lowerBound => 1 module ClassModule # Go through the gymnastics of making either value or pattern settable # with synchronization to the other form. A derived value cannot be serialized # and we want to serialize the pattern. When recreating the object we need to # recreate it from the pattern string. # The below sets both values if one is changed. # def value= regexp setValue regexp setPattern regexp.to_s end def pattern= regexp_string setPattern regexp_string setValue Regexp.new(regexp_string) end end end # A Literal String # class LiteralString < LiteralValue has_attr 'value', String, :lowerBound => 1 end class LiteralNumber < LiteralValue abstract end # A literal number has a radix of decimal (10), octal (8), or hex (16) to enable string conversion with the input radix. # By default, a radix of 10 is used. # class LiteralInteger < LiteralNumber has_attr 'radix', Integer, :lowerBound => 1, :defaultValueLiteral => "10" has_attr 'value', Integer, :lowerBound => 1 end class LiteralFloat < LiteralNumber has_attr 'value', Float, :lowerBound => 1 end # The DSL `undef`. # class LiteralUndef < Literal; end # The DSL `default` class LiteralDefault < Literal; end # DSL `true` or `false` class LiteralBoolean < LiteralValue has_attr 'value', Boolean, :lowerBound => 1 end # A text expression is an interpolation of an expression. If the embedded expression is # a QualifiedName, it is taken as a variable name and resolved. All other expressions are evaluated. # The result is transformed to a string. # class TextExpression < UnaryExpression; end # An interpolated/concatenated string. The contained segments are expressions. Verbatim sections # should be LiteralString instances, and interpolated expressions should either be # TextExpression instances (if QualifiedNames should be turned into variables), or any other expression # if such treatment is not needed. # class ConcatenatedString < Expression contains_many_uni 'segments', Expression end # A DSL NAME (one or multiple parts separated by '::'). # class QualifiedName < LiteralValue has_attr 'value', String, :lowerBound => 1 end # A DSL CLASSREF (one or multiple parts separated by '::' where (at least) the first part starts with an upper case letter). # class QualifiedReference < LiteralValue has_attr 'value', String, :lowerBound => 1 end # A Variable expression looks up value of expr (some kind of name) in scope. # The expression is typically a QualifiedName, or QualifiedReference. # class VariableExpression < UnaryExpression; end # Epp start class EppExpression < Expression has_attr 'see_scope', Boolean contains_one_uni 'body', Expression end # A string to render class RenderStringExpression < LiteralString end # An expression to evluate and render class RenderExpression < UnaryExpression end # A resource body describes one resource instance # class ResourceBody < Positioned contains_one_uni 'title', Expression contains_many_uni 'operations', AttributeOperation end # An abstract resource describes the form of the resource (regular, virtual or exported) # and adds convenience methods to ask if it is virtual or exported. # All derived classes may not support all forms, and these needs to be validated # class AbstractResource < Expression abstract has_attr 'form', RGen::MetamodelBuilder::DataTypes::Enum.new([:regular, :virtual, :exported ]), :lowerBound => 1, :defaultValueLiteral => "regular" has_attr 'virtual', Boolean, :derived => true has_attr 'exported', Boolean, :derived => true module ClassModule def virtual_derived form == :virtual || form == :exported end def exported_derived form == :exported end end end # A resource expression is used to instantiate one or many resource. Resources may optionally # be virtual or exported, an exported resource is always virtual. # class ResourceExpression < AbstractResource contains_one_uni 'type_name', Expression, :lowerBound => 1 contains_many_uni 'bodies', ResourceBody end # A resource defaults sets defaults for a resource type. This class inherits from AbstractResource # but does only support the :regular form (this is intentional to be able to produce better error messages # when illegal forms are applied to a model. # class ResourceDefaultsExpression < AbstractResource contains_one_uni 'type_ref', QualifiedReference contains_many_uni 'operations', AttributeOperation end # A resource override overrides already set values. # class ResourceOverrideExpression < Expression contains_one_uni 'resources', Expression, :lowerBound => 1 contains_many_uni 'operations', AttributeOperation end # A selector entry describes a map from matching_expr to value_expr. # class SelectorEntry < Positioned contains_one_uni 'matching_expr', Expression, :lowerBound => 1 contains_one_uni 'value_expr', Expression, :lowerBound => 1 end # A selector expression represents a mapping from a left_expr to a matching SelectorEntry. # class SelectorExpression < Expression contains_one_uni 'left_expr', Expression, :lowerBound => 1 contains_many_uni 'selectors', SelectorEntry end # A named access expression looks up a named part. (e.g. $a.b) # class NamedAccessExpression < BinaryExpression; end # A Program is the top level construct returned by the parser # it contains the parsed result in the body, and has a reference to the full source text, # and its origin. The line_offset's is an array with the start offset of each line. # class Program < PopsObject contains_one_uni 'body', Expression has_many 'definitions', Definition has_attr 'source_text', String has_attr 'source_ref', String has_many_attr 'line_offsets', Integer has_attr 'locator', Object, :lowerBound => 1, :transient => true module ClassModule def locator unless result = getLocator setLocator(result = Puppet::Pops::Parser::Locator.locator(source_text, source_ref(), line_offsets)) end result end end end end diff --git a/lib/puppet/pops/model/model_label_provider.rb b/lib/puppet/pops/model/model_label_provider.rb index dd4531761..979aa4bc5 100644 --- a/lib/puppet/pops/model/model_label_provider.rb +++ b/lib/puppet/pops/model/model_label_provider.rb @@ -1,105 +1,104 @@ # A provider of labels for model object, producing a human name for the model object. # As an example, if object is an ArithmeticExpression with operator +, `#a_an(o)` produces "a '+' Expression", # #the(o) produces "the + Expression", and #label produces "+ Expression". # class Puppet::Pops::Model::ModelLabelProvider < Puppet::Pops::LabelProvider def initialize @@label_visitor ||= Puppet::Pops::Visitor.new(self,"label",0,0) end # Produces a label for the given objects type/operator without article. # If a Class is given, its name is used as label # def label o @@label_visitor.visit(o) end def label_Factory o ; label(o.current) end def label_Array o ; "Array" end def label_LiteralInteger o ; "Literal Integer" end def label_LiteralFloat o ; "Literal Float" end def label_ArithmeticExpression o ; "'#{o.operator}' expression" end def label_AccessExpression o ; "'[]' expression" end def label_MatchExpression o ; "'#{o.operator}' expression" end def label_CollectExpression o ; label(o.query) end def label_EppExpression o ; "Epp Template" end def label_ExportedQuery o ; "Exported Query" end def label_VirtualQuery o ; "Virtual Query" end def label_QueryExpression o ; "Collect Query" end def label_ComparisonExpression o ; "'#{o.operator}' expression" end def label_AndExpression o ; "'and' expression" end def label_OrExpression o ; "'or' expression" end def label_InExpression o ; "'in' expression" end def label_AssignmentExpression o ; "'#{o.operator}' expression" end def label_AttributeOperation o ; "'#{o.operator}' expression" end def label_LiteralList o ; "Array Expression" end def label_LiteralHash o ; "Hash Expression" end def label_KeyedEntry o ; "Hash Entry" end def label_LiteralBoolean o ; "Boolean" end def label_TrueClass o ; "Boolean" end def label_FalseClass o ; "Boolean" end def label_LiteralString o ; "String" end def label_LambdaExpression o ; "Lambda" end def label_LiteralDefault o ; "'default' expression" end def label_LiteralUndef o ; "'undef' expression" end def label_LiteralRegularExpression o ; "Regular Expression" end def label_Nop o ; "Nop Expression" end def label_NamedAccessExpression o ; "'.' expression" end def label_NilClass o ; "Nil Object" end def label_NotExpression o ; "'not' expression" end def label_VariableExpression o ; "Variable" end def label_TextExpression o ; "Expression in Interpolated String" end def label_UnaryMinusExpression o ; "Unary Minus" end def label_BlockExpression o ; "Block Expression" end def label_ConcatenatedString o ; "Double Quoted String" end def label_HeredocExpression o ; "'@(#{o.syntax})' expression" end def label_HostClassDefinition o ; "Host Class Definition" end def label_NodeDefinition o ; "Node Definition" end def label_ResourceTypeDefinition o ; "'define' expression" end def label_ResourceOverrideExpression o ; "Resource Override" end def label_Parameter o ; "Parameter Definition" end def label_ParenthesizedExpression o ; "Parenthesized Expression" end def label_IfExpression o ; "'if' statement" end def label_UnlessExpression o ; "'unless' Statement" end def label_CallNamedFunctionExpression o ; "Function Call" end def label_CallMethodExpression o ; "Method call" end def label_CaseExpression o ; "'case' statement" end def label_CaseOption o ; "Case Option" end def label_RenderStringExpression o ; "Epp Text" end def label_RenderExpression o ; "Epp Interpolated Expression" end def label_RelationshipExpression o ; "'#{o.operator}' expression" end def label_ResourceBody o ; "Resource Instance Definition" end def label_ResourceDefaultsExpression o ; "Resource Defaults Expression" end def label_ResourceExpression o ; "Resource Statement" end def label_SelectorExpression o ; "Selector Expression" end def label_SelectorEntry o ; "Selector Option" end def label_Integer o ; "Integer" end def label_Fixnum o ; "Integer" end def label_Bignum o ; "Integer" end def label_Float o ; "Float" end def label_String o ; "String" end def label_Regexp o ; "Regexp" end def label_Object o ; "Object" end def label_Hash o ; "Hash" end def label_QualifiedName o ; "Name" end def label_QualifiedReference o ; "Type-Name" end - def label_FunctionDefinition o ; "Function" end def label_PAbstractType o ; "#{Puppet::Pops::Types::TypeCalculator.string(o)}-Type" end def label_PResourceType o if o.title "#{Puppet::Pops::Types::TypeCalculator.string(o)} Resource-Reference" else "#{Puppet::Pops::Types::TypeCalculator.string(o)}-Type" end end def label_Class o if o <= Puppet::Pops::Types::PAbstractType simple_name = o.name.split('::').last simple_name[1..-5] + "-Type" else o.name end end end diff --git a/lib/puppet/pops/model/model_tree_dumper.rb b/lib/puppet/pops/model/model_tree_dumper.rb index 7a3668afb..0366a421a 100644 --- a/lib/puppet/pops/model/model_tree_dumper.rb +++ b/lib/puppet/pops/model/model_tree_dumper.rb @@ -1,391 +1,385 @@ # Dumps a Pops::Model in reverse polish notation; i.e. LISP style # The intention is to use this for debugging output # TODO: BAD NAME - A DUMP is a Ruby Serialization # class Puppet::Pops::Model::ModelTreeDumper < Puppet::Pops::Model::TreeDumper def dump_Array o o.collect {|e| do_dump(e) } end def dump_LiteralFloat o o.value.to_s end def dump_LiteralInteger o case o.radix when 10 o.value.to_s when 8 "0%o" % o.value when 16 "0x%X" % o.value else "bad radix:" + o.value.to_s end end def dump_LiteralValue o o.value.to_s end def dump_Factory o do_dump(o.current) end def dump_ArithmeticExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end # x[y] prints as (slice x y) def dump_AccessExpression o if o.keys.size <= 1 ["slice", do_dump(o.left_expr), do_dump(o.keys[0])] else ["slice", do_dump(o.left_expr), do_dump(o.keys)] end end def dump_MatchesExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_CollectExpression o result = ["collect", do_dump(o.type_expr), :indent, :break, do_dump(o.query), :indent] o.operations do |ao| result << :break << do_dump(ao) end result += [:dedent, :dedent ] result end def dump_EppExpression o result = ["epp"] # result << ["parameters"] + o.parameters.collect {|p| do_dump(p) } if o.parameters.size() > 0 if o.body result << do_dump(o.body) else result << [] end result end def dump_ExportedQuery o result = ["<<| |>>"] result += dump_QueryExpression(o) unless is_nop?(o.expr) result end def dump_VirtualQuery o result = ["<| |>"] result += dump_QueryExpression(o) unless is_nop?(o.expr) result end def dump_QueryExpression o [do_dump(o.expr)] end def dump_ComparisonExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_AndExpression o ["&&", do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_OrExpression o ["||", do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_InExpression o ["in", do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_AssignmentExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end # Produces (name => expr) or (name +> expr) def dump_AttributeOperation o [o.attribute_name, o.operator, do_dump(o.value_expr)] end def dump_LiteralList o ["[]"] + o.values.collect {|x| do_dump(x)} end def dump_LiteralHash o ["{}"] + o.entries.collect {|x| do_dump(x)} end def dump_KeyedEntry o [do_dump(o.key), do_dump(o.value)] end def dump_MatchExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_LiteralString o "'#{o.value}'" end def dump_LambdaExpression o result = ["lambda"] result << ["parameters"] + o.parameters.collect {|p| do_dump(p) } if o.parameters.size() > 0 if o.body result << do_dump(o.body) else result << [] end result end def dump_LiteralDefault o ":default" end def dump_LiteralUndef o ":undef" end def dump_LiteralRegularExpression o "/#{o.value.source}/" end def dump_Nop o ":nop" end def dump_NamedAccessExpression o [".", do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_NilClass o "()" end def dump_NotExpression o ['!', dump(o.expr)] end def dump_VariableExpression o "$#{dump(o.expr)}" end # Interpolation (to string) shown as (str expr) def dump_TextExpression o ["str", do_dump(o.expr)] end def dump_UnaryMinusExpression o ['-', do_dump(o.expr)] end def dump_BlockExpression o ["block"] + o.statements.collect {|x| do_dump(x) } end # Interpolated strings are shown as (cat seg0 seg1 ... segN) def dump_ConcatenatedString o ["cat"] + o.segments.collect {|x| do_dump(x)} end def dump_HeredocExpression(o) result = ["@(#{o.syntax})", :indent, :break, do_dump(o.text_expr), :dedent, :break] end def dump_HostClassDefinition o result = ["class", o.name] result << ["inherits", o.parent_class] if o.parent_class result << ["parameters"] + o.parameters.collect {|p| do_dump(p) } if o.parameters.size() > 0 if o.body result << do_dump(o.body) else result << [] end result end def dump_NodeDefinition o result = ["node"] result << ["matches"] + o.host_matches.collect {|m| do_dump(m) } result << ["parent", do_dump(o.parent)] if o.parent if o.body result << do_dump(o.body) else result << [] end result end def dump_NamedDefinition o # the nil must be replaced with a string result = [nil, o.name] result << ["parameters"] + o.parameters.collect {|p| do_dump(p) } if o.parameters.size() > 0 if o.body result << do_dump(o.body) else result << [] end result end def dump_ResourceTypeDefinition o result = dump_NamedDefinition(o) result[0] = 'define' result end - def dump_FunctionDefinition o - result = dump_NamedDefinition(o) - result[0] = 'function' - result - end - def dump_ResourceOverrideExpression o result = ["override", do_dump(o.resources), :indent] o.operations.each do |p| result << :break << do_dump(p) end result << :dedent result end # Produces parameters as name, or (= name value) def dump_Parameter o name_part = "#{o.name}" if o.value ["=", name_part, do_dump(o.value)] else name_part end end def dump_ParenthesizedExpression o do_dump(o.expr) end # Hides that Program exists in the output (only its body is shown), the definitions are just # references to contained classes, resource types, and nodes def dump_Program(o) dump(o.body) end def dump_IfExpression o result = ["if", do_dump(o.test), :indent, :break, ["then", :indent, do_dump(o.then_expr), :dedent]] result += [:break, ["else", :indent, do_dump(o.else_expr), :dedent], :dedent] unless is_nop? o.else_expr result end def dump_UnlessExpression o result = ["unless", do_dump(o.test), :indent, :break, ["then", :indent, do_dump(o.then_expr), :dedent]] result += [:break, ["else", :indent, do_dump(o.else_expr), :dedent], :dedent] unless is_nop? o.else_expr result end # Produces (invoke name args...) when not required to produce an rvalue, and # (call name args ... ) otherwise. # def dump_CallNamedFunctionExpression o result = [o.rval_required ? "call" : "invoke", do_dump(o.functor_expr)] o.arguments.collect {|a| result << do_dump(a) } result end # def dump_CallNamedFunctionExpression o # result = [o.rval_required ? "call" : "invoke", do_dump(o.functor_expr)] # o.arguments.collect {|a| result << do_dump(a) } # result # end def dump_CallMethodExpression o result = [o.rval_required ? "call-method" : "invoke-method", do_dump(o.functor_expr)] o.arguments.collect {|a| result << do_dump(a) } result << do_dump(o.lambda) if o.lambda result end def dump_CaseExpression o result = ["case", do_dump(o.test), :indent] o.options.each do |s| result << :break << do_dump(s) end result << :dedent end def dump_CaseOption o result = ["when"] result << o.values.collect {|x| do_dump(x) } result << ["then", do_dump(o.then_expr) ] result end def dump_RelationshipExpression o [o.operator.to_s, do_dump(o.left_expr), do_dump(o.right_expr)] end def dump_RenderStringExpression o ["render-s", " '#{o.value}'"] end def dump_RenderExpression o ["render", do_dump(o.expr)] end def dump_ResourceBody o result = [do_dump(o.title), :indent] o.operations.each do |p| result << :break << do_dump(p) end result << :dedent result end def dump_ResourceDefaultsExpression o result = ["resource-defaults", do_dump(o.type_ref), :indent] o.operations.each do |p| result << :break << do_dump(p) end result << :dedent result end def dump_ResourceExpression o form = o.form == :regular ? '' : o.form.to_s + "-" result = [form+"resource", do_dump(o.type_name), :indent] o.bodies.each do |b| result << :break << do_dump(b) end result << :dedent result end def dump_SelectorExpression o ["?", do_dump(o.left_expr)] + o.selectors.collect {|x| do_dump(x) } end def dump_SelectorEntry o [do_dump(o.matching_expr), "=>", do_dump(o.value_expr)] end def dump_SubLocatedExpression o ["sublocated", do_dump(o.expr)] end def dump_Object o [o.class.to_s, o.to_s] end def is_nop? o o.nil? || o.is_a?(Puppet::Pops::Model::Nop) end end diff --git a/lib/puppet/pops/parser/egrammar.ra b/lib/puppet/pops/parser/egrammar.ra index 5f36886ef..bbd2819e4 100644 --- a/lib/puppet/pops/parser/egrammar.ra +++ b/lib/puppet/pops/parser/egrammar.ra @@ -1,762 +1,765 @@ # vim: syntax=ruby # Parser using the Pops model, expression based class Puppet::Pops::Parser::Parser token STRING DQPRE DQMID DQPOST 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 LOW prechigh left HIGH left SEMIC left PIPE left LPAREN left RPAREN left AT ATAT left DOT left CALL nonassoc EPP_START left LBRACK LISTSTART left RBRACK left QMARK left LCOLLECT LLCOLLECT right NOT 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 right APPENDS DELETES EQUALS left LBRACE left SELBRACE left RBRACE left IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB left TITLE_COLON left CASE_COLON left FARROW left COMMA nonassoc RENDER_EXPR nonassoc RENDER_STRING left LOW preclow rule # Produces [Model::BlockExpression, Model::Expression, nil] depending on multiple statements, single statement or empty program : statements { result = create_program(Factory.block_or_expression(*val[0])) } | epp_expression { result = create_program(Factory.block_or_expression(*val[0])) } | nil # Produces a semantic model (non validated, but semantically adjusted). statements : syntactic_statements { result = transform_calls(val[0]) } # Change may have issues with nil; i.e. program is a sequence of nils/nops # Simplified from original which had validation for top level constructs - see statement rule # 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 syntactic_statement : any_expression { result = val[0] } | syntactic_statement COMMA any_expression { result = aryfy(val[0]).push val[2] } any_expression : relationship_expression relationship_expression : resource_expression =LOW { result = val[0] } | relationship_expression IN_EDGE relationship_expression { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship_expression IN_EDGE_SUB relationship_expression { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship_expression OUT_EDGE relationship_expression { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } | relationship_expression OUT_EDGE_SUB relationship_expression { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] } #---EXPRESSION # # Produces Model::Expression expression : higher_precedence | 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] } | 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 EQUALS expression { result = val[0].set(val[2]) ; loc result, val[1] } | expression APPENDS expression { result = val[0].plus_set(val[2]) ; loc result, val[1] } | expression DELETES expression { result = val[0].minus_set(val[2]); loc result, val[1] } | expression QMARK selector_entries { result = val[0].select(*val[2]) ; loc result, val[0] } | LPAREN expression RPAREN { result = val[1].paren() ; loc result, val[0] } #---EXPRESSIONS # (e.g. 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]) } # These go through a chain of left recursion, ending with primary_expression higher_precedence : call_function_expression primary_expression : literal_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 | function_definition # Allways have the same value literal_expression : array | boolean | default | hash | regex | text_or_name | number | type | undef text_or_name : name { result = val[0] } | quotedtext { result = val[0] } #---CALL FUNCTION # # Produces Model::CallNamedFunction call_function_expression : primary_expression LPAREN expressions endcomma RPAREN { result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] } | primary_expression LPAREN RPAREN { result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] } | primary_expression LPAREN expressions endcomma RPAREN lambda { result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] result.lambda = val[5] } | primary_expression LPAREN RPAREN lambda { result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] result.lambda = val[3] } | primary_expression = LOW { result = val[0] } #---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 expressions 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] } # TODO: It may be of value to access named elements of types too named_access : expression DOT NAME { result = val[0].dot(Factory.fqn(val[2][:value])) loc result, val[1], val[2] } #---LAMBDA # # This is a temporary switch while experimenting with concrete syntax # One should be picked for inclusion in puppet. # Lambda with parameters to the left of the body lambda : lambda_parameter_list lambda_rest { result = Factory.LAMBDA(val[0], val[1]) # loc result, val[1] # TODO } lambda_rest : LBRACE statements RBRACE { result = val[1] } | LBRACE RBRACE { result = nil } # Produces Array lambda_parameter_list : PIPE PIPE { result = [] } | PIPE parameters endcomma PIPE { result = val[1] } #---CONDITIONALS # #--IF # # Produces Model::IfExpression 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 # # Changed from Puppet 3x where there is no else part on 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 # # Produces Model::CaseExpression 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 case_colon LBRACE statements RBRACE { result = Factory.WHEN(val[0], val[3]) loc result, val[1], val[4] } | expressions case_colon LBRACE RBRACE = LOW { result = Factory.WHEN(val[0], nil) loc result, val[1], val[3] } case_colon: COLON =CASE_COLON { result = val[0] } # 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] } #---RESOURCE # # Produces [Model::ResourceExpression, Model::ResourceDefaultsExpression] # The resource expression parses a generalized syntax and then selects the correct # resulting model based on the combinatoin of the LHS and what follows. # It also handled exported and virtual resources, and the class case # resource_expression : expression =LOW { result = val[0] } | at expression LBRACE resourceinstances endsemi RBRACE { result = case Factory.resource_shape(val[1]) when :resource, :class tmp = Factory.RESOURCE(Factory.fqn(token_text(val[1])), val[3]) tmp.form = val[0] tmp when :defaults error val[1], "A resource default can not be virtual or exported" when :override error val[1], "A resource override can not be virtual or exported" else error val[1], "Expression is not valid as a resource, resource-default, or resource-override" end loc result, val[1], val[4] } | at expression LBRACE attribute_operations endcomma RBRACE { result = case Factory.resource_shape(val[1]) when :resource, :class, :defaults, :override error val[1], "Defaults are not virtualizable" else error val[1], "Expression is not valid as a resource, resource-default, or resource-override" end } | expression LBRACE resourceinstances endsemi RBRACE { result = case Factory.resource_shape(val[0]) when :resource, :class Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2]) when :defaults error val[1], "A resource default can not specify a resource name" when :override error val[1], "A resource override does not allow override of name of resource" else error val[1], "Expression is not valid as a resource, resource-default, or resource-override" end loc result, val[0], val[4] } | expression 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 shuld 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] } | at CLASS LBRACE resourceinstances endsemi RBRACE { result = Factory.RESOURCE(Factory.fqn(token_text(val[1])), val[3]) result.form = val[0] loc result, val[1], val[5] } | CLASS LBRACE resourceinstances endsemi RBRACE { result = Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2]) loc result, val[0], val[4] } resourceinst : expression title_colon attribute_operations endcomma { result = Factory.RESOURCE_BODY(val[0], val[2]) } title_colon : COLON =TITLE_COLON { result = val[0] } resourceinstances : resourceinst { result = [val[0]] } | resourceinstances SEMIC resourceinst { result = val[0].push val[2] } # Produces Symbol corresponding to resource form # at : AT { result = :virtual } | AT AT { result = :exported } | ATAT { result = :exported } #---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 for source.select(QUERY).apply(ATTRIBUTE_OPERATIONS) # # Produces Model::CollectExpression # 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) # # Produces Array # attribute_operations : { result = [] } | 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] } #---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 nodeparent LBRACE statements RBRACE { result = add_definition(Factory.NODE(val[1], val[2], val[4])) loc result, val[0], val[5] } | NODE hostnames nodeparent LBRACE RBRACE { result = add_definition(Factory.NODE(val[1], val[2], nil)) loc result, val[0], val[4] } # 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 { result = val[0] } | quotedtext { result = val[0] } | DEFAULT { result = Factory.literal(:default); loc result, val[0] } | regex dotted_name : NAME { result = Factory.literal(val[0][:value]); loc result, val[0] } | dotted_name DOT NAME { result = Factory.concat(val[0], '.', val[2][:value]); loc result, val[0], val[2] } # Produces Expression, since hostname is an Expression nodeparent : nil | INHERITS hostname { result = val[1] } #---FUNCTION DEFINITION # 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] - } + : FUNCTION { result = Factory.literal(val[0][:value]) ; loc result, val[0] } + # 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 { result = val[0] } | 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 : 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] } #--RESTRICTED EXPRESSIONS # i.e. where one could have expected an expression, but the set is limited ## What is allowed RHS of match operators (see expression) #match_rvalue # : regex # | text_or_name #--VARIABLE # variable : VARIABLE { result = Factory.fqn(val[0][:value]).var ; loc result, val[0] } #---LITERALS (dynamic and static) # array : LBRACK expressions RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[2] } | LBRACK expressions COMMA RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[3] } | LBRACK RBRACK { result = Factory.literal([]) ; loc result, val[0] } | LISTSTART expressions RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[2] } | LISTSTART expressions COMMA RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[3] } | LISTSTART 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 : expression FARROW expression { 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] } 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 : expression { 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 statements { result = Factory.EPP(val[1], val[2]); loc result, val[0] } 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 number : NUMBER { result = Factory.NUMBER(val[0][:value]) ; loc result, val[0] } name : NAME { result = Factory.QNAME_OR_NUMBER(val[0][:value]) ; loc result, val[0] } type : CLASSREF { result = Factory.QREF(val[0][:value]) ; loc result, val[0] } undef : UNDEF { result = Factory.literal(:undef); loc result, val[0] } default : DEFAULT { result = Factory.literal(:default); loc result, val[0] } # Assumes lexer produces a Boolean value for booleans, or this will go wrong and produce a literal string # with the text 'true'. #TODO: could be changed to a specific boolean literal factory method to prevent this possible glitch. boolean : BOOLEAN { result = Factory.literal(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 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 9667e12f7..82c867c2c 100644 --- a/lib/puppet/pops/parser/eparser.rb +++ b/lib/puppet/pops/parser/eparser.rb @@ -1,2616 +1,2610 @@ # # 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', 758) +module_eval(<<'...end egrammar.ra/module_eval...', 'egrammar.ra', 761) # Make emacs happy # Local Variables: # mode: ruby # End: ...end egrammar.ra/module_eval... ##### State transition tables begin ### clist = [ -'59,61,-133,279,53,241,55,-218,269,-131,-227,214,269,227,249,317,59,61', -'300,248,227,358,302,14,227,59,61,247,124,42,243,49,246,52,46,128,50', -'71,67,127,44,70,47,48,-133,280,68,13,224,-218,69,-131,-227,12,137,262', -'128,135,59,61,127,72,53,137,55,402,135,43,268,254,253,66,62,269,64,65', -'63,72,234,51,128,14,251,54,127,252,72,42,62,49,244,52,46,333,50,71,67', -'62,44,70,47,48,190,128,68,13,128,127,69,128,127,12,76,127,128,336,59', -'61,127,72,53,368,55,128,81,43,353,127,352,66,62,76,64,65,353,338,352', -'51,104,14,108,54,103,264,265,42,157,49,340,52,46,324,50,71,67,74,44', -'70,47,48,59,61,68,13,107,154,69,152,278,12,77,79,78,80,59,61,323,72', -'53,345,55,400,81,43,346,347,82,66,62,227,64,65,320,350,319,51,104,14', -'108,54,103,354,356,42,316,49,276,52,46,276,50,71,67,278,44,70,47,48', -'276,364,68,13,107,365,69,223,300,12,129,301,117,300,59,61,238,72,53', -'376,55,398,81,43,116,294,82,66,62,378,64,65,116,278,293,51,104,14,108', -'54,103,292,381,42,116,49,278,52,46,276,50,71,67,113,44,70,47,48,385', -'356,68,13,107,387,69,388,389,12,390,391,238,393,59,61,394,72,53,395', -'55,396,81,43,238,76,73,66,62,403,64,65,404,405,406,51,104,14,108,54', -'103,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,107,,69,,,12,,,,', -'59,61,,72,53,,55,,81,43,,,,66,62,,64,65,,,,51,104,14,108,54,103,,,42', -',49,,52,110,,50,71,67,,44,70,,,,,68,13,107,,69,,,12,,,,,59,61,,72,53', -',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,', -'44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', -',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', -',,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', +'59,61,277,-131,53,240,55,-218,267,-133,-227,362,315,226,247,267,59,61', +'237,246,226,226,300,14,355,59,61,245,233,42,242,49,244,52,46,128,50', +'71,67,127,44,70,47,48,278,-131,68,13,260,-218,69,-133,-227,12,137,223', +'128,135,59,61,127,72,53,137,55,397,135,43,266,262,263,66,62,267,64,65', +'63,72,124,51,128,14,249,54,127,250,72,42,62,49,330,52,46,318,50,71,67', +'62,44,70,47,48,237,128,68,13,128,127,69,128,127,12,333,127,128,274,59', +'61,127,72,53,365,55,335,81,43,350,222,349,66,62,337,64,65,350,76,349', +'51,104,14,108,54,103,59,61,42,299,49,298,52,46,276,50,71,67,74,44,70', +'47,48,252,251,68,13,107,116,69,342,343,12,77,79,78,80,59,61,344,72,53', +'226,55,395,81,43,213,347,82,66,62,243,64,65,351,353,292,51,104,14,108', +'54,103,189,274,42,276,49,274,52,46,361,50,71,67,298,44,70,47,48,291', +'298,68,13,107,76,69,156,153,12,151,372,314,290,59,61,374,72,53,276,55', +'393,81,43,276,129,82,66,62,274,64,65,377,116,117,51,104,14,108,54,103', +'317,116,42,381,49,353,52,46,383,50,71,67,384,44,70,47,48,385,386,68', +'13,107,387,69,113,389,12,390,391,321,76,59,61,73,72,53,398,55,399,81', +'43,400,401,,66,62,,64,65,,,,51,104,14,108,54,103,,,42,,49,,52,110,,50', +'71,67,,44,70,,,,,68,13,107,,69,,,12,,,,,59,61,,72,53,,55,,81,43,,,,66', +'62,,64,65,,,,51,104,14,108,54,103,,,42,,49,,52,110,,50,71,67,,44,70', +',,,,68,13,107,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,', +'51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,', +',,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', '110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', -',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,', -'68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', -',54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59', +',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48', +',,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', +',54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61', +',72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50', +'71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62', +',64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,', +'69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42', +',49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', +',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', +',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51', +',14,,54,,,,42,,49,,52,123,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', '61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,', '50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', '62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', ',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', ',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', -',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,123,,50,71,67,', -'44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,374,,43,,,,66,62,,64', -'65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69', -',,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,', -'49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53', -',55,359,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67', -',44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', -',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', -',,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', -'110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,141,55,,,43', -',,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,', -',68,13,,,69,,,12,,,,,59,61,,72,53,143,55,,,43,,,,66,62,,64,65,,,,51', -',14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', -'61,,72,53,,55,146,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110', -',50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', -'62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', -',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', -',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', -',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,', -'44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,156,,,43,,,,66,62,,64,65', -',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', +',55,296,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67', +',44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,140,55,,,43,,,,66,62', +',64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,', +'69,,,12,,,,,59,61,,72,53,142,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,', +',,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72', +'53,,55,145,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71', +'67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64', +'65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,', +',12,,,,,59,61,,72,53,,55,302,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42', +',49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53', +',55,145,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67', +',44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,155,,,43,,,,66,62,', +'64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69', +',,12,,,,,59,61,,72,53,,55,371,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42', +',49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53', +',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44', +'70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', +',,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,', +',12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49', +',52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', +',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70', +'47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,', +',51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12', ',,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', -'110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', -',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48', +'46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43', +',,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48', ',,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', ',54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61', -',72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71', -'67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62', -',64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13', -',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', -',42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72', -'53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67', -',44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64', -'65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69', -',,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,', -'49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', +',72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50', +'71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62', +',64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,', +'69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42', +',49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', ',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', ',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51', ',14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', '61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,', '50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', '62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', ',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', ',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', ',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,', '44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', ',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', ',,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', '110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', ',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,', '68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', ',54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61', ',72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50', '71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62', ',64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,', '69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42', ',49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', ',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', ',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51', ',14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', '61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,', '50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', '62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', ',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', ',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', ',55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,', -'44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', -',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', -',,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', -'110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', -',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,', -'68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,189,66,62,,64,65,,,,51,', -'14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', -'61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,192,209,203,210', -'52,204,212,205,201,199,,194,207,,,,,68,13,213,208,206,,,12,,,,,59,61', -',72,53,,55,,211,193,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110', -',50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', +'44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,356,,43,,,188,66,62,', +'64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69', +',,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,191', +'208,202,209,52,203,211,204,200,198,,193,206,,,,,68,13,212,207,205,,', +'12,,,,,59,61,,72,53,,55,,210,192,,,,66,62,,64,65,,,,51,,14,,54,,,,42', +',49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', +',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', +',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51', +',14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', +'61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,', +'50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', '62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', ',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', ',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', -',55,329,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67', -',44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', -',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', -',,,,59,61,,72,53,327,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49', -',52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,326,55', +',55,304,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67', +',44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64', +'65,,,,51,,14,220,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69', +',,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,', +'49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55', ',,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', ',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51', -',14,221,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,', -',,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', -'110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', -',,66,62,,64,65,,,,51,,14,,54,,,,192,209,203,210,52,204,212,205,201,199', -',194,207,,,,,68,13,213,208,206,,,12,,,,,59,61,,72,53,,55,,211,193,,', -',66,62,,64,65,,,,51,,14,229,54,,,,42,,49,,52,110,,50,71,67,,44,70,,', -',,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', -',54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61', -',72,53,,55,306,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50', -'71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,304,,43,,', -',66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48', -',,68,13,,,69,,,12,,,,,59,61,,72,53,,55,298,,43,,,,66,62,,64,65,,,,51', -',14,,54,,,,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,', +',14,228,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,', ',,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52', -'110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,', -',,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,', -'68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14', -',54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61', -',72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50', -'71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62', -',64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,', -'69,,,12,,,,,59,61,,72,53,,55,146,,43,,,,66,62,,64,65,,,,51,,14,,54,', -',,42,,49,,52,46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,', -'72,53,,55,,,43,,,,66,62,,64,65,,59,61,51,,14,,54,,,,42,,49,,52,46,,50', -'71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,137,,,135,72,,,,,,43,,59,61', -'66,62,,64,65,81,,,51,72,,,54,,100,101,102,97,92,104,62,108,,103,,,93', -'95,94,96,,,,,,,137,,,135,,,,,,107,,,,99,98,,,85,86,88,87,90,91,72,83', -'84,,,,,81,82,105,,62,,,,,100,101,102,97,92,104,,108,,103,89,,93,95,94', -'96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82', -'100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,', -',,99,98,,,85,86,88,87,90,91,81,83,84,,,250,,,82,100,101,102,97,92,104', -',108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87', -'90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96', -',89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100', +'46,,50,71,67,,44,70,47,48,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43', +',,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,', +',68,13,,,69,,,12,,,,,59,61,,72,53,324,55,,,43,,,,66,62,,64,65,,,,51', +',14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59', +'61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,', +'50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66', +'62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13', +',,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,', +',42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53', +'323,55,,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67', +',44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65', +',,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12', +',,,,59,61,,72,53,,55,326,,43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49', +',52,110,,50,71,67,,44,70,,,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,', +'43,,,,66,62,,64,65,,,,51,,14,,54,,,,42,,49,,52,110,,50,71,67,,44,70', +',,,,68,13,,,69,,,12,,,,,59,61,,72,53,,55,,,43,,,,66,62,,64,65,,59,61', +'51,,14,,54,,,,191,208,202,209,52,203,211,204,200,198,,193,206,,59,61', +',68,13,212,207,205,,,12,,,,137,,,135,72,,,,,210,192,,,,66,62,,64,65', +'81,,,51,72,137,,54,135,100,101,102,97,92,104,62,108,,103,,,93,95,94', +'96,,,,72,,,,,,,,,,,62,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,81', +'82,105,,,248,,,,100,101,102,97,92,104,,108,,103,89,,93,95,94,96,,,,', +',,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,248,,,82,100', '101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99', -'98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,', -'103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91', -'81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,', -',,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100,101', -'102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98', -',,85,86,88,87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103', -',,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83', -'84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,', -',,,,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,,82,,,,,,,,,,,264', -'265,,81,,105,,89,250,,,,100,101,102,97,92,104,,108,,103,,,93,95,94,96', -',,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100', -'101,102,97,92,104,,108,,103,,219,93,95,94,96,,89,,,,,,,,,,,,,,107,,', -',99,98,,,85,86,88,87,90,91,,83,84,,,,,81,82,230,,,,,,,100,101,102,97', -'92,104,,108,,103,89,,93,95,94,96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86', -'88,87,90,91,,83,84,,,,,81,82,231,,,,,,,100,101,102,97,92,104,,108,,103', -'89,,93,95,94,96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,,83', -'84,,,,,81,82,232,,,,,,,100,101,102,97,92,104,,108,,103,89,,93,95,94', -'96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,81,82', -'233,,,,,,,100,101,102,97,92,104,,108,81,103,89,81,93,95,94,96,,,,,,', -'104,,108,104,103,108,,103,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,107', -',,107,,82,,,,,88,87,81,88,87,83,84,,83,84,,,82,89,,82,104,,108,,103', -',,,,81,,,,,89,,,89,100,101,102,97,92,104,,108,107,103,,,93,95,94,96', -'85,86,88,87,,,,83,84,,,,,,82,107,,,,99,98,,,85,86,88,87,90,91,81,83', -'84,89,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,', -',,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,270,,,82,100,101', -'102,97,92,104,,108,81,103,,,93,95,94,96,,89,,,,,104,,108,,103,,,,,107', -',,,99,98,,,85,86,88,87,90,91,,83,84,107,,,81,,82,,,85,86,88,87,,,,83', -'84,104,,108,81,103,82,89,,,,,,,,,,,104,,108,,103,,89,,,107,,,,,,,,85', -'86,88,87,90,91,,83,84,107,,,,,82,,,85,86,88,87,90,91,81,83,84,,,,,,82', -'89,,,,92,104,,108,81,103,,,93,,,,,89,,,,92,104,,108,,103,,,93,,107,', -',,,,,,85,86,88,87,90,91,,83,84,107,,,,,82,,,85,86,88,87,90,91,81,83', -'84,,,,,,82,89,,,,92,104,,108,81,103,,,93,,,,,89,,,,92,104,,108,,103', -',,93,,107,,,,,,,,85,86,88,87,90,91,,83,84,107,,,,,82,,,85,86,88,87,90', -'91,81,83,84,,,,,,82,89,,,97,92,104,,108,,103,,81,93,95,94,96,,89,,,', -',,97,92,104,,108,,103,,107,93,95,94,96,,,,85,86,88,87,90,91,,83,84,', -',,107,,82,,,98,,,85,86,88,87,90,91,81,83,84,,,,89,,82,100,101,102,97', +'98,,,85,86,88,87,90,91,,83,84,,,,,81,82,232,,,,,,,100,101,102,97,92', +'104,,108,,103,89,,93,95,94,96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88', +'87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94', +'96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,81,82', +'231,,,,,,,100,101,102,97,92,104,,108,,103,89,,93,95,94,96,,,,,,,,,,', +',,,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,81,82,230,,,,,,,100', +'101,102,97,92,104,,108,,103,89,,93,95,94,96,,,,,,,,,,,,,,,,107,,,,99', +'98,,,85,86,88,87,90,91,,83,84,,,,,81,82,229,,,,,,,100,101,102,97,92', +'104,,108,,103,89,,93,95,94,96,,,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88', +'87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,218,93,95', +'94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,', +',,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,', +'107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100,101,102,97,92', +'104,,108,,103,262,263,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85', +'86,88,87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93', +'95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84', +',,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,', +',,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100,101,102,97', '92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86', '88,87,90,91,81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95', '94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,', -',,82,100,101,102,97,92,104,274,108,81,103,,81,93,95,94,96,,89,,,,,104', -',108,104,103,108,,103,,107,,,,99,98,,81,85,86,88,87,90,91,,83,84,107', -',,107,104,82,108,,103,,,,,,,83,84,,83,84,,,82,89,,82,,,,,107,,,,,,,', -',,,,,,,83,84,,288,209,287,210,82,285,212,289,283,282,,284,286,,,,,,', -'213,208,290,288,209,287,210,,285,212,289,283,282,,284,286,,,211,291', -',,213,208,290,288,209,287,210,,285,212,289,283,282,,284,286,,,211,291', -',,213,208,290,,,,,,,,,,,,,,,,211,291' ] - racc_action_table = arr = ::Array.new(6596, nil) +',,82,100,101,102,97,92,104,,108,81,103,,81,93,95,94,96,,89,,,,,104,', +'108,104,103,108,,103,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,107,,', +'107,,82,,,,,88,87,81,88,87,83,84,,83,84,,,82,89,,82,104,,108,,103,,', +',,81,,,,,89,,,89,100,101,102,97,92,104,,108,107,103,,,93,95,94,96,85', +'86,88,87,,,,83,84,,,,,,82,107,,,,99,98,,,85,86,88,87,90,91,81,83,84', +'89,,,,,82,100,101,102,97,92,104,272,108,,103,,,93,95,94,96,,89,,,,,', +',,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,,,,,81,82,105,,,,,,', +'100,101,102,97,92,104,,108,81,103,89,,93,95,94,96,,,,,,,104,,108,,103', +',,,,107,,,,99,98,,,85,86,88,87,90,91,,83,84,107,,,81,,82,,,85,86,88', +'87,,,,83,84,104,,108,81,103,82,89,,,,,,,,,,,104,,108,,103,,89,,,107', +',,,,,,,85,86,88,87,90,91,,83,84,107,,,,,82,,,85,86,88,87,90,91,81,83', +'84,,,,,,82,89,,,,92,104,,108,81,103,,,93,,,,,89,,,,92,104,,108,,103', +',,93,,107,,,,,,,,85,86,88,87,90,91,,83,84,107,,,,,82,,,85,86,88,87,90', +'91,81,83,84,,,,,,82,89,,,,92,104,,108,81,103,,,93,,,,,89,,,,92,104,', +'108,,103,,,93,,107,,,,,,,,85,86,88,87,90,91,,83,84,107,,,,,82,,,85,86', +'88,87,90,91,81,83,84,,,,,,82,89,,,97,92,104,,108,,103,,81,93,95,94,96', +',89,,,,,,97,92,104,,108,,103,,107,93,95,94,96,,,,85,86,88,87,90,91,', +'83,84,,,,107,,82,,,98,,,85,86,88,87,90,91,81,83,84,,,,89,,82,100,101', +'102,97,92,104,,108,,103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98', +',,85,86,88,87,90,91,81,83,84,,,268,,,82,100,101,102,97,92,104,,108,', +'103,,,93,95,94,96,,89,,,,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91', +'81,83,84,,,,,,82,100,101,102,97,92,104,,108,,103,,,93,95,94,96,,89,', +',,,,,,,,,,,,107,,,,99,98,,,85,86,88,87,90,91,81,83,84,,,,,,82,100,101', +'102,97,92,104,,108,81,103,,81,93,95,94,96,,89,,,,,104,,108,104,103,108', +',103,,107,,,,99,98,,81,85,86,88,87,90,91,,83,84,107,,,107,104,82,108', +',103,,,,,,,83,84,,83,84,,,82,89,,82,,,,,107,,,,,,,,,,,,,,,83,84,,286', +'208,285,209,82,283,211,287,281,280,,282,284,,,,,,,212,207,288,286,208', +'285,209,,283,211,287,281,280,,282,284,,,210,289,,,212,207,288,286,208', +'285,209,,283,211,287,281,280,,282,284,,,210,289,,,212,207,288,,,,,,', +',,,,,,,,,210,289' ] + racc_action_table = arr = ::Array.new(6523, 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,201,202,0,131,0,207,228,199,206,106,307,116,142,238,50,50,261,142', -'154,307,228,0,238,243,243,140,46,0,131,0,140,0,0,49,0,0,0,49,0,0,0,0', -'201,202,0,0,116,207,0,199,206,0,50,154,46,50,388,388,46,0,388,243,388', -'388,243,0,164,150,150,0,0,164,0,0,0,50,123,0,203,388,145,0,203,145,243', -'388,50,388,133,388,388,267,388,388,388,243,388,388,388,388,104,204,388', -'388,123,204,388,51,123,388,75,51,316,271,5,5,316,388,5,316,5,110,167', -'388,304,110,304,388,388,158,388,388,350,275,350,388,167,5,167,388,167', -'333,333,5,73,5,277,5,5,245,5,5,5,5,5,5,5,5,152,152,5,5,167,63,5,62,281', -'5,8,8,8,8,387,387,244,5,387,295,387,387,166,5,297,299,167,5,5,300,5', -'5,240,303,239,5,166,387,166,5,166,305,306,387,236,387,235,387,387,310', -'387,387,387,311,387,387,387,387,312,313,387,387,166,314,387,115,318', -'387,47,227,41,225,385,385,138,387,385,332,385,385,111,387,221,220,166', -'387,387,335,387,387,40,337,218,387,111,385,111,387,111,216,344,385,345', -'385,196,385,385,195,385,385,385,39,385,385,385,385,353,354,385,385,111', -'356,385,357,361,385,362,363,125,369,365,365,370,385,365,373,365,375', -'165,385,130,6,1,385,385,392,385,385,397,399,401,385,165,365,165,385', -'165,,,365,,365,,365,365,,365,365,365,,365,365,365,365,,,365,365,165', -',365,,,365,,,,,12,12,,365,12,,12,,109,365,,,,365,365,,365,365,,,,365', -'109,12,109,365,109,,,12,,12,,12,12,,12,12,12,,12,12,,,,,12,12,109,,12', -',,12,,,,,13,13,,12,13,,13,,,12,,,,12,12,,12,12,,,,12,,13,,12,,,,13,', -'13,,13,13,,13,13,13,,13,13,,,,,13,13,,,13,,,13,,,,,14,14,,13,14,,14', -',,13,,,,13,13,,13,13,,,,13,,14,,13,,,,14,,14,,14,14,,14,14,14,,14,14', -',,,,14,14,,,14,,,14,,,,,352,352,,14,352,,352,,,14,,,,14,14,,14,14,,', -',14,,352,,14,,,,352,,352,,352,352,,352,352,352,,352,352,,,,,352,352', -',,352,,,352,,,,,336,336,,352,336,,336,,,352,,,,352,352,,352,352,,,,352', -',336,,352,,,,336,,336,,336,336,,336,336,336,,336,336,,,,,336,336,,,336', -',,336,,,,,324,324,,336,324,,324,,,336,,,,336,336,,336,336,,,,336,,324', -',336,,,,324,,324,,324,324,,324,324,324,,324,324,324,324,,,324,324,,', -'324,,,324,,,,,42,42,,324,42,,42,,,324,,,,324,324,,324,324,,,,324,,42', -',324,,,,42,,42,,42,42,,42,42,42,,42,42,,,,,42,42,,,42,,,42,,,,,43,43', -',42,43,,43,,,42,,,,42,42,,42,42,,,,42,,43,,42,,,,43,,43,,43,43,,43,43', -'43,,43,43,,,,,43,43,,,43,,,43,,,,,44,44,,43,44,,44,,,43,,,,43,43,,43', -'43,,,,43,,44,,43,,,,44,,44,,44,44,,44,44,44,,44,44,,,,,44,44,,,44,,', -'44,,,,,45,45,,44,45,,45,,,44,,,,44,44,,44,44,,,,44,,45,,44,,,,45,,45', -',45,45,,45,45,45,,45,45,,,,,45,45,,,45,,,45,,,,,320,320,,45,320,,320', -'320,,45,,,,45,45,,45,45,,,,45,,320,,45,,,,320,,320,,320,320,,320,320', -'320,,320,320,320,320,,,320,320,,,320,,,320,,,,,319,319,,320,319,,319', -',,320,,,,320,320,,320,320,,,,320,,319,,320,,,,319,,319,,319,319,,319', -'319,319,,319,319,319,319,,,319,319,,,319,,,319,,,,,308,308,,319,308', -',308,308,,319,,,,319,319,,319,319,,,,319,,308,,319,,,,308,,308,,308', -'308,,308,308,308,,308,308,,,,,308,308,,,308,,,308,,,,,301,301,,308,301', -',301,,,308,,,,308,308,,308,308,,,,308,,301,,308,,,,301,,301,,301,301', -',301,301,301,,301,301,,,,,301,301,,,301,,,301,,,,,294,294,,301,294,', -'294,,,301,,,,301,301,,301,301,,,,301,,294,,301,,,,294,,294,,294,294', -',294,294,294,,294,294,,,,,294,294,,,294,,,294,,,,,53,53,,294,53,53,53', -',,294,,,,294,294,,294,294,,,,294,,53,,294,,,,53,,53,,53,53,,53,53,53', -',53,53,,,,,53,53,,,53,,,53,,,,,54,54,,53,54,54,54,,,53,,,,53,53,,53', -'53,,,,53,,54,,53,,,,54,,54,,54,54,,54,54,54,,54,54,,,,,54,54,,,54,,', -'54,,,,,55,55,,54,55,,55,55,,54,,,,54,54,,54,54,,,,54,,55,,54,,,,55,', -'55,,55,55,,55,55,55,,55,55,,,,,55,55,,,55,,,55,,,,,60,60,,55,60,,60', -',,55,,,,55,55,,55,55,,,,55,,60,,55,,,,60,,60,,60,60,,60,60,60,,60,60', -',,,,60,60,,,60,,,60,,,,,280,280,,60,280,,280,,,60,,,,60,60,,60,60,,', -',60,,280,,60,,,,280,,280,,280,280,,280,280,280,,280,280,,,,,280,280', -',,280,,,280,,,,,279,279,,280,279,,279,,,280,,,,280,280,,280,280,,,,280', -',279,,280,,,,279,,279,,279,279,,279,279,279,,279,279,,,,,279,279,,,279', -',,279,,,,,65,65,,279,65,,65,,,279,,,,279,279,,279,279,,,,279,,65,,279', -',,,65,,65,,65,65,,65,65,65,,65,65,,,,,65,65,,,65,,,65,,,,,276,276,,65', -'276,,276,,,65,,,,65,65,,65,65,,,,65,,276,,65,,,,276,,276,,276,276,,276', -'276,276,,276,276,,,,,276,276,,,276,,,276,,,,,153,153,,276,153,,153,', -',276,,,,276,276,,276,276,,,,276,,153,,276,,,,153,,153,,153,153,,153', -'153,153,,153,153,153,153,,,153,153,,,153,,,153,,,,,270,270,,153,270', -',270,,,153,,,,153,153,,153,153,,,,153,,270,,153,,,,270,,270,,270,270', -',270,270,270,,270,270,,,,,270,270,,,270,,,270,,,,,76,76,,270,76,,76', -',,270,,,,270,270,,270,270,,,,270,,76,,270,,,,76,,76,,76,76,,76,76,76', -',76,76,76,76,,,76,76,,,76,,,76,,,,,77,77,,76,77,,77,,,76,,,,76,76,,76', -'76,,,,76,,77,,76,,,,77,,77,,77,77,,77,77,77,,77,77,77,77,,,77,77,,,77', -',,77,,,,,78,78,,77,78,,78,,,77,,,,77,77,,77,77,,,,77,,78,,77,,,,78,', -'78,,78,78,,78,78,78,,78,78,78,78,,,78,78,,,78,,,78,,,,,79,79,,78,79', -',79,,,78,,,,78,78,,78,78,,,,78,,79,,78,,,,79,,79,,79,79,,79,79,79,,79', -'79,79,79,,,79,79,,,79,,,79,,,,,80,80,,79,80,,80,,,79,,,,79,79,,79,79', -',,,79,,80,,79,,,,80,,80,,80,80,,80,80,80,,80,80,80,80,,,80,80,,,80,', -',80,,,,,81,81,,80,81,,81,,,80,,,,80,80,,80,80,,,,80,,81,,80,,,,81,,81', -',81,81,,81,81,81,,81,81,,,,,81,81,,,81,,,81,,,,,82,82,,81,82,,82,,,81', -',,,81,81,,81,81,,,,81,,82,,81,,,,82,,82,,82,82,,82,82,82,,82,82,,,,', -'82,82,,,82,,,82,,,,,83,83,,82,83,,83,,,82,,,,82,82,,82,82,,,,82,,83', -',82,,,,83,,83,,83,83,,83,83,83,,83,83,,,,,83,83,,,83,,,83,,,,,84,84', -',83,84,,84,,,83,,,,83,83,,83,83,,,,83,,84,,83,,,,84,,84,,84,84,,84,84', -'84,,84,84,,,,,84,84,,,84,,,84,,,,,85,85,,84,85,,85,,,84,,,,84,84,,84', -'84,,,,84,,85,,84,,,,85,,85,,85,85,,85,85,85,,85,85,,,,,85,85,,,85,,', -'85,,,,,86,86,,85,86,,86,,,85,,,,85,85,,85,85,,,,85,,86,,85,,,,86,,86', -',86,86,,86,86,86,,86,86,,,,,86,86,,,86,,,86,,,,,87,87,,86,87,,87,,,86', -',,,86,86,,86,86,,,,86,,87,,86,,,,87,,87,,87,87,,87,87,87,,87,87,,,,', -'87,87,,,87,,,87,,,,,88,88,,87,88,,88,,,87,,,,87,87,,87,87,,,,87,,88', -',87,,,,88,,88,,88,88,,88,88,88,,88,88,,,,,88,88,,,88,,,88,,,,,89,89', -',88,89,,89,,,88,,,,88,88,,88,88,,,,88,,89,,88,,,,89,,89,,89,89,,89,89', -'89,,89,89,,,,,89,89,,,89,,,89,,,,,90,90,,89,90,,90,,,89,,,,89,89,,89', -'89,,,,89,,90,,89,,,,90,,90,,90,90,,90,90,90,,90,90,,,,,90,90,,,90,,', -'90,,,,,91,91,,90,91,,91,,,90,,,,90,90,,90,90,,,,90,,91,,90,,,,91,,91', -',91,91,,91,91,91,,91,91,,,,,91,91,,,91,,,91,,,,,92,92,,91,92,,92,,,91', -',,,91,91,,91,91,,,,91,,92,,91,,,,92,,92,,92,92,,92,92,92,,92,92,,,,', -'92,92,,,92,,,92,,,,,93,93,,92,93,,93,,,92,,,,92,92,,92,92,,,,92,,93', -',92,,,,93,,93,,93,93,,93,93,93,,93,93,,,,,93,93,,,93,,,93,,,,,94,94', -',93,94,,94,,,93,,,,93,93,,93,93,,,,93,,94,,93,,,,94,,94,,94,94,,94,94', -'94,,94,94,,,,,94,94,,,94,,,94,,,,,95,95,,94,95,,95,,,94,,,,94,94,,94', -'94,,,,94,,95,,94,,,,95,,95,,95,95,,95,95,95,,95,95,,,,,95,95,,,95,,', -'95,,,,,96,96,,95,96,,96,,,95,,,,95,95,,95,95,,,,95,,96,,95,,,,96,,96', -',96,96,,96,96,96,,96,96,,,,,96,96,,,96,,,96,,,,,97,97,,96,97,,97,,,96', -',,,96,96,,96,96,,,,96,,97,,96,,,,97,,97,,97,97,,97,97,97,,97,97,,,,', -'97,97,,,97,,,97,,,,,98,98,,97,98,,98,,,97,,,,97,97,,97,97,,,,97,,98', -',97,,,,98,,98,,98,98,,98,98,98,,98,98,,,,,98,98,,,98,,,98,,,,,99,99', -',98,99,,99,,,98,,,,98,98,,98,98,,,,98,,99,,98,,,,99,,99,,99,99,,99,99', -'99,,99,99,,,,,99,99,,,99,,,99,,,,,100,100,,99,100,,100,,,99,,,,99,99', -',99,99,,,,99,,100,,99,,,,100,,100,,100,100,,100,100,100,,100,100,,,', -',100,100,,,100,,,100,,,,,101,101,,100,101,,101,,,100,,,,100,100,,100', -'100,,,,100,,101,,100,,,,101,,101,,101,101,,101,101,101,,101,101,,,,', -'101,101,,,101,,,101,,,,,102,102,,101,102,,102,,,101,,,,101,101,,101', -'101,,,,101,,102,,101,,,,102,,102,,102,102,,102,102,102,,102,102,,,,', -'102,102,,,102,,,102,,,,,103,103,,102,103,,103,,,102,,,,102,102,,102', -'102,,,,102,,103,,102,,,,103,,103,,103,103,,103,103,103,,103,103,,,,', -'103,103,,,103,,,103,,,,,269,269,,103,269,,269,,,103,,,103,103,103,,103', -'103,,,,103,,269,,103,,,,269,,269,,269,269,,269,269,269,,269,269,,,,', -'269,269,,,269,,,269,,,,,105,105,,269,105,,105,,,269,,,,269,269,,269', -'269,,,,269,,105,,269,,,,105,105,105,105,105,105,105,105,105,105,,105', -'105,,,,,105,105,105,105,105,,,105,,,,,257,257,,105,257,,257,,105,105', -',,,105,105,,105,105,,,,105,,257,,105,,,,257,,257,,257,257,,257,257,257', -',257,257,,,,,257,257,,,257,,,257,,,,,107,107,,257,107,,107,,,257,,,', -'257,257,,257,257,,,,257,,107,,257,,,,107,,107,,107,107,,107,107,107', -',107,107,,,,,107,107,,,107,,,107,,,,,108,108,,107,108,,108,,,107,,,', -'107,107,,107,107,,,,107,,108,,107,,,,108,,108,,108,108,,108,108,108', -',108,108,,,,,108,108,,,108,,,108,,,,,252,252,,108,252,,252,252,,108', -',,,108,108,,108,108,,,,108,,252,,108,,,,252,,252,,252,252,,252,252,252', -',252,252,,,,,252,252,,,252,,,252,,,,,250,250,,252,250,,250,,,252,,,', -'252,252,,252,252,,,,252,,250,,252,,,,250,,250,,250,250,,250,250,250', -',250,250,,,,,250,250,,,250,,,250,,,,,248,248,,250,248,248,248,,,250', -',,,250,250,,250,250,,,,250,,248,,250,,,,248,,248,,248,248,,248,248,248', -',248,248,,,,,248,248,,,248,,,248,,,,,246,246,,248,246,246,246,,,248', -',,,248,248,,248,248,,,,248,,246,,248,,,,246,,246,,246,246,,246,246,246', -',246,246,,,,,246,246,,,246,,,246,,,,,113,113,,246,113,,113,,,246,,,', -'246,246,,246,246,,,,246,,113,113,246,,,,113,,113,,113,113,,113,113,113', -',113,113,,,,,113,113,,,113,,,113,,,,,234,234,,113,234,,234,,,113,,,', -'113,113,,113,113,,,,113,,234,,113,,,,234,,234,,234,234,,234,234,234', -',234,234,,,,,234,234,,,234,,,234,,,,,233,233,,234,233,,233,,,234,,,', -'234,234,,234,234,,,,234,,233,,234,,,,233,233,233,233,233,233,233,233', -'233,233,,233,233,,,,,233,233,233,233,233,,,233,,,,,117,117,,233,117', -',117,,233,233,,,,233,233,,233,233,,,,233,,117,117,233,,,,117,,117,,117', -'117,,117,117,117,,117,117,,,,,117,117,,,117,,,117,,,,,232,232,,117,232', -',232,,,117,,,,117,117,,117,117,,,,117,,232,,117,,,,232,,232,,232,232', -',232,232,232,,232,232,,,,,232,232,,,232,,,232,,,,,231,231,,232,231,', -'231,231,,232,,,,232,232,,232,232,,,,232,,231,,232,,,,231,,231,,231,231', -',231,231,231,,231,231,231,231,,,231,231,,,231,,,231,,,,,230,230,,231', -'230,,230,230,,231,,,,231,231,,231,231,,,,231,,230,,231,,,,230,,230,', -'230,230,,230,230,230,,230,230,230,230,,,230,230,,,230,,,230,,,,,223', -'223,,230,223,,223,223,,230,,,,230,230,,230,230,,,,230,,223,,230,,,,223', -',223,,223,223,,223,223,223,,223,223,223,223,,,223,223,,,223,,,223,,', -',,194,194,,223,194,,194,,,223,,,,223,223,,223,223,,,,223,,194,,223,', -',,194,,194,,194,194,,194,194,194,,194,194,,,,,194,194,,,194,,,194,,', -',,124,124,,194,124,,124,,,194,,,,194,194,,194,194,,,,194,,124,,194,', -',,124,,124,,124,124,,124,124,124,,124,124,,,,,124,124,,,124,,,124,,', -',,193,193,,124,193,,193,,,124,,,,124,124,,124,124,,,,124,,193,,124,', -',,193,,193,,193,193,,193,193,193,,193,193,,,,,193,193,,,193,,,193,,', -',,192,192,,193,192,,192,,,193,,,,193,193,,193,193,,,,193,,192,,193,', -',,192,,192,,192,192,,192,192,192,,192,192,,,,,192,192,,,192,,,192,,', -',,189,189,,192,189,,189,,,192,,,,192,192,,192,192,,,,192,,189,,192,', -',,189,,189,,189,189,,189,189,189,,189,189,,,,,189,189,,,189,,,189,,', -',,156,156,,189,156,,156,156,,189,,,,189,189,,189,189,,,,189,,156,,189', -',,,156,,156,,156,156,,156,156,156,,156,156,156,156,,,156,156,,,156,', -',156,,,,,74,74,,156,74,,74,,,156,,,,156,156,,156,156,,205,205,156,,74', -',156,,,,74,,74,,74,74,,74,74,74,,74,74,74,74,,,74,74,,,74,,,74,,,,205', -',,205,74,,,,,,74,,241,241,74,74,,74,74,139,,,74,205,,,74,,139,139,139', -'139,139,139,205,139,,139,,,139,139,139,139,,,,,,,241,,,241,,,,,,139', -',,,139,139,,,139,139,139,139,139,139,241,139,139,,,,,11,139,11,,241', -',,,,11,11,11,11,11,11,,11,,11,139,,11,11,11,11,,,,,,,,,,,,,,,,11,,,', -'11,11,,,11,11,11,11,11,11,349,11,11,,,,,,11,349,349,349,349,349,349', -',349,,349,,,349,349,349,349,,11,,,,,,,,,,,,,,349,,,,349,349,,,349,349', -'349,349,349,349,144,349,349,,,144,,,349,144,144,144,144,144,144,,144', -',144,,,144,144,144,144,,349,,,,,,,,,,,,,,144,,,,144,144,,,144,144,144', -'144,144,144,343,144,144,,,,,,144,343,343,343,343,343,343,,343,,343,', -',343,343,343,343,,144,,,,,,,,,,,,,,343,,,,343,343,,,343,343,343,343', -'343,343,148,343,343,,,,,,343,148,148,148,148,148,148,,148,,148,,,148', -'148,148,148,,343,,,,,,,,,,,,,,148,,,,148,148,,,148,148,148,148,148,148', -'342,148,148,,,,,,148,342,342,342,342,342,342,,342,,342,,,342,342,342', -'342,,148,,,,,,,,,,,,,,342,,,,342,342,,,342,342,342,342,342,342,334,342', -'342,,,,,,342,334,334,334,334,334,334,,334,,334,,,334,334,334,334,,342', -',,,,,,,,,,,,,334,,,,334,334,,,334,334,334,334,334,334,328,334,334,,', -',,,334,328,328,328,328,328,328,,328,,328,,,328,328,328,328,,334,,,,', -',,,,,,,,,328,,,,328,328,,,328,328,328,328,328,328,325,328,328,,,,,,328', -'325,325,325,325,325,325,,325,,325,,,325,325,325,325,,328,,,,,,,,,,,', -',,325,,,,325,325,,,325,325,325,325,325,325,155,325,325,,,,,,325,155', -'155,155,155,155,155,,155,,155,,,155,155,155,155,,325,,,,,,,,,,,,,,155', -',,,155,155,,,155,155,155,155,155,155,,155,155,,,,,,155,,,,,,,,,,,155', -'155,,266,,266,,155,266,,,,266,266,266,266,266,266,,266,,266,,,266,266', -'266,266,,,,,,,,,,,,,,,,266,,,,266,266,,,266,266,266,266,266,266,112', -'266,266,,,,,,266,112,112,112,112,112,112,,112,,112,,112,112,112,112', -'112,,266,,,,,,,,,,,,,,112,,,,112,112,,,112,112,112,112,112,112,,112', -'112,,,,,118,112,118,,,,,,,118,118,118,118,118,118,,118,,118,112,,118', -'118,118,118,,,,,,,,,,,,,,,,118,,,,118,118,,,118,118,118,118,118,118', -',118,118,,,,,120,118,120,,,,,,,120,120,120,120,120,120,,120,,120,118', -',120,120,120,120,,,,,,,,,,,,,,,,120,,,,120,120,,,120,120,120,120,120', -'120,,120,120,,,,,121,120,121,,,,,,,121,121,121,121,121,121,,121,,121', -'120,,121,121,121,121,,,,,,,,,,,,,,,,121,,,,121,121,,,121,121,121,121', -'121,121,,121,121,,,,,122,121,122,,,,,,,122,122,122,122,122,122,,122', -'168,122,121,169,122,122,122,122,,,,,,,168,,168,169,168,169,,169,,122', -',,,122,122,,,122,122,122,122,122,122,,122,122,168,,,169,,122,,,,,168', -'168,173,169,169,168,168,,169,169,,,168,122,,169,173,,173,,173,,,,,215', -',,,,168,,,169,215,215,215,215,215,215,,215,173,215,,,215,215,215,215', -'173,173,173,173,,,,173,173,,,,,,173,215,,,,215,215,,,215,215,215,215', -'215,215,185,215,215,173,,,,,215,185,185,185,185,185,185,,185,,185,,', -'185,185,185,185,,215,,,,,,,,,,,,,,185,,,,185,185,,,185,185,185,185,185', -'185,186,185,185,,,186,,,185,186,186,186,186,186,186,,186,174,186,,,186', -'186,186,186,,185,,,,,174,,174,,174,,,,,186,,,,186,186,,,186,186,186', -'186,186,186,,186,186,174,,,175,,186,,,174,174,174,174,,,,174,174,175', -',175,176,175,174,186,,,,,,,,,,,176,,176,,176,,174,,,175,,,,,,,,175,175', -'175,175,175,175,,175,175,176,,,,,175,,,176,176,176,176,176,176,177,176', -'176,,,,,,176,175,,,,177,177,,177,178,177,,,177,,,,,176,,,,178,178,,178', -',178,,,178,,177,,,,,,,,177,177,177,177,177,177,,177,177,178,,,,,177', -',,178,178,178,178,178,178,179,178,178,,,,,,178,177,,,,179,179,,179,180', -'179,,,179,,,,,178,,,,180,180,,180,,180,,,180,,179,,,,,,,,179,179,179', -'179,179,179,,179,179,180,,,,,179,,,180,180,180,180,180,180,181,180,180', -',,,,,180,179,,,181,181,181,,181,,181,,182,181,181,181,181,,180,,,,,', -'182,182,182,,182,,182,,181,182,182,182,182,,,,181,181,181,181,181,181', -',181,181,,,,182,,181,,,182,,,182,182,182,182,182,182,183,182,182,,,', -'181,,182,183,183,183,183,183,183,,183,,183,,,183,183,183,183,,182,,', -',,,,,,,,,,,183,,,,183,183,,,183,183,183,183,183,183,184,183,183,,,,', -',183,184,184,184,184,184,184,,184,,184,,,184,184,184,184,,183,,,,,,', -',,,,,,,184,,,,184,184,,,184,184,184,184,184,184,191,184,184,,,,,,184', -'191,191,191,191,191,191,191,191,171,191,,170,191,191,191,191,,184,,', -',,171,,171,170,171,170,,170,,191,,,,191,191,,172,191,191,191,191,191', -'191,,191,191,171,,,170,172,191,172,,172,,,,,,,171,171,,170,170,,,171', -'191,,170,,,,,172,,,,,,,,,,,,,,,172,172,,214,214,214,214,172,214,214', -'214,214,214,,214,214,,,,,,,214,214,214,273,273,273,273,,273,273,273', -'273,273,,273,273,,,214,214,,,273,273,273,278,278,278,278,,278,278,278', -'278,278,,278,278,,,273,273,,,278,278,278,,,,,,,,,,,,,,,,278,278' ] - racc_action_check = arr = ::Array.new(6596, nil) +'0,0,201,198,0,131,0,206,227,200,205,312,237,153,141,305,242,242,125', +'141,116,237,227,0,305,240,240,139,123,0,131,0,139,0,0,203,0,0,0,203', +'0,0,0,0,201,198,0,0,153,206,0,200,205,0,242,116,123,242,384,384,123', +'0,384,240,384,384,240,0,163,330,330,0,0,163,0,0,0,242,46,0,49,384,144', +'0,49,144,240,384,242,384,265,384,384,239,384,384,384,240,384,384,384', +'384,130,202,384,384,46,202,384,110,46,384,269,110,314,234,5,5,314,384', +'5,314,5,273,165,384,347,115,347,384,384,275,384,384,302,157,302,384', +'165,5,165,384,165,151,151,5,226,5,224,5,5,279,5,5,5,5,5,5,5,5,149,149', +'5,5,165,220,5,293,295,5,8,8,8,8,383,383,297,5,383,298,383,383,166,5', +'106,301,165,5,5,133,5,5,303,304,219,5,166,383,166,5,166,104,308,383', +'309,383,310,383,383,311,383,383,383,259,383,383,383,383,217,316,383', +'383,166,75,383,73,63,383,62,329,235,215,381,381,332,383,381,195,381', +'381,164,383,334,47,166,383,383,194,383,383,341,342,41,383,164,381,164', +'383,164,238,40,381,350,381,351,381,381,353,381,381,381,354,381,381,381', +'381,358,359,381,381,164,360,381,39,366,381,367,370,243,6,188,188,1,381', +'188,388,188,392,111,381,394,396,,381,381,,381,381,,,,381,111,188,111', +'381,111,,,188,,188,,188,188,,188,188,188,,188,188,,,,,188,188,111,,188', +',,188,,,,,12,12,,188,12,,12,,109,188,,,,188,188,,188,188,,,,188,109', +'12,109,188,109,,,12,,12,,12,12,,12,12,12,,12,12,,,,,12,12,109,,12,,', +'12,,,,,13,13,,12,13,,13,,,12,,,,12,12,,12,12,,,,12,,13,,12,,,,13,,13', +',13,13,,13,13,13,,13,13,,,,,13,13,,,13,,,13,,,,,14,14,,13,14,,14,,,13', +',,,13,13,,13,13,,,,13,,14,,13,,,,14,,14,,14,14,,14,14,14,,14,14,,,,', +'14,14,,,14,,,14,,,,,362,362,,14,362,,362,,,14,,,,14,14,,14,14,,,,14', +',362,,14,,,,362,,362,,362,362,,362,362,362,,362,362,362,362,,,362,362', +',,362,,,362,,,,,349,349,,362,349,,349,,,362,,,,362,362,,362,362,,,,362', +',349,,362,,,,349,,349,,349,349,,349,349,349,,349,349,,,,,349,349,,,349', +',,349,,,,,191,191,,349,191,,191,,,349,,,,349,349,,349,349,,,,349,,191', +',349,,,,191,,191,,191,191,,191,191,191,,191,191,,,,,191,191,,,191,,', +'191,,,,,42,42,,191,42,,42,,,191,,,,191,191,,191,191,,,,191,,42,,191', +',,,42,,42,,42,42,,42,42,42,,42,42,,,,,42,42,,,42,,,42,,,,,43,43,,42', +'43,,43,,,42,,,,42,42,,42,42,,,,42,,43,,42,,,,43,,43,,43,43,,43,43,43', +',43,43,,,,,43,43,,,43,,,43,,,,,44,44,,43,44,,44,,,43,,,,43,43,,43,43', +',,,43,,44,,43,,,,44,,44,,44,44,,44,44,44,,44,44,,,,,44,44,,,44,,,44', +',,,,45,45,,44,45,,45,,,44,,,,44,44,,44,44,,,,44,,45,,44,,,,45,,45,,45', +'45,,45,45,45,,45,45,,,,,45,45,,,45,,,45,,,,,192,192,,45,192,,192,,,45', +',,,45,45,,45,45,,,,45,,192,,45,,,,192,,192,,192,192,,192,192,192,,192', +'192,,,,,192,192,,,192,,,192,,,,,193,193,,192,193,,193,,,192,,,,192,192', +',192,192,,,,192,,193,,192,,,,193,,193,,193,193,,193,193,193,,193,193', +',,,,193,193,,,193,,,193,,,,,333,333,,193,333,,333,,,193,,,,193,193,', +'193,193,,,,193,,333,,193,,,,333,,333,,333,333,,333,333,333,,333,333', +',,,,333,333,,,333,,,333,,,,,222,222,,333,222,,222,222,,333,,,,333,333', +',333,333,,,,333,,222,,333,,,,222,,222,,222,222,,222,222,222,,222,222', +'222,222,,,222,222,,,222,,,222,,,,,53,53,,222,53,53,53,,,222,,,,222,222', +',222,222,,,,222,,53,,222,,,,53,,53,,53,53,,53,53,53,,53,53,,,,,53,53', +',,53,,,53,,,,,54,54,,53,54,54,54,,,53,,,,53,53,,53,53,,,,53,,54,,53', +',,,54,,54,,54,54,,54,54,54,,54,54,,,,,54,54,,,54,,,54,,,,,55,55,,54', +'55,,55,55,,54,,,,54,54,,54,54,,,,54,,55,,54,,,,55,,55,,55,55,,55,55', +'55,,55,55,,,,,55,55,,,55,,,55,,,,,60,60,,55,60,,60,,,55,,,,55,55,,55', +'55,,,,55,,60,,55,,,,60,,60,,60,60,,60,60,60,,60,60,,,,,60,60,,,60,,', +'60,,,,,229,229,,60,229,,229,229,,60,,,,60,60,,60,60,,,,60,,229,,60,', +',,229,,229,,229,229,,229,229,229,,229,229,229,229,,,229,229,,,229,,', +'229,,,,,155,155,,229,155,,155,155,,229,,,,229,229,,229,229,,,,229,,155', +',229,,,,155,,155,,155,155,,155,155,155,,155,155,155,155,,,155,155,,', +'155,,,155,,,,,65,65,,155,65,,65,,,155,,,,155,155,,155,155,,,,155,,65', +',155,,,,65,,65,,65,65,,65,65,65,,65,65,,,,,65,65,,,65,,,65,,,,,318,318', +',65,318,,318,318,,65,,,,65,65,,65,65,,,,65,,318,,65,,,,318,,318,,318', +'318,,318,318,318,,318,318,318,318,,,318,318,,,318,,,318,,,,,74,74,,318', +'74,,74,,,318,,,,318,318,,318,318,,,,318,,74,,318,,,,74,,74,,74,74,,74', +'74,74,,74,74,74,74,,,74,74,,,74,,,74,,,,,317,317,,74,317,,317,,,74,', +',,74,74,,74,74,,,,74,,317,,74,,,,317,,317,,317,317,,317,317,317,,317', +'317,317,317,,,317,317,,,317,,,317,,,,,76,76,,317,76,,76,,,317,,,,317', +'317,,317,317,,,,317,,76,,317,,,,76,,76,,76,76,,76,76,76,,76,76,76,76', +',,76,76,,,76,,,76,,,,,77,77,,76,77,,77,,,76,,,,76,76,,76,76,,,,76,,77', +',76,,,,77,,77,,77,77,,77,77,77,,77,77,77,77,,,77,77,,,77,,,77,,,,,78', +'78,,77,78,,78,,,77,,,,77,77,,77,77,,,,77,,78,,77,,,,78,,78,,78,78,,78', +'78,78,,78,78,78,78,,,78,78,,,78,,,78,,,,,79,79,,78,79,,79,,,78,,,,78', +'78,,78,78,,,,78,,79,,78,,,,79,,79,,79,79,,79,79,79,,79,79,79,79,,,79', +'79,,,79,,,79,,,,,80,80,,79,80,,80,,,79,,,,79,79,,79,79,,,,79,,80,,79', +',,,80,,80,,80,80,,80,80,80,,80,80,80,80,,,80,80,,,80,,,80,,,,,81,81', +',80,81,,81,,,80,,,,80,80,,80,80,,,,80,,81,,80,,,,81,,81,,81,81,,81,81', +'81,,81,81,,,,,81,81,,,81,,,81,,,,,82,82,,81,82,,82,,,81,,,,81,81,,81', +'81,,,,81,,82,,81,,,,82,,82,,82,82,,82,82,82,,82,82,,,,,82,82,,,82,,', +'82,,,,,83,83,,82,83,,83,,,82,,,,82,82,,82,82,,,,82,,83,,82,,,,83,,83', +',83,83,,83,83,83,,83,83,,,,,83,83,,,83,,,83,,,,,84,84,,83,84,,84,,,83', +',,,83,83,,83,83,,,,83,,84,,83,,,,84,,84,,84,84,,84,84,84,,84,84,,,,', +'84,84,,,84,,,84,,,,,85,85,,84,85,,85,,,84,,,,84,84,,84,84,,,,84,,85', +',84,,,,85,,85,,85,85,,85,85,85,,85,85,,,,,85,85,,,85,,,85,,,,,86,86', +',85,86,,86,,,85,,,,85,85,,85,85,,,,85,,86,,85,,,,86,,86,,86,86,,86,86', +'86,,86,86,,,,,86,86,,,86,,,86,,,,,87,87,,86,87,,87,,,86,,,,86,86,,86', +'86,,,,86,,87,,86,,,,87,,87,,87,87,,87,87,87,,87,87,,,,,87,87,,,87,,', +'87,,,,,88,88,,87,88,,88,,,87,,,,87,87,,87,87,,,,87,,88,,87,,,,88,,88', +',88,88,,88,88,88,,88,88,,,,,88,88,,,88,,,88,,,,,89,89,,88,89,,89,,,88', +',,,88,88,,88,88,,,,88,,89,,88,,,,89,,89,,89,89,,89,89,89,,89,89,,,,', +'89,89,,,89,,,89,,,,,90,90,,89,90,,90,,,89,,,,89,89,,89,89,,,,89,,90', +',89,,,,90,,90,,90,90,,90,90,90,,90,90,,,,,90,90,,,90,,,90,,,,,91,91', +',90,91,,91,,,90,,,,90,90,,90,90,,,,90,,91,,90,,,,91,,91,,91,91,,91,91', +'91,,91,91,,,,,91,91,,,91,,,91,,,,,92,92,,91,92,,92,,,91,,,,91,91,,91', +'91,,,,91,,92,,91,,,,92,,92,,92,92,,92,92,92,,92,92,,,,,92,92,,,92,,', +'92,,,,,93,93,,92,93,,93,,,92,,,,92,92,,92,92,,,,92,,93,,92,,,,93,,93', +',93,93,,93,93,93,,93,93,,,,,93,93,,,93,,,93,,,,,94,94,,93,94,,94,,,93', +',,,93,93,,93,93,,,,93,,94,,93,,,,94,,94,,94,94,,94,94,94,,94,94,,,,', +'94,94,,,94,,,94,,,,,95,95,,94,95,,95,,,94,,,,94,94,,94,94,,,,94,,95', +',94,,,,95,,95,,95,95,,95,95,95,,95,95,,,,,95,95,,,95,,,95,,,,,96,96', +',95,96,,96,,,95,,,,95,95,,95,95,,,,95,,96,,95,,,,96,,96,,96,96,,96,96', +'96,,96,96,,,,,96,96,,,96,,,96,,,,,97,97,,96,97,,97,,,96,,,,96,96,,96', +'96,,,,96,,97,,96,,,,97,,97,,97,97,,97,97,97,,97,97,,,,,97,97,,,97,,', +'97,,,,,98,98,,97,98,,98,,,97,,,,97,97,,97,97,,,,97,,98,,97,,,,98,,98', +',98,98,,98,98,98,,98,98,,,,,98,98,,,98,,,98,,,,,99,99,,98,99,,99,,,98', +',,,98,98,,98,98,,,,98,,99,,98,,,,99,,99,,99,99,,99,99,99,,99,99,,,,', +'99,99,,,99,,,99,,,,,100,100,,99,100,,100,,,99,,,,99,99,,99,99,,,,99', +',100,,99,,,,100,,100,,100,100,,100,100,100,,100,100,,,,,100,100,,,100', +',,100,,,,,101,101,,100,101,,101,,,100,,,,100,100,,100,100,,,,100,,101', +',100,,,,101,,101,,101,101,,101,101,101,,101,101,,,,,101,101,,,101,,', +'101,,,,,102,102,,101,102,,102,,,101,,,,101,101,,101,101,,,,101,,102', +',101,,,,102,,102,,102,102,,102,102,102,,102,102,,,,,102,102,,,102,,', +'102,,,,,103,103,,102,103,,103,,,102,,,,102,102,,102,102,,,,102,,103', +',102,,,,103,,103,,103,103,,103,103,103,,103,103,,,,,103,103,,,103,,', +'103,,,,,306,306,,103,306,,306,306,,103,,,103,103,103,,103,103,,,,103', +',306,,103,,,,306,,306,,306,306,,306,306,306,,306,306,,,,,306,306,,,306', +',,306,,,,,105,105,,306,105,,105,,,306,,,,306,306,,306,306,,,,306,,105', +',306,,,,105,105,105,105,105,105,105,105,105,105,,105,105,,,,,105,105', +'105,105,105,,,105,,,,,299,299,,105,299,,299,,105,105,,,,105,105,,105', +'105,,,,105,,299,,105,,,,299,,299,,299,299,,299,299,299,,299,299,,,,', +'299,299,,,299,,,299,,,,,107,107,,299,107,,107,,,299,,,,299,299,,299', +'299,,,,299,,107,,299,,,,107,,107,,107,107,,107,107,107,,107,107,,,,', +'107,107,,,107,,,107,,,,,108,108,,107,108,,108,,,107,,,,107,107,,107', +'107,,,,107,,108,,107,,,,108,,108,,108,108,,108,108,108,,108,108,,,,', +'108,108,,,108,,,108,,,,,292,292,,108,292,,292,,,108,,,,108,108,,108', +'108,,,,108,,292,,108,,,,292,,292,,292,292,,292,292,292,,292,292,,,,', +'292,292,,,292,,,292,,,,,278,278,,292,278,,278,,,292,,,,292,292,,292', +'292,,,,292,,278,,292,,,,278,,278,,278,278,,278,278,278,,278,278,,,,', +'278,278,,,278,,,278,,,,,277,277,,278,277,,277,,,278,,,,278,278,,278', +'278,,,,278,,277,,278,,,,277,,277,,277,277,,277,277,277,,277,277,,,,', +'277,277,,,277,,,277,,,,,230,230,,277,230,,230,230,,277,,,,277,277,,277', +'277,,,,277,,230,,277,,,,230,,230,,230,230,,230,230,230,,230,230,230', +'230,,,230,230,,,230,,,230,,,,,113,113,,230,113,,113,,,230,,,,230,230', +',230,230,,,,230,,113,113,230,,,,113,,113,,113,113,,113,113,113,,113', +'113,,,,,113,113,,,113,,,113,,,,,274,274,,113,274,,274,,,113,,,,113,113', +',113,113,,,,113,,274,,113,,,,274,,274,,274,274,,274,274,274,,274,274', +',,,,274,274,,,274,,,274,,,,,268,268,,274,268,,268,,,274,,,,274,274,', +'274,274,,,,274,,268,,274,,,,268,,268,,268,268,,268,268,268,,268,268', +',,,,268,268,,,268,,,268,,,,,117,117,,268,117,,117,,,268,,,,268,268,', +'268,268,,,,268,,117,117,268,,,,117,,117,,117,117,,117,117,117,,117,117', +',,,,117,117,,,117,,,117,,,,,152,152,,117,152,,152,,,117,,,,117,117,', +'117,117,,,,117,,152,,117,,,,152,,152,,152,152,,152,152,152,,152,152', +'152,152,,,152,152,,,152,,,152,,,,,231,231,,152,231,,231,,,152,,,,152', +'152,,152,152,,,,152,,231,,152,,,,231,,231,,231,231,,231,231,231,,231', +'231,,,,,231,231,,,231,,,231,,,,,246,246,,231,246,246,246,,,231,,,,231', +'231,,231,231,,,,231,,246,,231,,,,246,,246,,246,246,,246,246,246,,246', +'246,,,,,246,246,,,246,,,246,,,,,233,233,,246,233,,233,,,246,,,,246,246', +',246,246,,,,246,,233,,246,,,,233,,233,,233,233,,233,233,233,,233,233', +',,,,233,233,,,233,,,233,,,,,267,267,,233,267,,267,,,233,,,,233,233,', +'233,233,,,,233,,267,,233,,,,267,,267,,267,267,,267,267,267,,267,267', +',,,,267,267,,,267,,,267,,,,,124,124,,267,124,,124,,,267,,,,267,267,', +'267,267,,,,267,,124,,267,,,,124,,124,,124,124,,124,124,124,,124,124', +',,,,124,124,,,124,,,124,,,,,244,244,,124,244,244,244,,,124,,,,124,124', +',124,124,,,,124,,244,,124,,,,244,,244,,244,244,,244,244,244,,244,244', +',,,,244,244,,,244,,,244,,,,,255,255,,244,255,,255,,,244,,,,244,244,', +'244,244,,,,244,,255,,244,,,,255,,255,,255,255,,255,255,255,,255,255', +',,,,255,255,,,255,,,255,,,,,250,250,,255,250,,250,250,,255,,,,255,255', +',255,255,,,,255,,250,,255,,,,250,,250,,250,250,,250,250,250,,250,250', +',,,,250,250,,,250,,,250,,,,,248,248,,250,248,,248,,,250,,,,250,250,', +'250,250,,,,250,,248,,250,,,,248,,248,,248,248,,248,248,248,,248,248', +',,,,248,248,,,248,,,248,,,,,232,232,,248,232,,232,,,248,,,,248,248,', +'248,248,,204,204,248,,232,,248,,,,232,232,232,232,232,232,232,232,232', +'232,,232,232,,50,50,,232,232,232,232,232,,,232,,,,204,,,204,232,,,,', +'232,232,,,,232,232,,232,232,138,,,232,204,50,,232,50,138,138,138,138', +'138,138,204,138,,138,,,138,138,138,138,,,,50,,,,,,,,,,,50,138,,,,138', +'138,,,138,138,138,138,138,138,,138,138,,,,,264,138,264,,,264,,,,264', +'264,264,264,264,264,,264,,264,138,,264,264,264,264,,,,,,,,,,,,,,,,264', +',,,264,264,,,264,264,264,264,264,264,143,264,264,,,143,,,264,143,143', +'143,143,143,143,,143,,143,,,143,143,143,143,,264,,,,,,,,,,,,,,143,,', +',143,143,,,143,143,143,143,143,143,,143,143,,,,,122,143,122,,,,,,,122', +'122,122,122,122,122,,122,,122,143,,122,122,122,122,,,,,,,,,,,,,,,,122', +',,,122,122,,,122,122,122,122,122,122,147,122,122,,,,,,122,147,147,147', +'147,147,147,,147,,147,,,147,147,147,147,,122,,,,,,,,,,,,,,147,,,,147', +'147,,,147,147,147,147,147,147,,147,147,,,,,121,147,121,,,,,,,121,121', +'121,121,121,121,,121,,121,147,,121,121,121,121,,,,,,,,,,,,,,,,121,,', +',121,121,,,121,121,121,121,121,121,,121,121,,,,,120,121,120,,,,,,,120', +'120,120,120,120,120,,120,,120,121,,120,120,120,120,,,,,,,,,,,,,,,,120', +',,,120,120,,,120,120,120,120,120,120,,120,120,,,,,118,120,118,,,,,,', +'118,118,118,118,118,118,,118,,118,120,,118,118,118,118,,,,,,,,,,,,,', +',,118,,,,118,118,,,118,118,118,118,118,118,112,118,118,,,,,,118,112', +'112,112,112,112,112,,112,,112,,112,112,112,112,112,,118,,,,,,,,,,,,', +',112,,,,112,112,,,112,112,112,112,112,112,154,112,112,,,,,,112,154,154', +'154,154,154,154,,154,,154,,,154,154,154,154,,112,,,,,,,,,,,,,,154,,', +',154,154,,,154,154,154,154,154,154,322,154,154,,,,,,154,322,322,322', +'322,322,322,,322,,322,154,154,322,322,322,322,,154,,,,,,,,,,,,,,322', +',,,322,322,,,322,322,322,322,322,322,325,322,322,,,,,,322,325,325,325', +'325,325,325,,325,,325,,,325,325,325,325,,322,,,,,,,,,,,,,,325,,,,325', +'325,,,325,325,325,325,325,325,331,325,325,,,,,,325,331,331,331,331,331', +'331,,331,,331,,,331,331,331,331,,325,,,,,,,,,,,,,,331,,,,331,331,,,331', +'331,331,331,331,331,214,331,331,,,,,,331,214,214,214,214,214,214,,214', +',214,,,214,214,214,214,,331,,,,,,,,,,,,,,214,,,,214,214,,,214,214,214', +'214,214,214,339,214,214,,,,,,214,339,339,339,339,339,339,,339,,339,', +',339,339,339,339,,214,,,,,,,,,,,,,,339,,,,339,339,,,339,339,339,339', +'339,339,340,339,339,,,,,,339,340,340,340,340,340,340,,340,167,340,,168', +'340,340,340,340,,339,,,,,167,,167,168,167,168,,168,,340,,,,340,340,', +',340,340,340,340,340,340,,340,340,167,,,168,,340,,,,,167,167,172,168', +'168,167,167,,168,168,,,167,340,,168,172,,172,,172,,,,,346,,,,,167,,', +'168,346,346,346,346,346,346,,346,172,346,,,346,346,346,346,172,172,172', +'172,,,,172,172,,,,,,172,346,,,,346,346,,,346,346,346,346,346,346,190', +'346,346,172,,,,,346,190,190,190,190,190,190,190,190,,190,,,190,190,190', +'190,,346,,,,,,,,,,,,,,190,,,,190,190,,,190,190,190,190,190,190,,190', +'190,,,,,11,190,11,,,,,,,11,11,11,11,11,11,,11,173,11,190,,11,11,11,11', +',,,,,,173,,173,,173,,,,,11,,,,11,11,,,11,11,11,11,11,11,,11,11,173,', +',174,,11,,,173,173,173,173,,,,173,173,174,,174,175,174,173,11,,,,,,', +',,,,175,,175,,175,,173,,,174,,,,,,,,174,174,174,174,174,174,,174,174', +'175,,,,,174,,,175,175,175,175,175,175,176,175,175,,,,,,175,174,,,,176', +'176,,176,177,176,,,176,,,,,175,,,,177,177,,177,,177,,,177,,176,,,,,', +',,176,176,176,176,176,176,,176,176,177,,,,,176,,,177,177,177,177,177', +'177,178,177,177,,,,,,177,176,,,,178,178,,178,179,178,,,178,,,,,177,', +',,179,179,,179,,179,,,179,,178,,,,,,,,178,178,178,178,178,178,,178,178', +'179,,,,,178,,,179,179,179,179,179,179,180,179,179,,,,,,179,178,,,180', +'180,180,,180,,180,,181,180,180,180,180,,179,,,,,,181,181,181,,181,,181', +',180,181,181,181,181,,,,180,180,180,180,180,180,,180,180,,,,181,,180', +',,181,,,181,181,181,181,181,181,182,181,181,,,,180,,181,182,182,182', +'182,182,182,,182,,182,,,182,182,182,182,,181,,,,,,,,,,,,,,182,,,,182', +'182,,,182,182,182,182,182,182,185,182,182,,,185,,,182,185,185,185,185', +'185,185,,185,,185,,,185,185,185,185,,182,,,,,,,,,,,,,,185,,,,185,185', +',,185,185,185,185,185,185,184,185,185,,,,,,185,184,184,184,184,184,184', +',184,,184,,,184,184,184,184,,185,,,,,,,,,,,,,,184,,,,184,184,,,184,184', +'184,184,184,184,183,184,184,,,,,,184,183,183,183,183,183,183,,183,170', +'183,,169,183,183,183,183,,184,,,,,170,,170,169,170,169,,169,,183,,,', +'183,183,,171,183,183,183,183,183,183,,183,183,170,,,169,171,183,171', +',171,,,,,,,170,170,,169,169,,,170,183,,169,,,,,171,,,,,,,,,,,,,,,171', +'171,,276,276,276,276,171,276,276,276,276,276,,276,276,,,,,,,276,276', +'276,271,271,271,271,,271,271,271,271,271,,271,271,,,276,276,,,271,271', +'271,213,213,213,213,,213,213,213,213,213,,213,213,,,271,271,,,213,213', +'213,,,,,,,,,,,,,,,,213,213' ] + racc_action_check = arr = ::Array.new(6523, 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, 302, nil, nil, nil, 114, 289, nil, 106, nil, - nil, 4887, 346, 404, 462, nil, nil, nil, nil, nil, + -2, 292, nil, nil, nil, 114, 277, nil, 106, nil, + nil, 5820, 346, 404, 462, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 258, + 190, 227, 694, 752, 810, 868, 70, 199, nil, 44, + 4739, nil, nil, 1158, 1216, 1274, nil, nil, nil, nil, + 1332, nil, 153, 156, nil, 1506, nil, nil, nil, nil, + nil, nil, nil, 225, 1622, 211, 1738, 1796, 1854, 1912, + 1970, 2028, 2086, 2144, 2202, 2260, 2318, 2376, 2434, 2492, + 2550, 2608, 2666, 2724, 2782, 2840, 2898, 2956, 3014, 3072, + 3130, 3188, 3246, 3304, 161, 3420, 176, 3536, 3594, 350, + 73, 292, 5235, 3884, nil, 119, -15, 4058, 5181, nil, + 5120, 5059, 4944, 20, 4406, -7, nil, nil, nil, nil, + 77, -7, nil, 169, nil, nil, nil, nil, 4768, 20, + nil, 7, nil, 4883, 73, nil, nil, 4998, nil, 156, + nil, 141, 4116, -22, 5289, 1448, nil, 123, nil, nil, + nil, nil, nil, 61, 234, 118, 176, 5630, 5633, 6349, + 6346, 6376, 5682, 5837, 5880, 5897, 5951, 5968, 6022, 6039, + 6093, 6113, 6167, 6329, 6275, 6221, nil, nil, 288, nil, + 5759, 636, 926, 984, 206, 225, nil, nil, -8, nil, + -2, -9, 67, -1, 4715, -1, -4, nil, nil, nil, + nil, nil, nil, 6453, 5505, 184, nil, 195, nil, 182, + 95, nil, 1100, nil, 136, nil, 131, -4, nil, 1390, + 3826, 4174, 4696, 4290, 74, 193, nil, -14, 251, 85, + 23, nil, 14, 248, 4464, nil, 4232, nil, 4638, nil, + 4580, nil, nil, nil, nil, 4522, nil, nil, nil, 201, + nil, nil, nil, nil, 4829, 81, nil, 4348, 4000, 100, + nil, 6431, nil, 114, 3942, 122, 6409, 3768, 3710, 139, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, - 180, 205, 694, 752, 810, 868, 20, 184, nil, -1, - 14, 73, nil, 1216, 1274, 1332, nil, nil, nil, nil, - 1390, nil, 92, 95, nil, 1564, nil, nil, nil, nil, - nil, nil, nil, 146, 4754, 100, 1796, 1854, 1912, 1970, - 2028, 2086, 2144, 2202, 2260, 2318, 2376, 2434, 2492, 2550, - 2608, 2666, 2724, 2782, 2840, 2898, 2956, 3014, 3072, 3130, - 3188, 3246, 3304, 3362, 62, 3478, 3, 3594, 3652, 350, - 87, 234, 5503, 3942, nil, 217, -22, 4116, 5564, nil, - 5625, 5686, 5747, 70, 4464, 263, nil, nil, nil, nil, - 275, -7, nil, 70, nil, nil, nil, nil, 209, 4826, - 20, nil, 7, nil, 4995, 73, nil, nil, 5103, nil, - 65, nil, 158, 1680, -15, 5373, 4696, nil, 119, nil, - nil, nil, nil, nil, 61, 292, 176, 118, 5764, 5767, - 6422, 6419, 6449, 5816, 5964, 6007, 6024, 6078, 6095, 6149, - 6166, 6220, 6240, 6294, 6348, 5893, 5947, nil, nil, 4638, - nil, 6402, 4580, 4522, 4406, 226, 252, nil, nil, -2, - nil, -9, -8, 44, 67, 4773, -1, -4, nil, nil, - nil, nil, nil, nil, 6482, 5839, 212, nil, 229, nil, - 231, 172, nil, 4348, nil, 219, nil, 214, -4, nil, - 4290, 4232, 4174, 4058, 4000, 165, 167, nil, -11, 186, - 184, 4823, nil, 23, 136, 143, 3884, nil, 3826, nil, - 3768, nil, 3710, nil, nil, nil, nil, 3536, nil, nil, - nil, 6, nil, nil, nil, nil, 5449, 84, nil, 3420, - 1738, 103, nil, 6504, nil, 126, 1622, 139, 6526, 1506, - 1448, 156, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 1158, 153, nil, 175, nil, 115, - 154, 1100, nil, 184, 94, 192, 170, 0, 1042, nil, - 168, 201, 177, 210, 215, nil, 78, nil, 214, 984, - 926, nil, nil, nil, 636, 5319, nil, nil, 5265, nil, - nil, nil, 167, 64, 5211, 238, 578, 239, nil, nil, - nil, nil, 5157, 5049, 251, 192, nil, nil, nil, 4941, - 102, nil, 520, 268, 245, nil, 273, 275, nil, nil, - nil, 275, 277, 278, nil, 288, nil, nil, nil, 263, - 283, nil, nil, 286, nil, 288, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 230, nil, 172, 56, nil, - nil, nil, 296, nil, nil, nil, nil, 299, nil, 300, - nil, 301, nil, nil, nil, nil, nil ] + nil, nil, 3652, 141, nil, 159, nil, 106, 144, 3478, + nil, 176, 102, 183, 161, 3, 3362, nil, 161, 192, + 165, 200, 3, nil, 78, nil, 207, 1680, 1564, nil, + nil, nil, 5343, nil, nil, 5397, nil, nil, nil, 159, + -10, 5451, 225, 1042, 230, nil, nil, nil, nil, 5559, + 5613, 241, 181, nil, nil, nil, 5705, 94, nil, 578, + 254, 232, nil, 259, 263, nil, nil, nil, 267, 268, + 272, nil, 520, nil, nil, nil, 258, 277, nil, nil, + 278, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, 172, 56, nil, nil, nil, 286, nil, + nil, nil, 288, nil, 291, nil, 292, nil, nil, nil, + nil, nil ] racc_action_default = [ -229, -230, -1, -2, -3, -4, -5, -8, -10, -11, -16, -108, -230, -230, -230, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -73, -74, -78, -230, -230, -230, -230, -230, -119, -121, -230, - -230, -230, -167, -230, -230, -230, -180, -181, -182, -183, + -230, -157, -167, -230, -230, -230, -180, -181, -182, -183, -230, -185, -230, -196, -199, -230, -204, -205, -206, -207, -208, -209, -210, -230, -230, -7, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -128, -123, -229, -229, -28, -230, -35, -230, -230, -75, -230, -230, -230, -230, -85, -230, -230, -230, -230, -230, -229, -138, -158, -159, -120, - -229, -229, -147, -149, -150, -151, -152, -153, -229, -43, - -230, -170, -230, -173, -230, -230, -176, -177, -189, -184, - -230, -192, -230, -230, -230, -230, -230, 407, -6, -9, - -12, -13, -14, -15, -230, -18, -19, -20, -21, -22, - -23, -24, -25, -26, -27, -29, -30, -31, -32, -33, - -34, -36, -37, -38, -39, -40, -230, -41, -103, -230, - -79, -230, -222, -228, -216, -213, -211, -117, -129, -205, - -132, -209, -230, -219, -217, -225, -207, -208, -215, -220, - -221, -223, -224, -226, -128, -127, -230, -126, -230, -42, - -211, -70, -80, -230, -83, -211, -163, -166, -230, -77, - -230, -230, -230, -128, -230, -213, -229, -160, -230, -230, - -230, -230, -155, -230, -230, -230, -230, -168, -230, -171, - -230, -174, -230, -186, -187, -188, -190, -230, -193, -194, - -195, -211, -197, -200, -202, -203, -108, -230, -17, -230, - -230, -211, -105, -128, -116, -230, -214, -230, -212, -230, - -230, -211, -131, -133, -216, -217, -218, -219, -222, -225, - -227, -228, -124, -125, -212, -230, -72, -230, -82, -230, - -212, -230, -76, -230, -88, -230, -94, -230, -230, -98, - -213, -211, -213, -230, -230, -141, -230, -161, -211, -229, - -230, -148, -156, -154, -229, -44, -169, -172, -179, -175, - -178, -191, -230, -230, -107, -230, -212, -211, -111, -118, - -112, -130, -134, -135, -230, -69, -81, -84, -164, -165, - -88, -87, -230, -230, -94, -93, -230, -230, -102, -97, - -99, -230, -230, -230, -114, -229, -142, -143, -144, -230, - -230, -139, -140, -230, -146, -230, -198, -201, -104, -106, - -115, -122, -71, -86, -89, -230, -92, -230, -230, -109, - -110, -113, -230, -162, -136, -145, -157, -230, -91, -230, - -96, -230, -101, -137, -90, -95, -100 ] + -229, -229, -147, -149, -150, -151, -152, -153, -43, -230, + -170, -230, -173, -230, -230, -176, -177, -189, -184, -230, + -192, -230, -230, -230, -230, -230, 402, -6, -9, -12, + -13, -14, -15, -230, -18, -19, -20, -21, -22, -23, + -24, -25, -26, -27, -29, -30, -31, -32, -33, -34, + -36, -37, -38, -39, -40, -230, -41, -103, -230, -79, + -230, -222, -228, -216, -213, -211, -117, -129, -205, -132, + -209, -230, -219, -217, -225, -207, -208, -215, -220, -221, + -223, -224, -226, -128, -127, -230, -126, -230, -42, -211, + -70, -80, -230, -83, -211, -163, -166, -230, -77, -230, + -230, -230, -128, -230, -213, -229, -160, -230, -230, -230, + -230, -155, -230, -230, -230, -168, -230, -171, -230, -174, + -230, -186, -187, -188, -190, -230, -193, -194, -195, -211, + -197, -200, -202, -203, -108, -230, -17, -230, -230, -211, + -105, -128, -116, -230, -214, -230, -212, -230, -230, -211, + -131, -133, -216, -217, -218, -219, -222, -225, -227, -228, + -124, -125, -212, -230, -72, -230, -82, -230, -212, -230, + -76, -230, -88, -230, -94, -230, -230, -98, -213, -211, + -213, -230, -230, -141, -230, -161, -211, -229, -230, -148, + -156, -154, -44, -169, -172, -179, -175, -178, -191, -230, + -230, -107, -230, -212, -211, -111, -118, -112, -130, -134, + -135, -230, -69, -81, -84, -164, -165, -88, -87, -230, + -230, -94, -93, -230, -230, -102, -97, -99, -230, -230, + -230, -114, -229, -142, -143, -144, -230, -230, -139, -140, + -230, -146, -198, -201, -104, -106, -115, -122, -71, -86, + -89, -230, -92, -230, -230, -109, -110, -113, -230, -162, + -136, -145, -230, -91, -230, -96, -230, -101, -137, -90, + -95, -100 ] racc_goto_table = [ - 2, 114, 4, 149, 136, 134, 109, 111, 112, 130, - 196, 138, 188, 263, 195, 225, 370, 275, 355, 351, - 187, 375, 236, 321, 309, 322, 159, 239, 160, 161, - 162, 163, 339, 235, 75, 245, 118, 120, 121, 122, - 277, 216, 218, 273, 140, 142, 357, 139, 139, 144, - 341, 271, 308, 261, 148, 384, 314, 313, 366, 155, - 240, 222, 392, 348, 295, 383, 386, 330, 258, 299, - 259, 3, 164, 256, 257, 139, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 272, 191, - 360, 215, 215, 158, 220, 332, 255, 139, 228, 217, - 217, 139, 151, 153, 1, 335, nil, nil, 191, 281, - nil, nil, nil, nil, nil, 344, nil, nil, nil, nil, - nil, nil, 361, 242, 363, nil, nil, 318, 311, nil, - nil, nil, 310, 312, nil, nil, nil, nil, nil, nil, - 266, nil, nil, 260, nil, 362, 267, nil, nil, 136, - 134, nil, 369, 130, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 337, nil, - nil, 380, 296, 186, nil, nil, 118, 120, 121, nil, - nil, 377, nil, nil, nil, 136, 134, 136, 134, nil, - 331, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 2, 114, 4, 130, 109, 111, 112, 148, 136, 134, + 261, 187, 195, 194, 224, 273, 352, 367, 186, 235, + 348, 215, 217, 307, 238, 159, 160, 161, 162, 319, + 158, 320, 234, 75, 118, 120, 121, 122, 336, 271, + 275, 354, 338, 139, 141, 138, 138, 143, 269, 306, + 380, 259, 147, 312, 363, 311, 239, 154, 221, 345, + 327, 256, 388, 382, 293, 379, 257, 3, 254, 297, + 255, 163, 253, 138, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 270, 190, 357, 214, + 214, 150, 157, 219, 329, 138, 152, 227, 1, 138, + nil, nil, nil, nil, 332, nil, 190, nil, nil, nil, + 279, nil, nil, nil, 341, nil, nil, 236, nil, 358, + nil, 360, 236, 241, nil, 316, nil, nil, nil, 309, + 308, 310, nil, nil, nil, nil, nil, 264, nil, nil, + nil, nil, 258, nil, 359, 265, 130, nil, nil, nil, + nil, 366, 136, 134, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 334, 376, + 185, 294, nil, 118, 120, 121, 373, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 136, 134, + 136, 134, 328, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 297, nil, nil, 139, 191, 191, nil, - 303, 305, nil, nil, nil, nil, nil, nil, 315, nil, - 325, nil, 325, nil, 328, 379, 144, nil, nil, nil, - nil, 148, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 325, 334, nil, nil, nil, nil, nil, - 191, nil, nil, 342, 343, nil, 367, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 325, nil, - nil, nil, nil, nil, nil, 349, nil, nil, nil, nil, - nil, nil, 139, nil, nil, nil, 382, nil, nil, nil, + nil, nil, 295, 138, 190, 190, nil, nil, nil, 301, + 303, nil, nil, nil, nil, nil, 322, 313, 322, nil, + 325, 375, 143, nil, nil, nil, nil, 147, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 322, + 331, nil, nil, nil, nil, nil, 190, nil, 364, 339, + 340, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 322, nil, nil, nil, nil, nil, + nil, 346, nil, nil, nil, nil, nil, nil, 138, nil, + nil, nil, nil, 378, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 370, 369, + nil, nil, nil, nil, nil, 185, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 373, 372, nil, nil, nil, nil, 372, nil, nil, nil, - 186, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 118, nil, nil, nil, + nil, 118, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 372, nil, nil, + nil, nil, nil, nil, 369, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 397, nil, 399, 401 ] + nil, 392, nil, 394, 396 ] racc_goto_check = [ - 2, 40, 4, 82, 32, 38, 10, 10, 10, 65, - 57, 65, 52, 89, 55, 45, 67, 56, 48, 47, - 13, 67, 66, 73, 50, 73, 7, 66, 8, 8, - 8, 8, 58, 55, 6, 66, 10, 10, 10, 10, - 39, 61, 61, 59, 12, 12, 51, 10, 10, 10, - 62, 53, 49, 45, 10, 46, 69, 56, 70, 10, - 72, 44, 67, 75, 39, 47, 48, 77, 78, 39, - 79, 3, 12, 83, 84, 10, 10, 10, 10, 10, + 2, 40, 4, 65, 10, 10, 10, 82, 32, 38, + 89, 52, 57, 55, 45, 56, 48, 67, 13, 66, + 47, 61, 61, 50, 66, 8, 8, 8, 8, 73, + 7, 73, 55, 6, 10, 10, 10, 10, 58, 59, + 39, 51, 62, 12, 12, 10, 10, 10, 53, 49, + 46, 45, 10, 69, 70, 56, 72, 10, 44, 75, + 77, 78, 67, 48, 39, 47, 79, 3, 83, 39, + 84, 12, 86, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 52, 10, - 50, 10, 10, 6, 12, 39, 86, 10, 12, 4, - 4, 10, 87, 88, 1, 39, nil, nil, 10, 57, - nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, - nil, nil, 56, 4, 56, nil, nil, 45, 57, nil, - nil, nil, 55, 55, nil, nil, nil, nil, nil, nil, - 10, nil, nil, 2, nil, 39, 2, nil, nil, 32, - 38, nil, 39, 65, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 57, nil, - nil, 39, 40, 10, nil, nil, 10, 10, 10, nil, - nil, 89, nil, nil, nil, 32, 38, 32, 38, nil, - 82, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 10, 10, 10, 10, 10, 10, 52, 10, 50, 10, + 10, 87, 6, 12, 39, 10, 88, 12, 1, 10, + nil, nil, nil, nil, 39, nil, 10, nil, nil, nil, + 57, nil, nil, nil, 39, nil, nil, 4, nil, 56, + nil, 56, 4, 4, nil, 45, nil, nil, nil, 57, + 55, 55, nil, nil, nil, nil, nil, 10, nil, nil, + nil, nil, 2, nil, 39, 2, 65, nil, nil, nil, + nil, 39, 32, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 57, 39, + 10, 40, nil, 10, 10, 10, 89, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, 38, + 32, 38, 82, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 2, nil, nil, 10, 10, 10, nil, - 2, 2, nil, nil, nil, nil, nil, nil, 4, nil, - 10, nil, 10, nil, 10, 52, 10, nil, nil, nil, - nil, 10, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 10, 10, nil, nil, nil, nil, nil, - 10, nil, nil, 10, 10, nil, 65, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, + nil, nil, 2, 10, 10, 10, nil, nil, nil, 2, + 2, nil, nil, nil, nil, nil, 10, 4, 10, nil, + 10, 52, 10, nil, nil, nil, nil, 10, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, + 10, nil, nil, nil, nil, nil, 10, nil, 65, 10, + 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 10, nil, nil, nil, nil, nil, + nil, 10, nil, nil, nil, nil, nil, nil, 10, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 2, 4, nil, nil, nil, nil, nil, 10, nil, nil, nil, nil, - nil, nil, 10, nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 2, 4, nil, nil, nil, nil, 4, nil, nil, nil, - 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 10, 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, nil, 4, nil, nil, + nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 2, nil, 2, 2 ] + nil, 2, nil, 2, 2 ] racc_goto_pointer = [ - nil, 114, 0, 71, 2, nil, 29, -50, -49, nil, - -6, nil, -9, -83, nil, nil, nil, nil, nil, nil, + nil, 108, 0, 67, 2, nil, 28, -46, -52, nil, + -8, nil, -10, -85, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, -46, nil, nil, nil, nil, nil, -45, -156, - -39, nil, nil, nil, -54, -101, -297, -285, -288, -180, - -208, -261, -91, -138, nil, -91, -178, -95, -244, -148, - nil, -66, -228, nil, nil, -40, -103, -303, nil, -180, - -258, nil, -71, -218, nil, -237, nil, -185, -84, -82, - nil, nil, -57, -77, -76, nil, -44, 50, 50, -142 ] + nil, nil, -42, nil, nil, nil, nil, nil, -41, -155, + -39, nil, nil, nil, -57, -102, -299, -282, -288, -182, + -208, -264, -92, -140, nil, -92, -179, -93, -236, -151, + nil, -86, -234, nil, nil, -46, -106, -300, nil, -182, + -260, nil, -75, -211, nil, -239, nil, -190, -90, -85, + nil, nil, -53, -81, -79, nil, -77, 39, 43, -144 ] racc_goto_default = [ - nil, nil, 371, nil, 237, 5, 6, 7, 8, 9, - 11, 10, 307, nil, 15, 39, 16, 17, 18, 19, + nil, nil, 368, nil, 216, 5, 6, 7, 8, 9, + 11, 10, 305, nil, 15, 39, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, nil, nil, 40, 41, 115, nil, nil, 119, nil, nil, nil, - nil, nil, nil, nil, 45, nil, nil, nil, 197, nil, - 106, nil, 198, 202, 200, 126, nil, nil, 125, nil, - nil, 131, nil, 132, 133, 226, 145, 147, 56, 57, - 58, 60, nil, nil, nil, 150, nil, nil, nil, nil ] + nil, nil, nil, nil, 45, nil, nil, nil, 196, nil, + 106, nil, 197, 201, 199, 126, nil, nil, 125, nil, + nil, 131, nil, 132, 133, 225, 144, 146, 56, 57, + 58, 60, nil, nil, nil, 149, nil, nil, nil, nil ] racc_reduce_table = [ 0, 0, :racc_error, 1, 90, :_reduce_1, 1, 90, :_reduce_2, 1, 90, :_reduce_none, 1, 91, :_reduce_4, 1, 94, :_reduce_5, 3, 94, :_reduce_6, 2, 94, :_reduce_7, 1, 95, :_reduce_8, 3, 95, :_reduce_9, 1, 96, :_reduce_none, 1, 97, :_reduce_11, 3, 97, :_reduce_12, 3, 97, :_reduce_13, 3, 97, :_reduce_14, 3, 97, :_reduce_15, 1, 99, :_reduce_none, 4, 99, :_reduce_17, 3, 99, :_reduce_18, 3, 99, :_reduce_19, 3, 99, :_reduce_20, 3, 99, :_reduce_21, 3, 99, :_reduce_22, 3, 99, :_reduce_23, 3, 99, :_reduce_24, 3, 99, :_reduce_25, 3, 99, :_reduce_26, 3, 99, :_reduce_27, 2, 99, :_reduce_28, 3, 99, :_reduce_29, 3, 99, :_reduce_30, 3, 99, :_reduce_31, 3, 99, :_reduce_32, 3, 99, :_reduce_33, 3, 99, :_reduce_34, 2, 99, :_reduce_35, 3, 99, :_reduce_36, 3, 99, :_reduce_37, 3, 99, :_reduce_38, 3, 99, :_reduce_39, 3, 99, :_reduce_40, 3, 99, :_reduce_41, 3, 99, :_reduce_42, 1, 101, :_reduce_43, 3, 101, :_reduce_44, 1, 100, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 104, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 105, :_reduce_none, 1, 122, :_reduce_67, 1, 122, :_reduce_68, 5, 103, :_reduce_69, 3, 103, :_reduce_70, 6, 103, :_reduce_71, 4, 103, :_reduce_72, 1, 103, :_reduce_73, 1, 107, :_reduce_74, 2, 107, :_reduce_75, 4, 130, :_reduce_76, 3, 130, :_reduce_77, 1, 130, :_reduce_78, 3, 131, :_reduce_79, 2, 129, :_reduce_80, 3, 133, :_reduce_81, 2, 133, :_reduce_82, 2, 132, :_reduce_83, 4, 132, :_reduce_84, 2, 110, :_reduce_85, 5, 135, :_reduce_86, 4, 135, :_reduce_87, 0, 136, :_reduce_none, 2, 136, :_reduce_89, 4, 136, :_reduce_90, 3, 136, :_reduce_91, 6, 111, :_reduce_92, 5, 111, :_reduce_93, 0, 137, :_reduce_none, 4, 137, :_reduce_95, 3, 137, :_reduce_96, 5, 109, :_reduce_97, 1, 138, :_reduce_98, 2, 138, :_reduce_99, 5, 139, :_reduce_100, 4, 139, :_reduce_101, 1, 140, :_reduce_102, 1, 102, :_reduce_none, 4, 102, :_reduce_104, 1, 142, :_reduce_105, 3, 142, :_reduce_106, 3, 141, :_reduce_107, 1, 98, :_reduce_108, 6, 98, :_reduce_109, 6, 98, :_reduce_110, 5, 98, :_reduce_111, 5, 98, :_reduce_112, 6, 98, :_reduce_113, 5, 98, :_reduce_114, 4, 147, :_reduce_115, 1, 148, :_reduce_116, 1, 144, :_reduce_117, 3, 144, :_reduce_118, 1, 143, :_reduce_119, 2, 143, :_reduce_120, 1, 143, :_reduce_121, 6, 108, :_reduce_122, 2, 108, :_reduce_123, 3, 149, :_reduce_124, 3, 149, :_reduce_125, 1, 150, :_reduce_none, 1, 150, :_reduce_none, 0, 146, :_reduce_128, 1, 146, :_reduce_129, 3, 146, :_reduce_130, 1, 152, :_reduce_none, 1, 152, :_reduce_none, 1, 152, :_reduce_none, 3, 151, :_reduce_134, 3, 151, :_reduce_135, 6, 112, :_reduce_136, 7, 113, :_reduce_137, 1, 157, :_reduce_138, 1, 156, :_reduce_none, 1, 156, :_reduce_none, 1, 158, :_reduce_none, 2, 158, :_reduce_142, 1, 159, :_reduce_none, 1, 159, :_reduce_none, 6, 114, :_reduce_145, 5, 114, :_reduce_146, 1, 160, :_reduce_147, 3, 160, :_reduce_148, 1, 162, :_reduce_149, 1, 162, :_reduce_150, 1, 162, :_reduce_151, 1, 162, :_reduce_none, 1, 163, :_reduce_153, 3, 163, :_reduce_154, 1, 161, :_reduce_none, 2, 161, :_reduce_156, - 6, 116, :_reduce_157, + 1, 116, :_reduce_157, 1, 154, :_reduce_158, 1, 154, :_reduce_159, 1, 155, :_reduce_160, 2, 155, :_reduce_161, 4, 155, :_reduce_162, 1, 134, :_reduce_163, 3, 134, :_reduce_164, 3, 164, :_reduce_165, 1, 164, :_reduce_166, 1, 106, :_reduce_167, 3, 117, :_reduce_168, 4, 117, :_reduce_169, 2, 117, :_reduce_170, 3, 117, :_reduce_171, 4, 117, :_reduce_172, 2, 117, :_reduce_173, 3, 120, :_reduce_174, 4, 120, :_reduce_175, 2, 120, :_reduce_176, 1, 165, :_reduce_177, 3, 165, :_reduce_178, 3, 166, :_reduce_179, 1, 127, :_reduce_none, 1, 127, :_reduce_none, 1, 127, :_reduce_none, 1, 167, :_reduce_183, 2, 168, :_reduce_184, 1, 170, :_reduce_185, 1, 172, :_reduce_186, 1, 173, :_reduce_187, 2, 171, :_reduce_188, 1, 174, :_reduce_189, 1, 175, :_reduce_190, 2, 175, :_reduce_191, 2, 169, :_reduce_192, 2, 176, :_reduce_193, 2, 176, :_reduce_194, 3, 92, :_reduce_195, 0, 177, :_reduce_196, 2, 177, :_reduce_197, 4, 177, :_reduce_198, 1, 115, :_reduce_199, 3, 115, :_reduce_200, 5, 115, :_reduce_201, 1, 178, :_reduce_none, 1, 178, :_reduce_none, 1, 123, :_reduce_204, 1, 126, :_reduce_205, 1, 124, :_reduce_206, 1, 125, :_reduce_207, 1, 119, :_reduce_208, 1, 118, :_reduce_209, 1, 121, :_reduce_210, 0, 128, :_reduce_none, 1, 128, :_reduce_212, 0, 145, :_reduce_none, 1, 145, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 1, 153, :_reduce_none, 0, 93, :_reduce_229 ] racc_reduce_n = 230 -racc_shift_n = 407 +racc_shift_n = 402 racc_token_table = { false => 0, :error => 1, :STRING => 2, :DQPRE => 3, :DQMID => 4, :DQPOST => 5, :LBRACK => 6, :RBRACK => 7, :LBRACE => 8, :RBRACE => 9, :SYMBOL => 10, :FARROW => 11, :COMMA => 12, :TRUE => 13, :FALSE => 14, :EQUALS => 15, :APPENDS => 16, :DELETES => 17, :LESSEQUAL => 18, :NOTEQUAL => 19, :DOT => 20, :COLON => 21, :LLCOLLECT => 22, :RRCOLLECT => 23, :QMARK => 24, :LPAREN => 25, :RPAREN => 26, :ISEQUAL => 27, :GREATEREQUAL => 28, :GREATERTHAN => 29, :LESSTHAN => 30, :IF => 31, :ELSE => 32, :DEFINE => 33, :ELSIF => 34, :VARIABLE => 35, :CLASS => 36, :INHERITS => 37, :NODE => 38, :BOOLEAN => 39, :NAME => 40, :SEMIC => 41, :CASE => 42, :DEFAULT => 43, :AT => 44, :ATAT => 45, :LCOLLECT => 46, :RCOLLECT => 47, :CLASSREF => 48, :NOT => 49, :OR => 50, :AND => 51, :UNDEF => 52, :PARROW => 53, :PLUS => 54, :MINUS => 55, :TIMES => 56, :DIV => 57, :LSHIFT => 58, :RSHIFT => 59, :UMINUS => 60, :MATCH => 61, :NOMATCH => 62, :REGEX => 63, :IN_EDGE => 64, :OUT_EDGE => 65, :IN_EDGE_SUB => 66, :OUT_EDGE_SUB => 67, :IN => 68, :UNLESS => 69, :PIPE => 70, :LAMBDA => 71, :SELBRACE => 72, :NUMBER => 73, :HEREDOC => 74, :SUBLOCATE => 75, :RENDER_STRING => 76, :RENDER_EXPR => 77, :EPP_START => 78, :EPP_END => 79, :EPP_END_TRIM => 80, :FUNCTION => 81, :LOW => 82, :HIGH => 83, :CALL => 84, :LISTSTART => 85, :MODULO => 86, :TITLE_COLON => 87, :CASE_COLON => 88 } racc_nt_base = 89 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", "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", "LOW", "HIGH", "CALL", "LISTSTART", "MODULO", "TITLE_COLON", "CASE_COLON", "$start", "program", "statements", "epp_expression", "nil", "syntactic_statements", "syntactic_statement", "any_expression", "relationship_expression", "resource_expression", "expression", "higher_precedence", "expressions", "selector_entries", "call_function_expression", "primary_expression", "literal_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", "function_definition", "array", "boolean", "default", "hash", "regex", "text_or_name", "number", "type", "undef", "name", "quotedtext", "endcomma", "lambda", "call_method_expression", "named_access", "lambda_parameter_list", "lambda_rest", "parameters", "if_part", "else", "unless_else", "case_options", "case_option", "case_colon", "selector_entry", "selector_entry_list", "at", "resourceinstances", "endsemi", "attribute_operations", "resourceinst", "title_colon", "collect_query", "optional_query", "attribute_operation", "attribute_name", "keyword", "classname", "parameter_list", "opt_statements", "stacked_classname", "classparent", "classnameordefault", "hostnames", "nodeparent", "hostname", "dotted_name", "parameter", "hashpairs", "hashpair", "string", "dq_string", "heredoc", "dqpre", "dqrval", "dqpost", "dqmid", "text_expression", "dqtail", "sublocated_text", "epp_parameters_list", "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 .,., # reduce 3 omitted module_eval(<<'.,.,', 'egrammar.ra', 71) def _reduce_4(val, _values, result) result = transform_calls(val[0]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 77) def _reduce_5(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 78) def _reduce_6(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 79) def _reduce_7(val, _values, result) result = val[0].push val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 83) def _reduce_8(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 84) def _reduce_9(val, _values, result) result = aryfy(val[0]).push val[2] result end .,., # reduce 10 omitted module_eval(<<'.,.,', 'egrammar.ra', 90) def _reduce_11(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 91) def _reduce_12(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 92) def _reduce_13(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 93) def _reduce_14(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 94) def _reduce_15(val, _values, result) result = val[0].relop(val[1][:value], val[2]); loc result, val[1] result end .,., # reduce 16 omitted module_eval(<<'.,.,', 'egrammar.ra', 101) def _reduce_17(val, _values, result) result = val[0][*val[2]] ; loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 102) def _reduce_18(val, _values, result) result = val[0].in val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 103) def _reduce_19(val, _values, result) result = val[0] =~ val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 104) def _reduce_20(val, _values, result) result = val[0].mne val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 105) def _reduce_21(val, _values, result) result = val[0] + val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 106) def _reduce_22(val, _values, result) result = val[0] - val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 107) def _reduce_23(val, _values, result) result = val[0] / val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 108) def _reduce_24(val, _values, result) result = val[0] * val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 109) def _reduce_25(val, _values, result) result = val[0] % val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 110) def _reduce_26(val, _values, result) result = val[0] << val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 111) def _reduce_27(val, _values, result) result = val[0] >> val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 112) def _reduce_28(val, _values, result) result = val[1].minus() ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 113) def _reduce_29(val, _values, result) result = val[0].ne val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 114) def _reduce_30(val, _values, result) result = val[0] == val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 115) def _reduce_31(val, _values, result) result = val[0] > val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 116) def _reduce_32(val, _values, result) result = val[0] >= val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 117) def _reduce_33(val, _values, result) result = val[0] < val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 118) def _reduce_34(val, _values, result) result = val[0] <= val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 119) def _reduce_35(val, _values, result) result = val[1].not ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 120) def _reduce_36(val, _values, result) result = val[0].and val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 121) def _reduce_37(val, _values, result) result = val[0].or val[2] ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 122) def _reduce_38(val, _values, result) result = val[0].set(val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 123) def _reduce_39(val, _values, result) result = val[0].plus_set(val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 124) def _reduce_40(val, _values, result) result = val[0].minus_set(val[2]); loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 125) def _reduce_41(val, _values, result) result = val[0].select(*val[2]) ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 126) def _reduce_42(val, _values, result) result = val[1].paren() ; loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 134) def _reduce_43(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 135) def _reduce_44(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 45 omitted # reduce 46 omitted # reduce 47 omitted # reduce 48 omitted # reduce 49 omitted # reduce 50 omitted # reduce 51 omitted # reduce 52 omitted # reduce 53 omitted # reduce 54 omitted # reduce 55 omitted # reduce 56 omitted # reduce 57 omitted # reduce 58 omitted # reduce 59 omitted # reduce 60 omitted # reduce 61 omitted # reduce 62 omitted # reduce 63 omitted # reduce 64 omitted # reduce 65 omitted # reduce 66 omitted module_eval(<<'.,.,', 'egrammar.ra', 168) def _reduce_67(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 169) def _reduce_68(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 177) def _reduce_69(val, _values, result) result = Factory.CALL_NAMED(val[0], true, val[2]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 181) def _reduce_70(val, _values, result) result = Factory.CALL_NAMED(val[0], true, []) loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 185) def _reduce_71(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', 190) def _reduce_72(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', 194) def _reduce_73(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 199) def _reduce_74(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 200) def _reduce_75(val, _values, result) result = val[0]; val[0].lambda = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 203) def _reduce_76(val, _values, result) result = Factory.CALL_METHOD(val[0], val[2]); loc result, val[1], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 204) def _reduce_77(val, _values, result) result = Factory.CALL_METHOD(val[0], []); loc result, val[1], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 205) def _reduce_78(val, _values, result) result = Factory.CALL_METHOD(val[0], []); loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 210) def _reduce_79(val, _values, result) result = val[0].dot(Factory.fqn(val[2][:value])) loc result, val[1], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 222) def _reduce_80(val, _values, result) result = Factory.LAMBDA(val[0], val[1]) # loc result, val[1] # TODO result end .,., module_eval(<<'.,.,', 'egrammar.ra', 227) def _reduce_81(val, _values, result) result = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 228) def _reduce_82(val, _values, result) result = nil result end .,., module_eval(<<'.,.,', 'egrammar.ra', 232) def _reduce_83(val, _values, result) result = [] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 233) def _reduce_84(val, _values, result) result = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 243) def _reduce_85(val, _values, result) result = val[1] loc(result, val[0], val[1]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 250) def _reduce_86(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', 254) def _reduce_87(val, _values, result) result = Factory.IF(val[0], nil, val[3]) loc(result, val[0], (val[3] ? val[3] : val[2])) result end .,., # reduce 88 omitted module_eval(<<'.,.,', 'egrammar.ra', 262) def _reduce_89(val, _values, result) result = val[1] loc(result, val[0], val[1]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 266) def _reduce_90(val, _values, result) result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 270) def _reduce_91(val, _values, result) result = nil # don't think a nop is needed here either result end .,., module_eval(<<'.,.,', 'egrammar.ra', 279) def _reduce_92(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', 283) def _reduce_93(val, _values, result) result = Factory.UNLESS(val[1], nil, nil) loc result, val[0], val[4] result end .,., # reduce 94 omitted module_eval(<<'.,.,', 'egrammar.ra', 293) def _reduce_95(val, _values, result) result = Factory.block_or_expression(*val[2]) loc result, val[0], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 297) def _reduce_96(val, _values, result) result = nil # don't think a nop is needed here either result end .,., module_eval(<<'.,.,', 'egrammar.ra', 305) def _reduce_97(val, _values, result) result = Factory.CASE(val[1], *val[3]) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 311) def _reduce_98(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 312) def _reduce_99(val, _values, result) result = val[0].push val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 317) def _reduce_100(val, _values, result) result = Factory.WHEN(val[0], val[3]) loc result, val[1], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 321) def _reduce_101(val, _values, result) result = Factory.WHEN(val[0], nil) loc result, val[1], val[3] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 325) def _reduce_102(val, _values, result) result = val[0] result end .,., # reduce 103 omitted module_eval(<<'.,.,', 'egrammar.ra', 336) def _reduce_104(val, _values, result) result = val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 341) def _reduce_105(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 342) def _reduce_106(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 347) def _reduce_107(val, _values, result) result = Factory.MAP(val[0], val[2]) ; loc result, val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 359) def _reduce_108(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 362) def _reduce_109(val, _values, result) result = case Factory.resource_shape(val[1]) when :resource, :class tmp = Factory.RESOURCE(Factory.fqn(token_text(val[1])), val[3]) tmp.form = val[0] tmp when :defaults error val[1], "A resource default can not be virtual or exported" when :override error val[1], "A resource override can not be virtual or exported" else error val[1], "Expression is not valid as a resource, resource-default, or resource-override" end loc result, val[1], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 377) def _reduce_110(val, _values, result) result = case Factory.resource_shape(val[1]) when :resource, :class, :defaults, :override error val[1], "Defaults are not virtualizable" else error val[1], "Expression is not valid as a resource, resource-default, or resource-override" end result end .,., module_eval(<<'.,.,', 'egrammar.ra', 385) def _reduce_111(val, _values, result) result = case Factory.resource_shape(val[0]) when :resource, :class Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2]) when :defaults error val[1], "A resource default can not specify a resource name" when :override error val[1], "A resource override does not allow override of name of resource" else error val[1], "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', 398) def _reduce_112(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 shuld 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', 419) def _reduce_113(val, _values, result) result = Factory.RESOURCE(Factory.fqn(token_text(val[1])), val[3]) result.form = val[0] loc result, val[1], val[5] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 424) def _reduce_114(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', 429) def _reduce_115(val, _values, result) result = Factory.RESOURCE_BODY(val[0], val[2]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 431) def _reduce_116(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 434) def _reduce_117(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 435) def _reduce_118(val, _values, result) result = val[0].push val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 440) def _reduce_119(val, _values, result) result = :virtual result end .,., module_eval(<<'.,.,', 'egrammar.ra', 441) def _reduce_120(val, _values, result) result = :exported result end .,., module_eval(<<'.,.,', 'egrammar.ra', 442) def _reduce_121(val, _values, result) result = :exported result end .,., module_eval(<<'.,.,', 'egrammar.ra', 454) def _reduce_122(val, _values, result) result = Factory.COLLECT(val[0], val[1], val[3]) loc result, val[0], val[5] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 458) def _reduce_123(val, _values, result) result = Factory.COLLECT(val[0], val[1], []) loc result, val[0], val[1] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 463) def _reduce_124(val, _values, result) result = Factory.VIRTUAL_QUERY(val[1]) ; loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 464) def _reduce_125(val, _values, result) result = Factory.EXPORTED_QUERY(val[1]) ; loc result, val[0], val[2] result end .,., # reduce 126 omitted # reduce 127 omitted module_eval(<<'.,.,', 'egrammar.ra', 477) def _reduce_128(val, _values, result) result = [] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 478) def _reduce_129(val, _values, result) result = [val[0]] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 479) def _reduce_130(val, _values, result) result = val[0].push(val[2]) result end .,., # reduce 131 omitted # reduce 132 omitted # reduce 133 omitted module_eval(<<'.,.,', 'egrammar.ra', 495) def _reduce_134(val, _values, result) result = Factory.ATTRIBUTE_OP(val[0][:value], :'=>', val[2]) loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 499) def _reduce_135(val, _values, result) result = Factory.ATTRIBUTE_OP(val[0][:value], :'+>', val[2]) loc result, val[0], val[2] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 509) def _reduce_136(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', 523) def _reduce_137(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', 533) def _reduce_138(val, _values, result) namestack(val[0][:value]) ; result = val[0] result end .,., # reduce 139 omitted # reduce 140 omitted # reduce 141 omitted module_eval(<<'.,.,', 'egrammar.ra', 542) def _reduce_142(val, _values, result) result = val[1] result end .,., # reduce 143 omitted # reduce 144 omitted module_eval(<<'.,.,', 'egrammar.ra', 559) def _reduce_145(val, _values, result) result = add_definition(Factory.NODE(val[1], val[2], val[4])) loc result, val[0], val[5] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 563) def _reduce_146(val, _values, result) result = add_definition(Factory.NODE(val[1], val[2], nil)) loc result, val[0], val[4] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 573) def _reduce_147(val, _values, result) result = [result] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 574) def _reduce_148(val, _values, result) result = val[0].push(val[2]) result end .,., module_eval(<<'.,.,', 'egrammar.ra', 579) def _reduce_149(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 580) def _reduce_150(val, _values, result) result = val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 581) def _reduce_151(val, _values, result) result = Factory.literal(:default); loc result, val[0] result end .,., # reduce 152 omitted module_eval(<<'.,.,', 'egrammar.ra', 585) def _reduce_153(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., module_eval(<<'.,.,', 'egrammar.ra', 586) def _reduce_154(val, _values, result) result = Factory.concat(val[0], '.', val[2][:value]); loc result, val[0], val[2] result end .,., # reduce 155 omitted module_eval(<<'.,.,', 'egrammar.ra', 591) def _reduce_156(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 597) +module_eval(<<'.,.,', 'egrammar.ra', 596) def _reduce_157(val, _values, result) - result = add_definition(Factory.FUNCTION(val[1][:value], val[2], val[4])) - loc result, val[0], val[5] - + result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 605) +module_eval(<<'.,.,', 'egrammar.ra', 608) def _reduce_158(val, _values, result) result = val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 606) +module_eval(<<'.,.,', 'egrammar.ra', 609) def _reduce_159(val, _values, result) error val[0], "'class' is not a valid classname" result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 610) +module_eval(<<'.,.,', 'egrammar.ra', 613) def _reduce_160(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 611) +module_eval(<<'.,.,', 'egrammar.ra', 614) def _reduce_161(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 612) +module_eval(<<'.,.,', 'egrammar.ra', 615) def _reduce_162(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 616) +module_eval(<<'.,.,', 'egrammar.ra', 619) def _reduce_163(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 617) +module_eval(<<'.,.,', 'egrammar.ra', 620) def _reduce_164(val, _values, result) result = val[0].push(val[2]) result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 621) +module_eval(<<'.,.,', 'egrammar.ra', 624) def _reduce_165(val, _values, result) result = Factory.PARAM(val[0][:value], val[2]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 622) +module_eval(<<'.,.,', 'egrammar.ra', 625) def _reduce_166(val, _values, result) result = Factory.PARAM(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 635) +module_eval(<<'.,.,', 'egrammar.ra', 638) def _reduce_167(val, _values, result) result = Factory.fqn(val[0][:value]).var ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 641) +module_eval(<<'.,.,', 'egrammar.ra', 644) def _reduce_168(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 642) +module_eval(<<'.,.,', 'egrammar.ra', 645) def _reduce_169(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 643) +module_eval(<<'.,.,', 'egrammar.ra', 646) def _reduce_170(val, _values, result) result = Factory.literal([]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 644) +module_eval(<<'.,.,', 'egrammar.ra', 647) def _reduce_171(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 645) +module_eval(<<'.,.,', 'egrammar.ra', 648) def _reduce_172(val, _values, result) result = Factory.LIST(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 646) +module_eval(<<'.,.,', 'egrammar.ra', 649) def _reduce_173(val, _values, result) result = Factory.literal([]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 649) +module_eval(<<'.,.,', 'egrammar.ra', 652) def _reduce_174(val, _values, result) result = Factory.HASH(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 650) +module_eval(<<'.,.,', 'egrammar.ra', 653) def _reduce_175(val, _values, result) result = Factory.HASH(val[1]); loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 651) +module_eval(<<'.,.,', 'egrammar.ra', 654) def _reduce_176(val, _values, result) result = Factory.literal({}) ; loc result, val[0], val[3] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 654) +module_eval(<<'.,.,', 'egrammar.ra', 657) def _reduce_177(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 655) +module_eval(<<'.,.,', 'egrammar.ra', 658) def _reduce_178(val, _values, result) result = val[0].push val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 658) +module_eval(<<'.,.,', 'egrammar.ra', 661) def _reduce_179(val, _values, result) result = Factory.KEY_ENTRY(val[0], val[2]); loc result, val[1] result end .,., # reduce 180 omitted # reduce 181 omitted # reduce 182 omitted -module_eval(<<'.,.,', 'egrammar.ra', 665) +module_eval(<<'.,.,', 'egrammar.ra', 668) def _reduce_183(val, _values, result) result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 666) +module_eval(<<'.,.,', 'egrammar.ra', 669) def _reduce_184(val, _values, result) result = Factory.string(val[0], *val[1]) ; loc result, val[0], val[1][-1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 667) +module_eval(<<'.,.,', 'egrammar.ra', 670) def _reduce_185(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 668) +module_eval(<<'.,.,', 'egrammar.ra', 671) def _reduce_186(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 669) +module_eval(<<'.,.,', 'egrammar.ra', 672) def _reduce_187(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 670) +module_eval(<<'.,.,', 'egrammar.ra', 673) def _reduce_188(val, _values, result) result = [val[0]] + val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 671) +module_eval(<<'.,.,', 'egrammar.ra', 674) def _reduce_189(val, _values, result) result = Factory.TEXT(val[0]) result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 674) +module_eval(<<'.,.,', 'egrammar.ra', 677) def _reduce_190(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 675) +module_eval(<<'.,.,', 'egrammar.ra', 678) def _reduce_191(val, _values, result) result = [val[0]] + val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 678) +module_eval(<<'.,.,', 'egrammar.ra', 681) def _reduce_192(val, _values, result) result = Factory.HEREDOC(val[0][:value], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 681) +module_eval(<<'.,.,', 'egrammar.ra', 684) def _reduce_193(val, _values, result) result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 682) +module_eval(<<'.,.,', 'egrammar.ra', 685) def _reduce_194(val, _values, result) result = Factory.SUBLOCATE(val[0], val[1]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 685) +module_eval(<<'.,.,', 'egrammar.ra', 688) def _reduce_195(val, _values, result) result = Factory.EPP(val[1], val[2]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 688) +module_eval(<<'.,.,', 'egrammar.ra', 691) def _reduce_196(val, _values, result) result = nil result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 689) +module_eval(<<'.,.,', 'egrammar.ra', 692) def _reduce_197(val, _values, result) result = [] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 690) +module_eval(<<'.,.,', 'egrammar.ra', 693) def _reduce_198(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 693) +module_eval(<<'.,.,', 'egrammar.ra', 696) def _reduce_199(val, _values, result) result = Factory.RENDER_STRING(val[0][:value]); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 694) +module_eval(<<'.,.,', 'egrammar.ra', 697) def _reduce_200(val, _values, result) result = Factory.RENDER_EXPR(val[1]); loc result, val[0], val[2] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 695) +module_eval(<<'.,.,', 'egrammar.ra', 698) def _reduce_201(val, _values, result) result = Factory.RENDER_EXPR(Factory.block_or_expression(*val[2])); loc result, val[0], val[4] result end .,., # reduce 202 omitted # reduce 203 omitted -module_eval(<<'.,.,', 'egrammar.ra', 701) +module_eval(<<'.,.,', 'egrammar.ra', 704) def _reduce_204(val, _values, result) result = Factory.NUMBER(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 702) +module_eval(<<'.,.,', 'egrammar.ra', 705) def _reduce_205(val, _values, result) result = Factory.QNAME_OR_NUMBER(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 703) +module_eval(<<'.,.,', 'egrammar.ra', 706) def _reduce_206(val, _values, result) result = Factory.QREF(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 704) +module_eval(<<'.,.,', 'egrammar.ra', 707) def _reduce_207(val, _values, result) result = Factory.literal(:undef); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 705) +module_eval(<<'.,.,', 'egrammar.ra', 708) def _reduce_208(val, _values, result) result = Factory.literal(:default); loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 710) +module_eval(<<'.,.,', 'egrammar.ra', 713) def _reduce_209(val, _values, result) result = Factory.literal(val[0][:value]) ; loc result, val[0] result end .,., -module_eval(<<'.,.,', 'egrammar.ra', 713) +module_eval(<<'.,.,', 'egrammar.ra', 716) def _reduce_210(val, _values, result) result = Factory.literal(val[0][:value]); loc result, val[0] result end .,., # reduce 211 omitted -module_eval(<<'.,.,', 'egrammar.ra', 719) +module_eval(<<'.,.,', 'egrammar.ra', 722) def _reduce_212(val, _values, result) result = nil result end .,., # reduce 213 omitted # reduce 214 omitted # reduce 215 omitted # reduce 216 omitted # reduce 217 omitted # reduce 218 omitted # reduce 219 omitted # 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 -module_eval(<<'.,.,', 'egrammar.ra', 742) +module_eval(<<'.,.,', 'egrammar.ra', 745) def _reduce_229(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/lib/puppet/pops/validation/checker4_0.rb b/lib/puppet/pops/validation/checker4_0.rb index 3c6d89583..fa2587620 100644 --- a/lib/puppet/pops/validation/checker4_0.rb +++ b/lib/puppet/pops/validation/checker4_0.rb @@ -1,519 +1,514 @@ # A Validator validates a model. # # Validation is performed on each model element in isolation. Each method should validate the model element's state # but not validate its referenced/contained elements except to check their validity in their respective role. # The intent is to drive the validation with a tree iterator that visits all elements in a model. # # # TODO: Add validation of multiplicities - this is a general validation that can be checked for all # Model objects via their metamodel. (I.e an extra call to multiplicity check in polymorph check). # This is however mostly valuable when validating model to model transformations, and is therefore T.B.D # class Puppet::Pops::Validation::Checker4_0 Issues = Puppet::Pops::Issues Model = Puppet::Pops::Model attr_reader :acceptor # Initializes the validator with a diagnostics producer. This object must respond to # `:will_accept?` and `:accept`. # def initialize(diagnostics_producer) @@check_visitor ||= Puppet::Pops::Visitor.new(nil, "check", 0, 0) @@rvalue_visitor ||= Puppet::Pops::Visitor.new(nil, "rvalue", 0, 0) @@hostname_visitor ||= Puppet::Pops::Visitor.new(nil, "hostname", 1, 2) @@assignment_visitor ||= Puppet::Pops::Visitor.new(nil, "assign", 0, 1) @@query_visitor ||= Puppet::Pops::Visitor.new(nil, "query", 0, 0) @@top_visitor ||= Puppet::Pops::Visitor.new(nil, "top", 1, 1) @@relation_visitor ||= Puppet::Pops::Visitor.new(nil, "relation", 0, 0) @acceptor = diagnostics_producer end # Validates the entire model by visiting each model element and calling `check`. # The result is collected (or acted on immediately) by the configured diagnostic provider/acceptor # given when creating this Checker. # def validate(model) # tree iterate the model, and call check for each element check(model) model.eAllContents.each {|m| check(m) } end # Performs regular validity check def check(o) @@check_visitor.visit_this_0(self, o) end # Performs check if this is a vaid hostname expression # @param single_feature_name [String, nil] the name of a single valued hostname feature of the value's container. e.g. 'parent' def hostname(o, semantic, single_feature_name = nil) @@hostname_visitor.visit_this_2(self, o, semantic, single_feature_name) end # Performs check if this is valid as a query def query(o) @@query_visitor.visit_this_0(self, o) end # Performs check if this is valid as a relationship side def relation(o) @@relation_visitor.visit_this_0(self, o) end # Performs check if this is valid as a rvalue def rvalue(o) @@rvalue_visitor.visit_this_0(self, o) end # Performs check if this is valid as a container of a definition (class, define, node) def top(o, definition) @@top_visitor.visit_this_1(self, o, definition) end # Checks the LHS of an assignment (is it assignable?). # If args[0] is true, assignment via index is checked. # def assign(o, via_index = false) @@assignment_visitor.visit_this_1(self, o, via_index) end #---ASSIGNMENT CHECKS def assign_VariableExpression(o, via_index) varname_string = varname_to_s(o.expr) if varname_string =~ Puppet::Pops::Patterns::NUMERIC_VAR_NAME acceptor.accept(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o, :varname => varname_string) end # Can not assign to something in another namespace (i.e. a '::' in the name is not legal) if acceptor.will_accept? Issues::CROSS_SCOPE_ASSIGNMENT if varname_string =~ /::/ acceptor.accept(Issues::CROSS_SCOPE_ASSIGNMENT, o, :name => varname_string) end end # TODO: Could scan for reassignment of the same variable if done earlier in the same container # Or if assigning to a parameter (more work). # TODO: Investigate if there are invalid cases for += assignment end def assign_AccessExpression(o, via_index) # Are indexed assignments allowed at all ? $x[x] = '...' if acceptor.will_accept? Issues::ILLEGAL_INDEXED_ASSIGNMENT acceptor.accept(Issues::ILLEGAL_INDEXED_ASSIGNMENT, o) else # Then the left expression must be assignable-via-index assign(o.left_expr, true) end end def assign_Object(o, via_index) # Can not assign to anything else (differentiate if this is via index or not) # i.e. 10 = 'hello' vs. 10['x'] = 'hello' (the root is reported as being in error in both cases) # acceptor.accept(via_index ? Issues::ILLEGAL_ASSIGNMENT_VIA_INDEX : Issues::ILLEGAL_ASSIGNMENT, o) end #---CHECKS def check_Object(o) end def check_Factory(o) check(o.current) end def check_AccessExpression(o) # Only min range is checked, all other checks are RT checks as they depend on the resulting type # of the LHS. if o.keys.size < 1 acceptor.accept(Issues::MISSING_INDEX, o) end end def check_AssignmentExpression(o) acceptor.accept(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator}) unless [:'=', :'+=', :'-='].include? o.operator assign(o.left_expr) rvalue(o.right_expr) end # Checks that operation with :+> is contained in a ResourceOverride or Collector. # # Parent of an AttributeOperation can be one of: # * CollectExpression # * ResourceOverride # * ResourceBody (ILLEGAL this is a regular resource expression) # * ResourceDefaults (ILLEGAL) # def check_AttributeOperation(o) if o.operator == :'+>' # Append operator use is constrained parent = o.eContainer unless parent.is_a?(Model::CollectExpression) || parent.is_a?(Model::ResourceOverrideExpression) acceptor.accept(Issues::ILLEGAL_ATTRIBUTE_APPEND, o, {:name=>o.attribute_name, :parent=>parent}) end end rvalue(o.value_expr) end def check_BinaryExpression(o) rvalue(o.left_expr) rvalue(o.right_expr) end def check_CallNamedFunctionExpression(o) case o.functor_expr when Puppet::Pops::Model::QualifiedName # ok nil when Puppet::Pops::Model::RenderStringExpression # helpful to point out this easy to make Epp error acceptor.accept(Issues::ILLEGAL_EPP_PARAMETERS, o) else acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o}) end end def check_MethodCallExpression(o) unless o.functor_expr.is_a? Model::QualifiedName acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, :feature => 'function name', :container => o) end end def check_CaseExpression(o) rvalue(o.test) # There should only be one LiteralDefault case option value # TODO: Implement this check end def check_CaseOption(o) o.values.each { |v| rvalue(v) } end def check_CollectExpression(o) unless o.type_expr.is_a? Model::QualifiedReference acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.type_expr, :feature=> 'type name', :container => o) end # If a collect expression tries to collect exported resources and storeconfigs is not on # then it will not work... This was checked in the parser previously. This is a runtime checking # thing as opposed to a language thing. if acceptor.will_accept?(Issues::RT_NO_STORECONFIGS) && o.query.is_a?(Model::ExportedQuery) acceptor.accept(Issues::RT_NO_STORECONFIGS, o) end end # Only used for function names, grammar should not be able to produce something faulty, but # check anyway if model is created programatically (it will fail in transformation to AST for sure). def check_NamedAccessExpression(o) name = o.right_expr unless name.is_a? Model::QualifiedName acceptor.accept(Issues::ILLEGAL_EXPRESSION, name, :feature=> 'function name', :container => o.eContainer) end end # for 'class', 'define', and function def check_NamedDefinition(o) top(o.eContainer, o) if o.name !~ Puppet::Pops::Patterns::CLASSREF acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name}) end end - def check_FunctionDefinition(o) - # super class check - check_NamedDefinition(o) - end - def check_IfExpression(o) rvalue(o.test) end def check_KeyedEntry(o) rvalue(o.key) rvalue(o.value) # In case there are additional things to forbid than non-rvalues # acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.key, :feature => 'hash key', :container => o.eContainer) end # A Lambda is a Definition, but it may appear in other scopes than top scope (Which check_Definition asserts). # def check_LambdaExpression(o) end def check_LiteralList(o) o.values.each {|v| rvalue(v) } end def check_NodeDefinition(o) # Check that hostnames are valid hostnames (or regular expressions) hostname(o.host_matches, o) hostname(o.parent, o, 'parent') unless o.parent.nil? top(o.eContainer, o) end # No checking takes place - all expressions using a QualifiedName need to check. This because the # rules are slightly different depending on the container (A variable allows a numeric start, but not # other names). This means that (if the lexer/parser so chooses) a QualifiedName # can be anything when it represents a Bare Word and evaluates to a String. # def check_QualifiedName(o) end # Checks that the value is a valid UpperCaseWord (a CLASSREF), and optionally if it contains a hypen. # DOH: QualifiedReferences are created with LOWER CASE NAMES at parse time def check_QualifiedReference(o) # Is this a valid qualified name? if o.value !~ Puppet::Pops::Patterns::CLASSREF acceptor.accept(Issues::ILLEGAL_CLASSREF, o, {:name=>o.value}) end end def check_QueryExpression(o) query(o.expr) if o.expr # is optional end def relation_Object(o) rvalue(o) end def relation_CollectExpression(o); end def relation_RelationshipExpression(o); end def check_Parameter(o) if o.name =~ /^[0-9]+$/ acceptor.accept(Issues::ILLEGAL_NUMERIC_PARAMETER, o, :name => o.name) end end #relationship_side: resource # | resourceref # | collection # | variable # | quotedtext # | selector # | casestatement # | hasharrayaccesses def check_RelationshipExpression(o) relation(o.left_expr) relation(o.right_expr) end def check_ResourceExpression(o) # A resource expression must have a lower case NAME as its type e.g. 'file { ... }' unless o.type_name.is_a? Model::QualifiedName acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.type_name, :feature => 'resource type', :container => o) 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 acceptor.accept(Issues::RT_NO_STORECONFIGS_EXPORT, o) end end def check_ResourceDefaultsExpression(o) if o.form && o.form != :regular acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o) end end def check_SelectorExpression(o) rvalue(o.left_expr) end def check_SelectorEntry(o) rvalue(o.matching_expr) end def check_UnaryExpression(o) rvalue(o.expr) end def check_UnlessExpression(o) rvalue(o.test) # TODO: Unless may not have an else part that is an IfExpression (grammar denies this though) end # Checks that variable is either strictly 0, or a non 0 starting decimal number, or a valid VAR_NAME def check_VariableExpression(o) # The expression must be a qualified name if !o.expr.is_a?(Model::QualifiedName) acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, :feature => 'name', :container => o) else # name must be either a decimal value, or a valid NAME name = o.expr.value if name[0,1] =~ /[0-9]/ unless name =~ Puppet::Pops::Patterns::NUMERIC_VAR_NAME acceptor.accept(Issues::ILLEGAL_NUMERIC_VAR_NAME, o, :name => name) end else unless name =~ Puppet::Pops::Patterns::VAR_NAME acceptor.accept(Issues::ILLEGAL_VAR_NAME, o, :name => name) end end end end #--- HOSTNAME CHECKS # Transforms Array of host matching expressions into a (Ruby) array of AST::HostName def hostname_Array(o, semantic, single_feature_name) if single_feature_name acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature=>single_feature_name, :container=>semantic}) end o.each {|x| hostname(x, semantic, false) } end def hostname_String(o, semantic, single_feature_name) # The 3.x checker only checks for illegal characters - if matching /[^-\w.]/ the name is invalid, # but this allows pathological names like "a..b......c", "----" # TODO: Investigate if more illegal hostnames should be flagged. # if o =~ Puppet::Pops::Patterns::ILLEGAL_HOSTNAME_CHARS acceptor.accept(Issues::ILLEGAL_HOSTNAME_CHARS, semantic, :hostname => o) end end def hostname_LiteralValue(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end def hostname_ConcatenatedString(o, semantic, single_feature_name) # Puppet 3.1. only accepts a concatenated string without interpolated expressions if the_expr = o.segments.index {|s| s.is_a?(Model::TextExpression) } acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o.segments[the_expr].expr) elsif o.segments.size() != 1 # corner case, bad model, concatenation of several plain strings acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o) else # corner case, may be ok, but lexer may have replaced with plain string, this is # here if it does not hostname_String(o.segments[0], o.segments[0], false) end end def hostname_QualifiedName(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end def hostname_QualifiedReference(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end def hostname_LiteralNumber(o, semantic, single_feature_name) # always ok end def hostname_LiteralDefault(o, semantic, single_feature_name) # always ok end def hostname_LiteralRegularExpression(o, semantic, single_feature_name) # always ok end def hostname_Object(o, semantic, single_feature_name) acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature=> single_feature_name || 'hostname', :container=>semantic}) end #---QUERY CHECKS # Anything not explicitly allowed is flagged as error. def query_Object(o) acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) end # Puppet AST only allows == and != # def query_ComparisonExpression(o) acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) unless [:'==', :'!='].include? o.operator end # Allows AND, OR, and checks if left/right are allowed in query. def query_BooleanExpression(o) query o.left_expr query o.right_expr end def query_ParenthesizedExpression(o) query(o.expr) end def query_VariableExpression(o); end def query_QualifiedName(o); end def query_LiteralNumber(o); end def query_LiteralString(o); end def query_LiteralBoolean(o); end #---RVALUE CHECKS # By default, all expressions are reported as being rvalues # Implement specific rvalue checks for those that are not. # def rvalue_Expression(o); end def rvalue_ResourceDefaultsExpression(o); acceptor.accept(Issues::NOT_RVALUE, o) ; end def rvalue_ResourceOverrideExpression(o); acceptor.accept(Issues::NOT_RVALUE, o) ; end def rvalue_CollectExpression(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end def rvalue_Definition(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end def rvalue_NodeDefinition(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end def rvalue_UnaryExpression(o) ; rvalue o.expr ; end #---TOP CHECK def top_NilClass(o, definition) # ok, reached the top, no more parents end def top_Object(o, definition) # fail, reached a container that is not top level acceptor.accept(Issues::NOT_TOP_LEVEL, definition) end def top_BlockExpression(o, definition) # ok, if this is a block representing the body of a class, or is top level top o.eContainer, definition end def top_HostClassDefinition(o, definition) # ok, stop scanning parents end def top_Program(o, definition) # ok end # A LambdaExpression is a BlockExpression, and this method is needed to prevent the polymorph method for BlockExpression # to accept a lambda. # A lambda can not iteratively create classes, nodes or defines as the lambda does not have a closure. # def top_LambdaExpression(o, definition) # fail, stop scanning parents acceptor.accept(Issues::NOT_TOP_LEVEL, definition) end #--- NON POLYMORPH, NON CHECKING CODE # Produces string part of something named, or nil if not a QualifiedName or QualifiedReference # def varname_to_s(o) case o when Model::QualifiedName o.value when Model::QualifiedReference o.value else nil end end end diff --git a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_a.pp b/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_a.pp deleted file mode 100644 index fb4238340..000000000 --- a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_a.pp +++ /dev/null @@ -1 +0,0 @@ -function modulea::func_a() { "I am modulea::func_a()" } \ No newline at end of file diff --git a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_b.pp b/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_b.pp deleted file mode 100644 index c0ebd62d7..000000000 --- a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/func_b.pp +++ /dev/null @@ -1,2 +0,0 @@ -# Is not namespaces on purpose to trigger error -function func_b() { "I am func_a()" } \ No newline at end of file diff --git a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/nested/func_a.pp b/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/nested/func_a.pp deleted file mode 100644 index 17ed2ac58..000000000 --- a/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/nested/func_a.pp +++ /dev/null @@ -1 +0,0 @@ -function modulea::nested::func_a() { "I am modulea::nested::func_a()" } \ No newline at end of file diff --git a/spec/unit/pops/loaders/dependency_loader_spec.rb b/spec/unit/pops/loaders/dependency_loader_spec.rb index de4289e7a..5f12528a2 100644 --- a/spec/unit/pops/loaders/dependency_loader_spec.rb +++ b/spec/unit/pops/loaders/dependency_loader_spec.rb @@ -1,40 +1,43 @@ require 'spec_helper' require 'puppet_spec/files' require 'puppet/pops' require 'puppet/loaders' describe 'dependency loader' do include PuppetSpec::Files let(:static_loader) { Puppet::Pops::Loader::StaticLoader.new() } describe 'FileBased module loader' do it 'load something in global name space raises an error' do module_dir = dir_containing('testmodule', { - 'functions' => { - 'foo.pp' => 'function foo() { yay }'}}) + 'lib' => { 'puppet' => { 'functions' => { 'testmodule' => { + 'foo.rb' => 'Puppet::Functions.create_function("foo") { def foo; end; }' + }}}}}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') dep_loader = Puppet::Pops::Loader::DependencyLoader.new(static_loader, 'test-dep', [module_loader]) expect do dep_loader.load_typed(typed_name(:function, 'testmodule::foo')).value - end.to raise_error(ArgumentError, /produced function with the wrong name, expected testmodule::foo, actual foo/) + end.to raise_error(ArgumentError, /produced mis-matched name, expected 'testmodule::foo', got foo/) end it 'can load something in a qualified name space' do module_dir = dir_containing('testmodule', { - 'functions' => { - 'foo.pp' => 'function testmodule::foo() { yay }'}}) - + 'lib' => { 'puppet' => { 'functions' => { 'testmodule' => { + 'foo.rb' => 'Puppet::Functions.create_function("testmodule::foo") { def foo; end; }' + }}}}}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') dep_loader = Puppet::Pops::Loader::DependencyLoader.new(static_loader, 'test-dep', [module_loader]) + function = dep_loader.load_typed(typed_name(:function, 'testmodule::foo')).value + expect(function.class.name).to eq('testmodule::foo') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end end def typed_name(type, name) Puppet::Pops::Loader::Loader::TypedName.new(type, name) end end diff --git a/spec/unit/pops/loaders/loader_paths_spec.rb b/spec/unit/pops/loaders/loader_paths_spec.rb index c17861e59..4e098a097 100644 --- a/spec/unit/pops/loaders/loader_paths_spec.rb +++ b/spec/unit/pops/loaders/loader_paths_spec.rb @@ -1,74 +1,71 @@ require 'spec_helper' require 'puppet_spec/files' require 'puppet/pops' require 'puppet/loaders' describe 'loader paths' do include PuppetSpec::Files before(:each) { Puppet[:biff] = true } let(:static_loader) { Puppet::Pops::Loader::StaticLoader.new() } it 'expects dir_containing to create a temp directory structure from a hash' do module_dir = dir_containing('testmodule', { 'test.txt' => 'Hello world', 'sub' => { 'foo.txt' => 'foo'}}) expect(File.read(File.join(module_dir, 'test.txt'))).to be_eql('Hello world') expect(File.read(File.join(module_dir, 'sub', 'foo.txt'))).to be_eql('foo') end describe 'the relative_path_for_types method' do it 'produces paths to load in precendence order' do module_dir = dir_containing('testmodule', { 'functions' => {}, 'lib' => { 'puppet' => { 'functions' => {}, 'parser' => { 'functions' => {}, } }}}) # Must have a File/Path based loader to talk to module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') effective_paths = Puppet::Pops::Loader::LoaderPaths.relative_paths_for_type(:function, module_loader) - expect(effective_paths.size).to be_eql(3) + expect(effective_paths.size).to be_eql(2) # 4x expect(effective_paths[0].generic_path).to be_eql(File.join(module_dir, 'lib', 'puppet', 'functions')) # 3x expect(effective_paths[1].generic_path).to be_eql(File.join(module_dir, 'lib', 'puppet','parser', 'functions')) - # .pp - expect(effective_paths[2].generic_path).to be_eql(File.join(module_dir, 'functions')) end it 'module loader has smart-paths that prunes unavailable paths' do - module_dir = dir_containing('testmodule', {'functions' => {'foo.pp' => 'function foo() { yay }'} }) - # Must have a File/Path based loader to talk to + module_dir = dir_containing('testmodule', {'lib' => {'puppet' => {'functions' => {'foo.rb' => 'Puppet::Functions.create_function("testmodule::foo") { def foo; end; }' }}}}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') + effective_paths = module_loader.smart_paths.effective_paths(:function) + expect(effective_paths.size).to be_eql(1) - expect(effective_paths[0].generic_path).to be_eql(File.join(module_dir, 'functions')) + expect(effective_paths[0].generic_path).to be_eql(File.join(module_dir, 'lib', 'puppet', 'functions')) expect(module_loader.path_index.size).to be_eql(1) - expect(module_loader.path_index.include?(File.join(module_dir, 'functions', 'foo.pp'))).to be(true) + expect(module_loader.path_index.include?(File.join(module_dir, 'lib', 'puppet', 'functions', 'foo.rb'))).to be(true) end it 'all function smart-paths produces entries if they exist' do module_dir = dir_containing('testmodule', { - 'functions' => {'foo.pp' => 'function foo() { yay }'}, 'lib' => { 'puppet' => { 'functions' => {'foo4x.rb' => 'ignored in this test'}, 'parser' => { 'functions' => {'foo3x.rb' => 'ignored in this test'}, } }}}) # Must have a File/Path based loader to talk to module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') effective_paths = module_loader.smart_paths.effective_paths(:function) - expect(effective_paths.size).to eq(3) - expect(module_loader.path_index.size).to eq(3) + expect(effective_paths.size).to eq(2) + expect(module_loader.path_index.size).to eq(2) path_index = module_loader.path_index - expect(path_index.include?(File.join(module_dir, 'functions', 'foo.pp'))).to eq(true) expect(path_index.include?(File.join(module_dir, 'lib', 'puppet', 'functions', 'foo4x.rb'))).to eq(true) expect(path_index.include?(File.join(module_dir, 'lib', 'puppet', 'parser', 'functions', 'foo3x.rb'))).to eq(true) end end end diff --git a/spec/unit/pops/loaders/loaders_spec.rb b/spec/unit/pops/loaders/loaders_spec.rb index e5d12f217..a3ee91ac3 100644 --- a/spec/unit/pops/loaders/loaders_spec.rb +++ b/spec/unit/pops/loaders/loaders_spec.rb @@ -1,86 +1,78 @@ require 'spec_helper' require 'puppet_spec/files' require 'puppet/pops' require 'puppet/loaders' describe 'loaders' do include PuppetSpec::Files def config_dir(config_name) my_fixture(config_name) end # Loaders caches the puppet_system_loader, must reset between tests # before(:each) { Puppet::Pops::Loaders.clear() } it 'creates a puppet_system loader' do loaders = Puppet::Pops::Loaders.new() expect(loaders.puppet_system_loader().class).to be(Puppet::Pops::Loader::ModuleLoaders::FileBased) end it 'creates an environment loader' do loaders = Puppet::Pops::Loaders.new() # When this test is running, there is no environments dir configured, and a NullLoader is therefore used a.t.m expect(loaders.public_environment_loader().class).to be(Puppet::Pops::Loader::SimpleEnvironmentLoader) # The default name of the enironment is '*root*', and the loader should identify itself that way expect(loaders.public_environment_loader().to_s).to eql("(SimpleEnvironmentLoader 'environment:*root*')") expect(loaders.private_environment_loader().class).to be(Puppet::Pops::Loader::DependencyLoader) expect(loaders.private_environment_loader().to_s).to eql("(DependencyLoader 'environment' [])") end context 'when delegating 3x to 4x' do before(:each) { Puppet[:biff] = true } it 'the puppet system loader can load 3x functions' do loaders = Puppet::Pops::Loaders.new() puppet_loader = loaders.puppet_system_loader() function = puppet_loader.load_typed(typed_name(:function, 'sprintf')).value expect(function.class.name).to eq('sprintf') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end end # TODO: LOADING OF MODULES ON MODULEPATH context 'loading from path with single module' do before do env = Puppet::Node::Environment.create(:'*test*', [File.join(config_dir('single_module'), 'modules')], '') overrides = { :current_environment => env } Puppet.push_context(overrides, "single-module-test-loaders") end after do Puppet.pop_context() end it 'can load from a module path' do loaders = Puppet::Pops::Loaders.new() modulea_loader = loaders.public_loader_for_module('modulea') expect(modulea_loader.class).to eql(Puppet::Pops::Loader::ModuleLoaders::FileBased) - function = modulea_loader.load_typed(typed_name(:function, 'modulea::func_a')).value - expect(function.is_a?(Puppet::Functions::Function)).to eq(true) - expect(function.class.name).to eq('modulea::func_a') - - function = modulea_loader.load_typed(typed_name(:function, 'modulea::nested::func_a')).value - expect(function.is_a?(Puppet::Functions::Function)).to eq(true) - expect(function.class.name).to eq('modulea::nested::func_a') - function = modulea_loader.load_typed(typed_name(:function, 'rb_func_a')).value expect(function.is_a?(Puppet::Functions::Function)).to eq(true) expect(function.class.name).to eq('rb_func_a') function = modulea_loader.load_typed(typed_name(:function, 'modulea::rb_func_a')).value expect(function.is_a?(Puppet::Functions::Function)).to eq(true) expect(function.class.name).to eq('modulea::rb_func_a') end end def typed_name(type, name) Puppet::Pops::Loader::Loader::TypedName.new(type, name) end -end \ No newline at end of file +end diff --git a/spec/unit/pops/loaders/module_loaders_spec.rb b/spec/unit/pops/loaders/module_loaders_spec.rb index 9c73ab858..24bad0cf4 100644 --- a/spec/unit/pops/loaders/module_loaders_spec.rb +++ b/spec/unit/pops/loaders/module_loaders_spec.rb @@ -1,134 +1,122 @@ require 'spec_helper' require 'puppet_spec/files' require 'puppet/pops' require 'puppet/loaders' describe 'module loaders' do include PuppetSpec::Files let(:static_loader) { Puppet::Pops::Loader::StaticLoader.new() } describe 'FileBased module loader' do - it 'loading a .pp function in global name space raises an error' do - module_dir = dir_containing('testmodule', { - 'functions' => { - 'foo.pp' => 'function foo() { yay }'}}) - - module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') - expect do - module_loader.load_typed(typed_name(:function, 'testmodule::foo')).value - end.to raise_error(ArgumentError, /produced function with the wrong name, expected testmodule::foo, actual foo/) - - end - - it 'can load a .pp function in a qualified name space' do - module_dir = dir_containing('testmodule', { - 'functions' => { - 'foo.pp' => 'function testmodule::foo() { yay }'}}) - - module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') - function = module_loader.load_typed(typed_name(:function, 'testmodule::foo')).value - expect(function.class.name).to eq('testmodule::foo') - expect(function.is_a?(Puppet::Functions::Function)).to eq(true) - end - it 'can load a 4x function API ruby function in global name space' do module_dir = dir_containing('testmodule', { 'lib' => { 'puppet' => { 'functions' => { 'foo4x.rb' => <<-CODE Puppet::Functions.create_function(:foo4x) do def foo4x() 'yay' end end CODE } } } }) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') function = module_loader.load_typed(typed_name(:function, 'foo4x')).value expect(function.class.name).to eq('foo4x') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end it 'can load a 4x function API ruby function in qualified name space' do module_dir = dir_containing('testmodule', { 'lib' => { 'puppet' => { 'functions' => { 'testmodule' => { 'foo4x.rb' => <<-CODE Puppet::Functions.create_function('testmodule::foo4x') do def foo4x() 'yay' end end CODE } } } }}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') function = module_loader.load_typed(typed_name(:function, 'testmodule::foo4x')).value expect(function.class.name).to eq('testmodule::foo4x') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end it 'makes parent loader win over entries in child' do module_dir = dir_containing('testmodule', { - 'functions' => { - 'foo.pp' => 'function testmodule::foo() { yay }'}}) - + 'lib' => { 'puppet' => { 'functions' => { 'testmodule' => { + 'foo.rb' => <<-CODE + Puppet::Functions.create_function('testmodule::foo') do + def foo() + 'yay' + end + end + CODE + }}}}}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') - module_dir2 = dir_containing('testmodule2', { - 'functions' => { - 'foo.pp' => 'fail(should not happen)'}}) + module_dir2 = dir_containing('testmodule2', { + 'lib' => { 'puppet' => { 'functions' => { 'testmodule2' => { + 'foo.rb' => <<-CODE + raise "should not get here" + CODE + }}}}}) module_loader2 = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(module_loader, 'testmodule2', module_dir2, 'test2') + function = module_loader2.load_typed(typed_name(:function, 'testmodule::foo')).value + expect(function.class.name).to eq('testmodule::foo') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end context 'when delegating 3x to 4x' do before(:each) { Puppet[:biff] = true } it 'can load a 3x function API ruby function in global name space' do module_dir = dir_containing('testmodule', { 'lib' => { 'puppet' => { 'parser' => { 'functions' => { 'foo3x.rb' => <<-CODE Puppet::Parser::Functions::newfunction( :foo3x, :type => :rvalue, :arity => 1 ) do |args| args[0] end CODE } } } }}) module_loader = Puppet::Pops::Loader::ModuleLoaders::FileBased.new(static_loader, 'testmodule', module_dir, 'test1') function = module_loader.load_typed(typed_name(:function, 'foo3x')).value expect(function.class.name).to eq('foo3x') expect(function.is_a?(Puppet::Functions::Function)).to eq(true) end end # Gives error when loading something with mismatched name end def typed_name(type, name) Puppet::Pops::Loader::Loader::TypedName.new(type, name) end end diff --git a/spec/unit/pops/parser/parse_functions_spec.rb b/spec/unit/pops/parser/parse_functions_spec.rb deleted file mode 100644 index 27be1d046..000000000 --- a/spec/unit/pops/parser/parse_functions_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' -require 'puppet/pops' - -# relative to this spec file (./) does not work as this file is loaded by rspec -require File.join(File.dirname(__FILE__), '/parser_rspec_helper') - -describe "egrammar parsing function definitions" do - include ParserRspecHelper - - context "when defining a function" do - it "it can be dumped" do - dump(parse("function foo() { }")).should == "(function foo ())" - end - - it "un typed parameters are dumped" do - dump(parse("function foo($a) { }")).should == "(function foo (parameters a) ())" - end - - it "typed parameters are dumped" do - pending "typed parameters PUP-514" - dump(parse("function foo(String $a) { }")).should == "(function foo (parameters (t string a)) ())" - end - - it "last captures rest is dumped" do - pending "last captures rest PUP-514 related" - dump(parse("function foo(String *$a) { }")).should == "(function foo (parameters (t string *a)) ())" - end - - it "the body is dumped" do - dump(parse("function foo() { 10 }")).should == "(function foo (block 10))" - end - end -end