diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index 6af7745e9..06adb8baa 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -1,118 +1,119 @@ # the parent class for all of our syntactical objects require 'puppet' require 'puppet/util/autoload' require 'puppet/file_collection/lookup' # The base class for all of the objects that make up the parse trees. # Handles things like file name, line #, and also does the initialization # for all of the parameters of all of the child objects. class Puppet::Parser::AST # Do this so I don't have to type the full path in all of the subclasses AST = Puppet::Parser::AST include Puppet::FileCollection::Lookup include Puppet::Util::Errors include Puppet::Util::MethodHelper include Puppet::Util::Docs attr_accessor :parent, :scope # don't fetch lexer comment by default def use_docs self.class.use_docs end # allow our subclass to specify they want documentation class << self attr_accessor :use_docs def associates_doc self.use_docs = true end end # Does this ast object set something? If so, it gets evaluated first. def self.settor? if defined? @settor @settor else false end end # Evaluate the current object. Just a stub method, since the subclass # should override this method. # of the contained children and evaluates them in turn, returning a # list of all of the collected values, rejecting nil values def evaluate(*options) raise Puppet::DevError, "Did not override #evaluate in %s" % self.class end # Throw a parse error. def parsefail(message) self.fail(Puppet::ParseError, message) end # Wrap a statemp in a reusable way so we always throw a parse error. def parsewrap exceptwrap :type => Puppet::ParseError do yield end end # The version of the evaluate method that should be called, because it # correctly handles errors. It is critical to use this method because # it can enable you to catch the error where it happens, rather than # much higher up the stack. def safeevaluate(*options) # We duplicate code here, rather than using exceptwrap, because this # is called so many times during parsing. begin return self.evaluate(*options) rescue Puppet::Error => detail raise adderrorcontext(detail) rescue => detail error = Puppet::Error.new(detail.to_s) # We can't use self.fail here because it always expects strings, # not exceptions. raise adderrorcontext(error, detail) end end # Initialize the object. Requires a hash as the argument, and # takes each of the parameters of the hash and calls the settor # method for them. This is probably pretty inefficient and should # likely be changed at some point. def initialize(args) set_options(args) end end # And include all of the AST subclasses. require 'puppet/parser/ast/arithmetic_operator' require 'puppet/parser/ast/astarray' require 'puppet/parser/ast/asthash' require 'puppet/parser/ast/branch' require 'puppet/parser/ast/boolean_operator' require 'puppet/parser/ast/caseopt' require 'puppet/parser/ast/casestatement' require 'puppet/parser/ast/collection' require 'puppet/parser/ast/collexpr' require 'puppet/parser/ast/comparison_operator' require 'puppet/parser/ast/else' require 'puppet/parser/ast/function' require 'puppet/parser/ast/ifstatement' require 'puppet/parser/ast/leaf' require 'puppet/parser/ast/match_operator' require 'puppet/parser/ast/minus' require 'puppet/parser/ast/nop' require 'puppet/parser/ast/not' require 'puppet/parser/ast/resource' require 'puppet/parser/ast/resource_defaults' require 'puppet/parser/ast/resource_override' require 'puppet/parser/ast/resource_reference' require 'puppet/parser/ast/resourceparam' require 'puppet/parser/ast/selector' require 'puppet/parser/ast/tag' require 'puppet/parser/ast/vardef' +require 'puppet/parser/ast/relationship' diff --git a/lib/puppet/parser/ast/relationship.rb b/lib/puppet/parser/ast/relationship.rb new file mode 100644 index 000000000..9f9f6fc1d --- /dev/null +++ b/lib/puppet/parser/ast/relationship.rb @@ -0,0 +1,60 @@ +require 'puppet/parser/ast' +require 'puppet/parser/ast/branch' +require 'puppet/parser/relationship' + +class Puppet::Parser::AST::Relationship < Puppet::Parser::AST::Branch + RELATIONSHIP_TYPES = %w{-> <- ~> <~} + + attr_accessor :left, :right, :arrow, :type + + def actual_left + chained? ? left.right : left + end + + # Evaluate our object, but just return a simple array of the type + # and name. + def evaluate(scope) + if chained? + real_left = left.safeevaluate(scope) + left_dep = left_dep.shift if left_dep.is_a?(Array) + else + real_left = left.safeevaluate(scope) + end + real_right = right.safeevaluate(scope) + + source, target = sides2edge(real_left, real_right) + result = Puppet::Parser::Relationship.new(source, target, type) + scope.compiler.add_relationship(result) + real_right + end + + def initialize(left, right, arrow, args = {}) + super(args) + unless RELATIONSHIP_TYPES.include?(arrow) + raise ArgumentError, "Invalid relationship type #{arrow.inspect}; valid types are #{RELATIONSHIP_TYPES.collect { |r| r.to_s }.join(", ")}" + end + @left, @right, @arrow = left, right, arrow + end + + def type + subscription? ? :subscription : :relationship + end + + def sides2edge(left, right) + out_edge? ? [left, right] : [right, left] + end + + private + + def chained? + left.is_a?(self.class) + end + + def out_edge? + ["->", "~>"].include?(arrow) + end + + def subscription? + ["~>", "<~"].include?(arrow) + end +end diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb index 8e84f5a5b..fd7d9680b 100644 --- a/lib/puppet/parser/compiler.rb +++ b/lib/puppet/parser/compiler.rb @@ -1,410 +1,423 @@ # Created by Luke A. Kanies on 2007-08-13. # Copyright (c) 2007. All rights reserved. require 'puppet/node' require 'puppet/resource/catalog' require 'puppet/util/errors' require 'puppet/resource/type_collection_helper' # Maintain a graph of scopes, along with a bunch of data # about the individual catalog we're compiling. class Puppet::Parser::Compiler include Puppet::Util include Puppet::Util::Errors include Puppet::Resource::TypeCollectionHelper def self.compile(node) new(node).compile.to_resource rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "#{detail} on node #{node.name}" end - attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources + attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships # Add a collection to the global list. def add_collection(coll) @collections << coll end + def add_relationship(dep) + @relationships << dep + end + # Store a resource override. def add_override(override) # If possible, merge the override in immediately. if resource = @catalog.resource(override.ref) resource.merge(override) else # Otherwise, store the override for later; these # get evaluated in Resource#finish. @resource_overrides[override.ref] << override end end # Store a resource in our resource table. def add_resource(scope, resource) @resources << resource # Note that this will fail if the resource is not unique. @catalog.add_resource(resource) # And in the resource graph. At some point, this might supercede # the global resource table, but the table is a lot faster # so it makes sense to maintain for now. if resource.type.to_s.downcase == "class" and main = @catalog.resource(:class, :main) @catalog.add_edge(main, resource) else @catalog.add_edge(scope.resource, resource) end end # Do we use nodes found in the code, vs. the external node sources? def ast_nodes? known_resource_types.nodes? end # Store the fact that we've evaluated a class def add_class(name) @catalog.add_class(name) unless name == "" end # Return a list of all of the defined classes. def classlist return @catalog.classes end # Compiler our catalog. This mostly revolves around finding and evaluating classes. # This is the main entry into our catalog. def compile # Set the client's parameters into the top scope. set_node_parameters() evaluate_main() evaluate_ast_node() evaluate_node_classes() evaluate_generators() finish() fail_on_unevaluated() return @catalog end # LAK:FIXME There are no tests for this. def delete_collection(coll) @collections.delete(coll) if @collections.include?(coll) end # Return the node's environment. def environment unless defined? @environment if node.environment and node.environment != "" @environment = node.environment else @environment = nil end end @environment end # Evaluate all of the classes specified by the node. def evaluate_node_classes evaluate_classes(@node.classes, topscope) end # Evaluate each specified class in turn. If there are any classes we can't # find, just tag the catalog and move on. This method really just # creates resource objects that point back to the classes, and then the # resources are themselves evaluated later in the process. def evaluate_classes(classes, scope, lazy_evaluate = true) unless scope.source raise Puppet::DevError, "No source for scope passed to evaluate_classes" end found = [] classes.each do |name| # If we can find the class, then make a resource that will evaluate it. if klass = scope.find_hostclass(name) found << name and next if scope.class_scope(klass) resource = klass.mk_plain_resource(scope) # If they've disabled lazy evaluation (which the :include function does), # then evaluate our resource immediately. resource.evaluate unless lazy_evaluate found << name else Puppet.info "Could not find class %s for %s" % [name, node.name] @catalog.tag(name) end end found end + def evaluate_relationships + @relationships.each { |rel| rel.evaluate(catalog) } + end + # Return a resource by either its ref or its type and title. def findresource(*args) @catalog.resource(*args) end def initialize(node, options = {}) @node = node options.each do |param, value| begin send(param.to_s + "=", value) rescue NoMethodError raise ArgumentError, "Compiler objects do not accept %s" % param end end initvars() init_main() end # Create a new scope, with either a specified parent scope or # using the top scope. def newscope(parent, options = {}) parent ||= topscope options[:compiler] = self scope = Puppet::Parser::Scope.new(options) scope.parent = parent scope end # Return any overrides for the given resource. def resource_overrides(resource) @resource_overrides[resource.ref] end # The top scope is usually the top-level scope, but if we're using AST nodes, # then it is instead the node's scope. def topscope node_scope || @topscope end private # If ast nodes are enabled, then see if we can find and evaluate one. def evaluate_ast_node return unless ast_nodes? # Now see if we can find the node. astnode = nil @node.names.each do |name| break if astnode = known_resource_types.node(name.to_s.downcase) end unless (astnode ||= known_resource_types.node("default")) raise Puppet::ParseError, "Could not find default node or by name with '%s'" % node.names.join(", ") end # Create a resource to model this node, and then add it to the list # of resources. resource = astnode.mk_plain_resource(topscope) resource.evaluate # Now set the node scope appropriately, so that :topscope can # behave differently. @node_scope = topscope.class_scope(astnode) end # Evaluate our collections and return true if anything returned an object. # The 'true' is used to continue a loop, so it's important. def evaluate_collections return false if @collections.empty? found_something = false exceptwrap do # We have to iterate over a dup of the array because # collections can delete themselves from the list, which # changes its length and causes some collections to get missed. @collections.dup.each do |collection| found_something = true if collection.evaluate end end return found_something end # Make sure all of our resources have been evaluated into native resources. # We return true if any resources have, so that we know to continue the # evaluate_generators loop. def evaluate_definitions exceptwrap do if ary = unevaluated_resources evaluated = false ary.each do |resource| if not resource.virtual? resource.evaluate evaluated = true end end # If we evaluated, let the loop know. return evaluated else return false end end end # Iterate over collections and resources until we're sure that the whole # compile is evaluated. This is necessary because both collections # and defined resources can generate new resources, which themselves could # be defined resources. def evaluate_generators count = 0 loop do done = true # Call collections first, then definitions. done = false if evaluate_collections done = false if evaluate_definitions break if done count += 1 if count > 1000 raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host catalog" end end end # Find and evaluate our main object, if possible. def evaluate_main @main = known_resource_types.find_hostclass([""], "") || known_resource_types.add(Puppet::Resource::Type.new(:hostclass, "")) @topscope.source = @main @main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main) @topscope.resource = @main_resource @resources << @main_resource @catalog.add_resource(@main_resource) @main_resource.evaluate end # Make sure the entire catalog is evaluated. def fail_on_unevaluated fail_on_unevaluated_overrides fail_on_unevaluated_resource_collections end # If there are any resource overrides remaining, then we could # not find the resource they were supposed to override, so we # want to throw an exception. def fail_on_unevaluated_overrides remaining = [] @resource_overrides.each do |name, overrides| remaining += overrides end unless remaining.empty? fail Puppet::ParseError, "Could not find resource(s) %s for overriding" % remaining.collect { |o| o.ref }.join(", ") end end # Make sure we don't have any remaining collections that specifically # look for resources, because we want to consider those to be # parse errors. def fail_on_unevaluated_resource_collections remaining = [] @collections.each do |coll| # We're only interested in the 'resource' collections, # which result from direct calls of 'realize'. Anything # else is allowed not to return resources. # Collect all of them, so we have a useful error. if r = coll.resources if r.is_a?(Array) remaining += r else remaining << r end end end unless remaining.empty? raise Puppet::ParseError, "Failed to realize virtual resources %s" % remaining.join(', ') end end # Make sure all of our resources and such have done any last work # necessary. def finish + evaluate_relationships() + resources.each do |resource| # Add in any resource overrides. if overrides = resource_overrides(resource) overrides.each do |over| resource.merge(over) end # Remove the overrides, so that the configuration knows there # are none left. overrides.clear end resource.finish if resource.respond_to?(:finish) end end # Initialize the top-level scope, class, and resource. def init_main # Create our initial scope and a resource that will evaluate main. @topscope = Puppet::Parser::Scope.new(:compiler => self) end # Set up all of our internal variables. def initvars # The list of objects that will available for export. @exported_resources = {} # The list of overrides. This is used to cache overrides on objects # that don't exist yet. We store an array of each override. @resource_overrides = Hash.new do |overs, ref| overs[ref] = [] end # The list of collections that have been created. This is a global list, # but they each refer back to the scope that created them. @collections = [] + # The list of relationships to evaluate. + @relationships = [] + # For maintaining the relationship between scopes and their resources. @catalog = Puppet::Resource::Catalog.new(@node.name) @catalog.version = known_resource_types.version # local resource array to maintain resource ordering @resources = [] # Make sure any external node classes are in our class list @catalog.add_class(*@node.classes) end # Set the node's parameters into the top-scope as variables. def set_node_parameters node.parameters.each do |param, value| @topscope.setvar(param, value) end # These might be nil. catalog.client_version = node.parameters["clientversion"] catalog.server_version = node.parameters["serverversion"] end # Return an array of all of the unevaluated resources. These will be definitions, # which need to get evaluated into native resources. def unevaluated_resources ary = resources.reject { |resource| resource.builtin? or resource.evaluated? } if ary.empty? return nil else return ary end end end diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra index e125e327f..c505556ec 100644 --- a/lib/puppet/parser/grammar.ra +++ b/lib/puppet/parser/grammar.ra @@ -1,860 +1,872 @@ # vim: syntax=ruby # the parser class Puppet::Parser::Parser token STRING DQPRE DQMID DQPOST token LBRACK RBRACK LBRACE RBRACE SYMBOL FARROW COMMA TRUE token FALSE EQUALS APPENDS LESSEQUAL NOTEQUAL DOT COLON LLCOLLECT RRCOLLECT token QMARK LPAREN RPAREN ISEQUAL GREATEREQUAL GREATERTHAN LESSTHAN token IF ELSE IMPORT DEFINE ELSIF VARIABLE CLASS INHERITS NODE BOOLEAN token NAME SEMIC CASE DEFAULT AT LCOLLECT RCOLLECT CLASSNAME CLASSREF token NOT OR AND UNDEF PARROW PLUS MINUS TIMES DIV LSHIFT RSHIFT UMINUS -token MATCH NOMATCH REGEX +token MATCH NOMATCH REGEX IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB prechigh right NOT nonassoc UMINUS left MATCH NOMATCH left TIMES DIV left MINUS PLUS left LSHIFT RSHIFT left NOTEQUAL ISEQUAL left GREATEREQUAL GREATERTHAN LESSTHAN LESSEQUAL left AND left OR preclow rule program: statements { if val[0] # Make sure we always return an array. if val[0].is_a?(AST::ASTArray) if val[0].children.empty? result = nil else result = val[0] end else result = aryfy(val[0]) end else result = nil end } | nil statements: statement | statements statement { if val[0] and val[1] if val[0].instance_of?(AST::ASTArray) val[0].push(val[1]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[1]] end elsif obj = (val[0] || val[1]) result = obj else result = nil end } # The main list of valid statements statement: resource | virtualresource | collection | assignment | casestatement | ifstatement | import | fstatement | definition | hostclass | nodedef | resourceoverride | append + | relationship + +relationship: relationship_side edge relationship_side { + result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) +} + | relationship edge relationship_side { + result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) +} + +relationship_side: resource | resourceref | collection + +edge: IN_EDGE | OUT_EDGE | IN_EDGE_SUB | OUT_EDGE_SUB fstatement: NAME LPAREN funcvalues RPAREN { args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement } | NAME LPAREN funcvalues COMMA RPAREN { args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement } | NAME LPAREN RPAREN { result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => AST::ASTArray.new({}), :ftype => :statement } | NAME funcvalues { args = aryfy(val[1]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement } funcvalues: namestring | resourceref | funcvalues COMMA namestring { result = aryfy(val[0], val[2]) result.line = @lexer.line result.file = @lexer.file } | funcvalues COMMA resourceref { unless val[0].is_a?(AST::ASTArray) val[0] = aryfy(val[0]) end val[0].push(val[2]) result = val[0] } # This is *almost* an rvalue, but I couldn't get a full # rvalue to work without scads of shift/reduce conflicts. namestring: name | variable | type | boolean | funcrvalue | selector | quotedtext | hasharrayaccesses | CLASSNAME { result = ast AST::Name, :value => val[0][:value] } resource: classname LBRACE resourceinstances endsemi RBRACE { @lexer.commentpop array = val[2] if array.instance_of?(AST::ResourceInstance) array = [array] end result = ast AST::ASTArray # this iterates across each specified resourceinstance array.each { |instance| unless instance.instance_of?(AST::ResourceInstance) raise Puppet::Dev, "Got something that isn't an instance" end # now, i need to somehow differentiate between those things with # arrays in their names, and normal things result.push ast(AST::Resource, :type => val[0], :title => instance[0], :parameters => instance[1]) } } | classname LBRACE params endcomma RBRACE { # This is a deprecated syntax. error "All resource specifications require names" } | classref LBRACE params endcomma RBRACE { # a defaults setting for a type result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2]) } # Override a value set elsewhere in the configuration. resourceoverride: resourceref LBRACE anyparams endcomma RBRACE { @lexer.commentpop result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2] } # Exported and virtual resources; these don't get sent to the client # unless they get collected elsewhere in the db. virtualresource: at resource { type = val[0] if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect without storeconfigs being set") end if val[1].is_a? AST::ResourceDefaults error "Defaults are not virtualizable" end method = type.to_s + "=" # Just mark our resources as exported and pass them through. if val[1].instance_of?(AST::ASTArray) val[1].each do |obj| obj.send(method, true) end else val[1].send(method, true) end result = val[1] } at: AT { result = :virtual } | AT AT { result = :exported } # A collection statement. Currently supports no arguments at all, but eventually # will, I assume. collection: classref collectrhand LBRACE anyparams endcomma RBRACE { if val[0] =~ /^[a-z]/ Puppet.warning addcontext("Collection names must now be capitalized") end type = val[0].downcase args = {:type => type} if val[1].is_a?(AST::CollExpr) args[:query] = val[1] args[:query].type = type args[:form] = args[:query].form else args[:form] = val[1] end if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored") end args[:override] = val[3] result = ast AST::Collection, args } | classref collectrhand { if val[0] =~ /^[a-z]/ Puppet.warning addcontext("Collection names must now be capitalized") end type = val[0].downcase args = {:type => type } if val[1].is_a?(AST::CollExpr) args[:query] = val[1] args[:query].type = type args[:form] = args[:query].form else args[:form] = val[1] end if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored") end result = ast AST::Collection, args } collectrhand: LCOLLECT collstatements RCOLLECT { if val[1] result = val[1] result.form = :virtual else result = :virtual end } | LLCOLLECT collstatements RRCOLLECT { if val[1] result = val[1] result.form = :exported else result = :exported end } # A mini-language for handling collection comparisons. This is organized # to avoid the need for precedence indications. collstatements: nil | collstatement | collstatements colljoin collstatement { result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2] } collstatement: collexpr | LPAREN collstatements RPAREN { result = val[1] result.parens = true } colljoin: AND { result=val[0][:value] } | OR { result=val[0][:value] } collexpr: colllval ISEQUAL simplervalue { result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val } | colllval NOTEQUAL simplervalue { result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val } colllval: variable | name resourceinst: resourcename COLON params endcomma { result = ast AST::ResourceInstance, :children => [val[0],val[2]] } resourceinstances: resourceinst | resourceinstances SEMIC resourceinst { if val[0].instance_of?(AST::ResourceInstance) result = ast AST::ASTArray, :children => [val[0],val[2]] else val[0].push val[2] result = val[0] end } endsemi: # nothing | SEMIC undef: UNDEF { result = ast AST::Undef, :value => :undef } name: NAME { result = ast AST::Name, :value => val[0][:value], :line => val[0][:line] } type: CLASSREF { result = ast AST::Type, :value => val[0][:value], :line => val[0][:line] } resourcename: quotedtext | name | type | selector | variable | array | hasharrayaccesses assignment: VARIABLE EQUALS expression { if val[0][:value] =~ /::/ raise Puppet::ParseError, "Cannot assign to variables in other namespaces" end # this is distinct from referencing a variable variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line] } | hasharrayaccess EQUALS expression { result = ast AST::VarDef, :name => val[0], :value => val[2] } append: VARIABLE APPENDS expression { variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line] } params: # nothing { result = ast AST::ASTArray } | param { result = val[0] } | params COMMA param { if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end } param: NAME FARROW rvalue { result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2] } addparam: NAME PARROW rvalue { result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2], :add => true } anyparam: param | addparam anyparams: # nothing { result = ast AST::ASTArray } | anyparam { result = val[0] } | anyparams COMMA anyparam { if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end } rvalues: rvalue | rvalues comma rvalue { if val[0].instance_of?(AST::ASTArray) result = val[0].push(val[2]) else result = ast AST::ASTArray, :children => [val[0],val[2]] end } simplervalue: quotedtext | name | type | boolean | selector | variable rvalue: quotedtext | name | type | boolean | selector | variable | array | hash | hasharrayaccesses | resourceref | funcrvalue | undef # We currently require arguments in these functions. funcrvalue: NAME LPAREN funcvalues RPAREN { args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :rvalue } | NAME LPAREN RPAREN { result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => AST::ASTArray.new({}), :ftype => :rvalue } quotedtext: STRING { result = ast AST::String, :value => val[0][:value], :line => val[0][:line] } | DQPRE dqrval { result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] } dqrval: expression dqtail { result = [val[0]] + val[1] } dqtail: DQPOST { result = [ast(AST::String,val[0])] } | DQMID dqrval { result = [ast(AST::String,val[0])] + val[1] } boolean: BOOLEAN { result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line] } resourceref: NAME LBRACK rvalues RBRACK { Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized") result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2] } | classref LBRACK rvalues RBRACK { result = ast AST::ResourceReference, :type => val[0], :title => val[2] } ifstatement: IF expression LBRACE statements RBRACE else { @lexer.commentpop args = { :test => val[1], :statements => val[3] } if val[5] args[:else] = val[5] end result = ast AST::IfStatement, args } | IF expression LBRACE RBRACE else { @lexer.commentpop args = { :test => val[1], :statements => ast(AST::Nop) } if val[4] args[:else] = val[4] end result = ast AST::IfStatement, args } else: # nothing | ELSE LBRACE statements RBRACE { @lexer.commentpop result = ast AST::Else, :statements => val[2] } | ELSE LBRACE RBRACE { @lexer.commentpop result = ast AST::Else, :statements => ast(AST::Nop) } # Unlike yacc/bison, it seems racc # gives tons of shift/reduce warnings # with the following syntax: # # expression: ... # | expression arithop expressio { ... } # # arithop: PLUS | MINUS | DIVIDE | TIMES ... # # So I had to develop the expression by adding one rule # per operator :-( expression: rvalue | expression MATCH regex { result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression NOMATCH regex { result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression PLUS expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression MINUS expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression DIV expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression TIMES expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression LSHIFT expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression RSHIFT expression { result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | MINUS expression =UMINUS { result = ast AST::Minus, :value => val[1] } | expression NOTEQUAL expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression ISEQUAL expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression GREATERTHAN expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression GREATEREQUAL expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression LESSTHAN expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression LESSEQUAL expression { result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | NOT expression { result = ast AST::Not, :value => val[1] } | expression AND expression { result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | expression OR expression { result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] } | LPAREN expression RPAREN { result = val[1] } casestatement: CASE rvalue LBRACE caseopts RBRACE { @lexer.commentpop options = val[3] unless options.instance_of?(AST::ASTArray) options = ast AST::ASTArray, :children => [val[3]] end result = ast AST::CaseStatement, :test => val[1], :options => options } caseopts: caseopt | caseopts caseopt { if val[0].instance_of?(AST::ASTArray) val[0].push val[1] result = val[0] else result = ast AST::ASTArray, :children => [val[0], val[1]] end } caseopt: casevalues COLON LBRACE statements RBRACE { @lexer.commentpop result = ast AST::CaseOpt, :value => val[0], :statements => val[3] } | casevalues COLON LBRACE RBRACE { @lexer.commentpop result = ast(AST::CaseOpt, :value => val[0], :statements => ast(AST::ASTArray) ) } casevalues: selectlhand | casevalues COMMA selectlhand { if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end } selector: selectlhand QMARK svalues { result = ast AST::Selector, :param => val[0], :values => val[2] } svalues: selectval | LBRACE sintvalues endcomma RBRACE { @lexer.commentpop result = val[1] } sintvalues: selectval | sintvalues comma selectval { if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end } selectval: selectlhand FARROW rvalue { result = ast AST::ResourceParam, :param => val[0], :value => val[2] } selectlhand: name | type | quotedtext | variable | funcrvalue | boolean | undef | DEFAULT { result = ast AST::Default, :value => val[0][:value], :line => val[0][:line] } | regex # These are only used for importing, and we don't interpolate there. string: STRING { result = [val[0][:value]] } strings: string | strings COMMA string { result = val[0] += val[2] } import: IMPORT strings { val[1].each do |file| import(file) end result = AST::ASTArray.new(:children => []) } # Disable definition inheritance for now. 8/27/06, luke #definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE { definition: DEFINE classname argumentlist LBRACE statements RBRACE { @lexer.commentpop newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line] @lexer.indefine = false result = nil #} | DEFINE NAME argumentlist parent LBRACE RBRACE { } | DEFINE classname argumentlist LBRACE RBRACE { @lexer.commentpop newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line] @lexer.indefine = false result = nil } #hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE { hostclass: CLASS classname argumentlist classparent LBRACE statements RBRACE { @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line] result = nil } | CLASS classname argumentlist classparent LBRACE RBRACE { @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line] result = nil } nodedef: NODE hostnames nodeparent LBRACE statements RBRACE { @lexer.commentpop newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line] result = nil } | NODE hostnames nodeparent LBRACE RBRACE { @lexer.commentpop newnode val[1], :parent => val[2], :line => val[0][:line] result = nil } classref: CLASSREF { result = val[0][:value] } classname: NAME { result = val[0][:value] } | CLASSNAME { result = val[0][:value] } | CLASS { result = "class" } # Multiple hostnames, as used for node names. These are all literal # strings, not AST objects. hostnames: nodename | hostnames COMMA nodename { result = val[0] result = [result] unless result.is_a?(Array) result << val[2] } nodename: hostname { result = ast AST::HostName, :value => val[0] } hostname: NAME { result = val[0][:value] } | STRING { result = val[0][:value] } | DEFAULT { result = val[0][:value] } | regex nil: { result = nil } nothing: { result = ast AST::ASTArray, :children => [] } argumentlist: nil | LPAREN nothing RPAREN { result = nil } | LPAREN arguments RPAREN { result = val[1] result = [result] unless result[0].is_a?(Array) } arguments: argument | arguments COMMA argument { result = val[0] result = [result] unless result[0].is_a?(Array) result << val[2] } argument: NAME EQUALS rvalue { Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value], val[2]] } | NAME { Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value]] } | VARIABLE EQUALS rvalue { result = [val[0][:value], val[2]] } | VARIABLE { result = [val[0][:value]] } nodeparent: nil | INHERITS hostname { result = val[1] } classparent: nil | INHERITS classnameordefault { result = val[1] } classnameordefault: classname | DEFAULT variable: VARIABLE { result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] } array: LBRACK rvalues RBRACK { if val[1].instance_of?(AST::ASTArray) result = val[1] else result = ast AST::ASTArray, :children => [val[1]] end } | LBRACK rvalues COMMA RBRACK { if val[1].instance_of?(AST::ASTArray) result = val[1] else result = ast AST::ASTArray, :children => [val[1]] end } | LBRACK RBRACK { result = ast AST::ASTArray } comma: FARROW | COMMA endcomma: # nothing | COMMA { result = nil } regex: REGEX { result = ast AST::Regex, :value => val[0][:value] } hash: LBRACE hashpairs RBRACE { if val[1].instance_of?(AST::ASTHash) result = val[1] else result = ast AST::ASTHash, { :value => val[1] } end } | LBRACE hashpairs COMMA RBRACE { if val[1].instance_of?(AST::ASTHash) result = val[1] else result = ast AST::ASTHash, { :value => val[1] } end } | LBRACE RBRACE { result = ast AST::ASTHash } hashpairs: hashpair | hashpairs COMMA hashpair { if val[0].instance_of?(AST::ASTHash) result = val[0].merge(val[2]) else result = ast AST::ASTHash, :value => val[0] result.merge(val[2]) end } hashpair: key FARROW rvalue { result = ast AST::ASTHash, { :value => { val[0] => val[2] } } } key: NAME { result = val[0][:value] } | quotedtext { result = val[0] } hasharrayaccess: VARIABLE LBRACK rvalue RBRACK { result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2] } hasharrayaccesses: hasharrayaccess | hasharrayaccess LBRACK rvalue RBRACK { result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2] } end ---- header ---- require 'puppet' require 'puppet/util/loadedfile' require 'puppet/parser/lexer' require 'puppet/parser/ast' module Puppet class ParseError < Puppet::Error; end class ImportError < Racc::ParseError; end class AlreadyImportedError < ImportError; end end ---- inner ---- # It got too annoying having code in a file that needs to be compiled. require 'puppet/parser/parser_support' # Make emacs happy # Local Variables: # mode: ruby # End: # $Id$ diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb index f13a85f35..def462129 100644 --- a/lib/puppet/parser/lexer.rb +++ b/lib/puppet/parser/lexer.rb @@ -1,554 +1,558 @@ # the scanner/lexer require 'strscan' require 'puppet' module Puppet class LexError < RuntimeError; end end module Puppet::Parser; end class Puppet::Parser::Lexer attr_reader :last, :file, :lexing_context, :token_queue attr_accessor :line, :indefine def lex_error msg raise Puppet::LexError.new(msg) end class Token attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate def initialize(regex, name) if regex.is_a?(String) @name, @string = name, regex @regex = Regexp.new(Regexp.escape(@string)) else @name, @regex = name, regex end end # MQR: Why not just alias? %w{skip accumulate}.each do |method| define_method(method+"?") do self.send(method) end end def to_s if self.string @string else @name.to_s end end def acceptable?(context={}) # By default tokens are aceeptable in any context true end end # Maintain a list of tokens. class TokenList attr_reader :regex_tokens, :string_tokens def [](name) @tokens[name] end # Create a new token. def add_token(name, regex, options = {}, &block) token = Token.new(regex, name) raise(ArgumentError, "Token %s already exists" % name) if @tokens.include?(name) @tokens[token.name] = token if token.string @string_tokens << token @tokens_by_string[token.string] = token else @regex_tokens << token end options.each do |name, option| token.send(name.to_s + "=", option) end token.meta_def(:convert, &block) if block_given? token end def initialize @tokens = {} @regex_tokens = [] @string_tokens = [] @tokens_by_string = {} end # Look up a token by its value, rather than name. def lookup(string) @tokens_by_string[string] end # Define more tokens. def add_tokens(hash) hash.each do |regex, name| add_token(name, regex) end end # Sort our tokens by length, so we know once we match, we're done. # This helps us avoid the O(n^2) nature of token matching. def sort_tokens @string_tokens.sort! { |a, b| b.string.length <=> a.string.length } end end TOKENS = TokenList.new TOKENS.add_tokens( '[' => :LBRACK, ']' => :RBRACK, '{' => :LBRACE, '}' => :RBRACE, '(' => :LPAREN, ')' => :RPAREN, '=' => :EQUALS, '+=' => :APPENDS, '==' => :ISEQUAL, '>=' => :GREATEREQUAL, '>' => :GREATERTHAN, '<' => :LESSTHAN, '<=' => :LESSEQUAL, '!=' => :NOTEQUAL, '!' => :NOT, ',' => :COMMA, '.' => :DOT, ':' => :COLON, '@' => :AT, '<<|' => :LLCOLLECT, + '->' => :IN_EDGE, + '<-' => :OUT_EDGE, + '~>' => :IN_EDGE_SUB, + '<~' => :OUT_EDGE_SUB, '|>>' => :RRCOLLECT, '<|' => :LCOLLECT, '|>' => :RCOLLECT, ';' => :SEMIC, '?' => :QMARK, '\\' => :BACKSLASH, '=>' => :FARROW, '+>' => :PARROW, '+' => :PLUS, '-' => :MINUS, '/' => :DIV, '*' => :TIMES, '<<' => :LSHIFT, '>>' => :RSHIFT, '=~' => :MATCH, '!~' => :NOMATCH, %r{([a-z][-\w]*)?(::[a-z][-\w]*)+} => :CLASSNAME, # Require '::' in the class name, else we'd compete with NAME %r{((::){0,1}[A-Z][-\w]*)+} => :CLASSREF, "" => :STRING, "" => :DQPRE, "" => :DQMID, "" => :DQPOST, "" => :BOOLEAN ) TOKENS.add_token :NUMBER, %r{\b(?:0[xX][0-9A-Fa-f]+|0?\d+(?:\.\d+)?(?:[eE]-?\d+)?)\b} do |lexer, value| [TOKENS[:NAME], value] end def (TOKENS[:NUMBER]).acceptable?(context={}) ![:DQPRE,:DQMID].include? context[:after] end TOKENS.add_token :NAME, %r{[a-z0-9][-\w]*} do |lexer, value| string_token = self # we're looking for keywords here if tmp = KEYWORDS.lookup(value) string_token = tmp if [:TRUE, :FALSE].include?(string_token.name) value = eval(value) string_token = TOKENS[:BOOLEAN] end end [string_token, value] end def (TOKENS[:NAME]).acceptable?(context={}) ![:DQPRE,:DQMID].include? context[:after] end TOKENS.add_token :COMMENT, %r{#.*}, :accumulate => true, :skip => true do |lexer,value| value.sub!(/# ?/,'') [self, value] end TOKENS.add_token :MLCOMMENT, %r{/\*(.*?)\*/}m, :accumulate => true, :skip => true do |lexer, value| lexer.line += value.count("\n") value.sub!(/^\/\* ?/,'') value.sub!(/ ?\*\/$/,'') [self,value] end TOKENS.add_token :REGEX, %r{/[^/\n]*/} do |lexer, value| # Make sure we haven't matched an escaped / while value[-2..-2] == '\\' other = lexer.scan_until(%r{/}) value += other end regex = value.sub(%r{\A/}, "").sub(%r{/\Z}, '').gsub("\\/", "/") [self, Regexp.new(regex)] end def (TOKENS[:REGEX]).acceptable?(context={}) [:NODE,:LBRACE,:RBRACE,:MATCH,:NOMATCH,:COMMA].include? context[:after] end TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true TOKENS.add_token :SQUOTE, "'" do |lexer, value| [TOKENS[:STRING], lexer.slurpstring(value).first ] end DQ_initial_token_types = {'$' => :DQPRE,'"' => :STRING} DQ_continuation_token_types = {'$' => :DQMID,'"' => :DQPOST} TOKENS.add_token :DQUOTE, /"/ do |lexer, value| lexer.tokenize_interpolated_string(DQ_initial_token_types) end TOKENS.add_token :DQCONT, /\}/ do |lexer, value| lexer.tokenize_interpolated_string(DQ_continuation_token_types) end def (TOKENS[:DQCONT]).acceptable?(context={}) context[:string_interpolation_depth] > 0 end TOKENS.add_token :DOLLAR_VAR, %r{\$(\w*::)*\w+} do |lexer, value| [TOKENS[:VARIABLE],value[1..-1]] end TOKENS.add_token :VARIABLE, %r{(\w*::)*\w+} def (TOKENS[:VARIABLE]).acceptable?(context={}) [:DQPRE,:DQMID].include? context[:after] end TOKENS.sort_tokens @@pairs = { "{" => "}", "(" => ")", "[" => "]", "<|" => "|>", "<<|" => "|>>" } KEYWORDS = TokenList.new KEYWORDS.add_tokens( "case" => :CASE, "class" => :CLASS, "default" => :DEFAULT, "define" => :DEFINE, "import" => :IMPORT, "if" => :IF, "elsif" => :ELSIF, "else" => :ELSE, "inherits" => :INHERITS, "node" => :NODE, "and" => :AND, "or" => :OR, "undef" => :UNDEF, "false" => :FALSE, "true" => :TRUE ) def clear initvars end def expected return nil if @expected.empty? name = @expected[-1] TOKENS.lookup(name) or lex_error "Could not find expected token #{name}" end # scan the whole file # basically just used for testing def fullscan array = [] self.scan { |token, str| # Ignore any definition nesting problems @indefine = false array.push([token,str]) } return array end def file=(file) @file = file @line = 1 @scanner = StringScanner.new(File.read(file)) end def shift_token @token_queue.shift end def find_string_token # We know our longest string token is three chars, so try each size in turn # until we either match or run out of chars. This way our worst-case is three # tries, where it is otherwise the number of string token we have. Also, # the lookups are optimized hash lookups, instead of regex scans. # s = @scanner.peek(3) token = TOKENS.lookup(s[0,3]) || TOKENS.lookup(s[0,2]) || TOKENS.lookup(s[0,1]) [ token, token && @scanner.scan(token.regex) ] end # Find the next token that matches a regex. We look for these first. def find_regex_token @regex += 1 best_token = nil best_length = 0 # I tried optimizing based on the first char, but it had # a slightly negative affect and was a good bit more complicated. TOKENS.regex_tokens.each do |token| if length = @scanner.match?(token.regex) and token.acceptable?(lexing_context) # We've found a longer match if length > best_length best_length = length best_token = token end end end return best_token, @scanner.scan(best_token.regex) if best_token end # Find the next token, returning the string and the token. def find_token @find += 1 shift_token || find_regex_token || find_string_token end def indefine? if defined? @indefine @indefine else false end end def initialize @find = 0 @regex = 0 initvars() end def initvars @line = 1 @previous_token = nil @scanner = nil @file = nil # AAARRGGGG! okay, regexes in ruby are bloody annoying # no one else has "\n" =~ /\s/ @skip = %r{[ \t]+} @namestack = [] @token_queue = [] @indefine = false @expected = [] @commentstack = [ ['', @line] ] @lexing_context = { :after => nil, :start_of_line => true, :string_interpolation_depth => 0 } end # Make any necessary changes to the token and/or value. def munge_token(token, value) @line += 1 if token.incr_line skip() if token.skip_text return if token.skip and not token.accumulate? token, value = token.convert(self, value) if token.respond_to?(:convert) return unless token if token.accumulate? comment = @commentstack.pop comment[0] << value + "\n" @commentstack.push(comment) end return if token.skip return token, { :value => value, :line => @line } end # Go up one in the namespace. def namepop @namestack.pop end # Collect the current namespace. def namespace @namestack.join("::") end # This value might have :: in it, but we don't care -- it'll be # handled normally when joining, and when popping we want to pop # this full value, however long the namespace is. def namestack(value) @namestack << value end def rest @scanner.rest end # this is the heart of the lexer def scan #Puppet.debug("entering scan") lex_error "Invalid or empty string" unless @scanner # Skip any initial whitespace. skip() until token_queue.empty? and @scanner.eos? do yielded = false matched_token, value = find_token # error out if we didn't match anything at all lex_error "Could not match #{@scanner.rest[/^(\S+|\s+|.*)/]}" unless matched_token newline = matched_token.name == :RETURN # this matches a blank line; eat the previously accumulated comments getcomment if lexing_context[:start_of_line] and newline lexing_context[:start_of_line] = newline final_token, token_value = munge_token(matched_token, value) unless final_token skip() next end lexing_context[:after] = final_token.name unless newline lexing_context[:string_interpolation_depth] += 1 if final_token.name == :DQPRE lexing_context[:string_interpolation_depth] -= 1 if final_token.name == :DQPOST value = token_value[:value] if match = @@pairs[value] and final_token.name != :DQUOTE and final_token.name != :SQUOTE @expected << match elsif exp = @expected[-1] and exp == value and final_token.name != :DQUOTE and final_token.name != :SQUOTE @expected.pop end if final_token.name == :LBRACE commentpush end yield [final_token.name, token_value] if @previous_token namestack(value) if @previous_token.name == :CLASS if @previous_token.name == :DEFINE if indefine? msg = "Cannot nest definition %s inside %s" % [value, @indefine] self.indefine = false raise Puppet::ParseError, msg end @indefine = value end end @previous_token = final_token skip() end @scanner = nil # This indicates that we're done parsing. yield [false,false] end # Skip any skipchars in our remaining string. def skip @scanner.skip(@skip) end # Provide some limited access to the scanner, for those # tokens that need it. def scan_until(regex) @scanner.scan_until(regex) end # we've encountered the start of a string... # slurp in the rest of the string and return it Valid_escapes_in_strings = %w{ \\ $ ' " n t s }+["\n"] def slurpstring(terminators) # we search for the next quote that isn't preceded by a # backslash; the caret is there to match empty strings str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'" @line += str.count("\n") # literal carriage returns add to the line count. str.gsub!(/\\(.)/) { case ch=$1 when 'n'; "\n" when 't'; "\t" when 's'; " " else if Valid_escapes_in_strings.include? ch and not (ch == '"' and terminators == "'") ch else Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}" "\\#{ch}" end end } [ str[0..-2],str[-1,1] ] end def tokenize_interpolated_string(token_type) value,terminator = slurpstring('"$') token_queue << [TOKENS[token_type[terminator]],value] while terminator == '$' and not @scanner.scan(/\{/) token_queue << [TOKENS[:VARIABLE],@scanner.scan(%r{(\w*::)*\w+|[0-9]})] value,terminator = slurpstring('"$') token_queue << [TOKENS[DQ_continuation_token_types[terminator]],value] end token_queue.shift end # just parse a string, not a whole file def string=(string) @scanner = StringScanner.new(string) end # returns the content of the currently accumulated content cache def commentpop return @commentstack.pop[0] end def getcomment(line = nil) comment = @commentstack.last if line.nil? or comment[1] <= line @commentstack.pop @commentstack.push(['', @line]) return comment[0] end return '' end def commentpush @commentstack.push(['', @line]) end end diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb index 8937fe17d..1ada48fa8 100644 --- a/lib/puppet/parser/parser.rb +++ b/lib/puppet/parser/parser.rb @@ -1,2582 +1,2534 @@ # # DO NOT MODIFY!!!! -# This file is automatically generated by Racc 1.4.6 -# from Racc grammer file "". +# This file is automatically generated by racc 1.4.5 +# from racc grammer file "grammar.ra". # -require 'racc/parser.rb' +require 'racc/parser' + require 'puppet' require 'puppet/util/loadedfile' require 'puppet/parser/lexer' require 'puppet/parser/ast' module Puppet class ParseError < Puppet::Error; end class ImportError < Racc::ParseError; end class AlreadyImportedError < ImportError; end end + module Puppet + module Parser + class Parser < Racc::Parser -module_eval(<<'...end grammar.ra/module_eval...', 'grammar.ra', 850) +module_eval <<'..end grammar.ra modeval..id2f1634261a', 'grammar.ra', 862 # It got too annoying having code in a file that needs to be compiled. require 'puppet/parser/parser_support' # Make emacs happy # Local Variables: # mode: ruby # End: # $Id$ -...end grammar.ra/module_eval... -##### State transition tables begin ### + +..end grammar.ra modeval..id2f1634261a + +##### racc 1.4.5 generates ### + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 69, :_reduce_1, + 1, 69, :_reduce_none, + 1, 70, :_reduce_none, + 2, 70, :_reduce_4, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 3, 86, :_reduce_19, + 3, 86, :_reduce_20, + 1, 87, :_reduce_none, + 1, 87, :_reduce_none, + 1, 87, :_reduce_none, + 1, 88, :_reduce_none, + 1, 88, :_reduce_none, + 1, 88, :_reduce_none, + 1, 88, :_reduce_none, + 4, 80, :_reduce_28, + 5, 80, :_reduce_29, + 3, 80, :_reduce_30, + 2, 80, :_reduce_31, + 1, 90, :_reduce_none, + 1, 90, :_reduce_none, + 3, 90, :_reduce_34, + 3, 90, :_reduce_35, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_none, + 1, 91, :_reduce_44, + 5, 73, :_reduce_45, + 5, 73, :_reduce_46, + 5, 73, :_reduce_47, + 5, 84, :_reduce_48, + 2, 74, :_reduce_49, + 1, 107, :_reduce_50, + 2, 107, :_reduce_51, + 6, 75, :_reduce_52, + 2, 75, :_reduce_53, + 3, 108, :_reduce_54, + 3, 108, :_reduce_55, + 1, 109, :_reduce_none, + 1, 109, :_reduce_none, + 3, 109, :_reduce_58, + 1, 110, :_reduce_none, + 3, 110, :_reduce_60, + 1, 111, :_reduce_61, + 1, 111, :_reduce_62, + 3, 112, :_reduce_63, + 3, 112, :_reduce_64, + 1, 113, :_reduce_none, + 1, 113, :_reduce_none, + 4, 115, :_reduce_67, + 1, 101, :_reduce_none, + 3, 101, :_reduce_69, + 0, 102, :_reduce_none, + 1, 102, :_reduce_none, + 1, 117, :_reduce_72, + 1, 92, :_reduce_73, + 1, 94, :_reduce_74, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 3, 76, :_reduce_82, + 3, 76, :_reduce_83, + 3, 85, :_reduce_84, + 0, 103, :_reduce_85, + 1, 103, :_reduce_86, + 3, 103, :_reduce_87, + 3, 121, :_reduce_88, + 3, 123, :_reduce_89, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 0, 106, :_reduce_92, + 1, 106, :_reduce_93, + 3, 106, :_reduce_94, + 1, 125, :_reduce_none, + 3, 125, :_reduce_96, + 1, 114, :_reduce_none, + 1, 114, :_reduce_none, + 1, 114, :_reduce_none, + 1, 114, :_reduce_none, + 1, 114, :_reduce_none, + 1, 114, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 4, 96, :_reduce_115, + 3, 96, :_reduce_116, + 1, 98, :_reduce_117, + 2, 98, :_reduce_118, + 2, 128, :_reduce_119, + 1, 129, :_reduce_120, + 2, 129, :_reduce_121, + 1, 95, :_reduce_122, + 4, 89, :_reduce_123, + 4, 89, :_reduce_124, + 6, 78, :_reduce_125, + 5, 78, :_reduce_126, + 0, 130, :_reduce_none, + 4, 130, :_reduce_128, + 3, 130, :_reduce_129, + 1, 119, :_reduce_none, + 3, 119, :_reduce_131, + 3, 119, :_reduce_132, + 3, 119, :_reduce_133, + 3, 119, :_reduce_134, + 3, 119, :_reduce_135, + 3, 119, :_reduce_136, + 3, 119, :_reduce_137, + 3, 119, :_reduce_138, + 2, 119, :_reduce_139, + 3, 119, :_reduce_140, + 3, 119, :_reduce_141, + 3, 119, :_reduce_142, + 3, 119, :_reduce_143, + 3, 119, :_reduce_144, + 3, 119, :_reduce_145, + 2, 119, :_reduce_146, + 3, 119, :_reduce_147, + 3, 119, :_reduce_148, + 3, 119, :_reduce_149, + 5, 77, :_reduce_150, + 1, 132, :_reduce_none, + 2, 132, :_reduce_152, + 5, 133, :_reduce_153, + 4, 133, :_reduce_154, + 1, 134, :_reduce_none, + 3, 134, :_reduce_156, + 3, 97, :_reduce_157, + 1, 136, :_reduce_none, + 4, 136, :_reduce_159, + 1, 138, :_reduce_none, + 3, 138, :_reduce_161, + 3, 137, :_reduce_162, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_none, + 1, 135, :_reduce_170, + 1, 135, :_reduce_none, + 1, 139, :_reduce_172, + 1, 140, :_reduce_none, + 3, 140, :_reduce_174, + 2, 79, :_reduce_175, + 6, 81, :_reduce_176, + 5, 81, :_reduce_177, + 7, 82, :_reduce_178, + 6, 82, :_reduce_179, + 6, 83, :_reduce_180, + 5, 83, :_reduce_181, + 1, 105, :_reduce_182, + 1, 100, :_reduce_183, + 1, 100, :_reduce_184, + 1, 100, :_reduce_185, + 1, 143, :_reduce_none, + 3, 143, :_reduce_187, + 1, 145, :_reduce_188, + 1, 146, :_reduce_189, + 1, 146, :_reduce_190, + 1, 146, :_reduce_191, + 1, 146, :_reduce_none, + 0, 71, :_reduce_193, + 0, 147, :_reduce_194, + 1, 141, :_reduce_none, + 3, 141, :_reduce_196, + 3, 141, :_reduce_197, + 1, 148, :_reduce_none, + 3, 148, :_reduce_199, + 3, 149, :_reduce_200, + 1, 149, :_reduce_201, + 3, 149, :_reduce_202, + 1, 149, :_reduce_203, + 1, 144, :_reduce_none, + 2, 144, :_reduce_205, + 1, 142, :_reduce_none, + 2, 142, :_reduce_207, + 1, 150, :_reduce_none, + 1, 150, :_reduce_none, + 1, 93, :_reduce_210, + 3, 118, :_reduce_211, + 4, 118, :_reduce_212, + 2, 118, :_reduce_213, + 1, 126, :_reduce_none, + 1, 126, :_reduce_none, + 0, 104, :_reduce_none, + 1, 104, :_reduce_217, + 1, 131, :_reduce_218, + 3, 127, :_reduce_219, + 4, 127, :_reduce_220, + 2, 127, :_reduce_221, + 1, 151, :_reduce_none, + 3, 151, :_reduce_223, + 3, 152, :_reduce_224, + 1, 153, :_reduce_225, + 1, 153, :_reduce_226, + 4, 120, :_reduce_227, + 1, 99, :_reduce_none, + 4, 99, :_reduce_229 ] + +racc_reduce_n = 230 + +racc_shift_n = 379 racc_action_table = [ - 60, 65, 60, 65, 95, 121, 95, 216, 97, 187, - 71, 113, 108, 187, 109, 46, 285, 217, 281, 46, - 186, 60, 65, 216, 186, 191, 280, 110, 154, 191, - 122, 46, 144, 59, 325, 59, 154, 72, 133, 72, - 75, 80, 326, 80, 278, 279, 131, 170, 68, 222, - 77, 106, 77, 50, 59, 161, 53, 50, 72, 75, - 53, 52, 80, 52, 60, 65, 66, 68, 150, 50, - 239, 77, 53, 327, 60, 65, 52, 167, 171, 286, - 52, 315, 52, 173, 157, 158, 159, 160, 162, 287, - 167, 171, 52, 60, 65, 60, 65, 186, 278, 279, - 223, 72, 237, 231, 348, 80, 187, 186, 289, 43, - 131, 72, 237, 224, 77, 80, 244, 186, 41, 42, - 131, 290, 191, 288, 77, 52, 59, 105, 186, 170, - 72, 75, 72, 237, 80, 52, 80, 161, 66, 68, - 34, 131, 187, 77, 36, 77, 60, 65, 60, 65, - 95, 11, 97, 186, 52, 182, 52, 201, 191, -157, - 60, 65, 202, 293, 71, 173, 157, 158, 159, 160, - 162, 283, 167, 171, 34, 231, 232, 268, 36, 59, - 267, 296, 62, 72, 75, 11, 181, 80, 60, 65, - 167, 171, 68, 59, -155, 321, 77, 72, 75, 233, - -158, 80, 299, 231, 232, 66, 68, 52, 60, 65, - 77, 34, 95, 34, 97, 36, -159, 36, -154, 197, - 201, 52, 11, 16, 11, 202, 181, 60, 65, 303, - 88, 95, 276, 97, 60, 65, 278, 279, 95, 197, - 97, 59, 158, 159, 144, 72, 75, 167, 171, 80, - 306, 108, -156, 309, 68, 93, 88, -153, 77, 269, - 59, 83, 312, 154, 72, 75, 153, 59, 80, 52, - -153, 72, 75, 68, 266, 80, 52, 77, 231, 265, - 68, 93, -156, -154, 77, 60, 65, 83, 52, 95, - 183, 97, 158, 159, 52, 52, 184, 167, 171, 150, - -172, -155, 147, 43, 60, 65, -157, 88, 95, 195, - 97, 60, 65, -158, 318, 95, 197, 97, 59, 319, - 200, 144, 72, 75, 206, 207, 80, 210, 213, 60, - 65, 68, 93, 216, 109, 77, 220, 59, 83, 338, - 113, 72, 75, 111, 59, 80, 52, -155, 72, 75, - 68, 105, 80, 55, 77, 54, 217, 68, 45, 215, - 318, 77, 186, 352, -153, 52, 72, 237, 354, -158, - 80, -155, 52, -153, -156, 131, 60, 65, -154, 77, - 95, 355, 97, 217, 173, 157, 158, 159, -207, -156, - 52, 167, 171, 358, 220, 60, 65, 37, 88, 95, - 219, 97, 60, 65, -154, nil, 95, nil, 97, 59, - nil, nil, nil, 72, 75, nil, nil, 80, nil, nil, - 60, 65, 68, 93, 88, nil, 77, nil, 59, 83, - nil, nil, 72, 75, nil, 59, 80, 52, nil, 72, - 75, 68, nil, 80, nil, 77, nil, nil, 68, 93, - nil, nil, 77, 186, nil, 83, 52, 72, 237, nil, - nil, 80, nil, 52, nil, nil, 131, 60, 65, nil, - 77, 95, nil, 97, nil, 173, 157, 158, 159, 160, - 162, 52, 167, 171, nil, 60, 65, nil, nil, 88, - nil, nil, 324, nil, 173, 157, 158, 159, nil, nil, - 59, 167, 171, nil, 72, 75, nil, nil, 80, nil, - nil, nil, nil, 68, 93, 60, 65, 77, 186, 95, - 83, 97, 72, 237, nil, nil, 80, nil, 52, nil, - nil, 131, nil, nil, nil, 77, nil, 88, nil, nil, - nil, 60, 65, nil, nil, 95, 52, 97, 59, nil, - nil, nil, 72, 75, nil, nil, 80, nil, nil, nil, - nil, 68, 93, 60, 65, 77, nil, 95, 83, 97, - nil, nil, nil, nil, 59, nil, 52, nil, 72, 75, - nil, nil, 80, nil, nil, 88, nil, 68, nil, 60, - 65, 77, nil, 95, nil, 97, 59, nil, nil, nil, - 72, 75, 52, nil, 80, nil, nil, nil, nil, 68, - 93, 88, nil, 77, nil, nil, 83, nil, nil, 60, - 65, nil, 59, 95, 52, 97, 72, 75, nil, nil, - 80, nil, nil, nil, nil, 68, 93, nil, nil, 77, - nil, 88, 83, nil, 60, 65, nil, nil, nil, nil, - 52, nil, 59, nil, nil, nil, 72, 75, nil, nil, - 80, nil, nil, nil, nil, 68, 93, 145, nil, 77, - 60, 65, 83, nil, 95, nil, 97, 59, nil, nil, - 52, 72, 75, nil, nil, 80, nil, nil, nil, 66, - 68, nil, 88, nil, 77, nil, 60, 65, nil, nil, - 95, nil, 97, 59, nil, 52, nil, 72, 75, nil, - nil, 80, nil, nil, nil, nil, 68, 93, 88, nil, - 77, 60, 65, 83, nil, 95, nil, 97, nil, 59, - nil, 52, nil, 72, 75, nil, nil, 80, nil, nil, - nil, nil, 68, 93, nil, nil, 77, 60, 65, 83, - nil, 95, nil, 97, 59, nil, nil, 52, 72, 75, - nil, nil, 80, nil, nil, nil, nil, 68, nil, 88, - nil, 77, nil, 60, 65, nil, nil, 95, nil, 97, - 59, nil, 52, nil, 72, 75, nil, nil, 80, nil, - nil, 60, 65, 68, 93, 88, nil, 77, 60, 65, - 83, nil, 95, nil, 97, nil, 59, nil, 52, nil, - 72, 75, 60, 65, 80, nil, 95, nil, 97, 68, - 93, nil, nil, 77, 186, nil, 83, nil, 72, 237, - nil, 59, 80, nil, 52, 72, 75, 131, nil, 80, - nil, 77, 60, 65, 68, 59, nil, nil, 77, 72, - 75, nil, 52, 80, nil, nil, nil, nil, 68, 52, - 60, 65, 77, nil, 95, 308, 97, nil, nil, nil, - nil, nil, nil, 52, nil, 59, nil, nil, nil, 72, - 75, nil, 88, 80, nil, 60, 65, 66, 68, 95, - nil, 97, 77, 59, nil, nil, nil, 72, 75, nil, - nil, 80, nil, 52, nil, nil, 68, 93, nil, nil, - 77, 60, 65, 83, nil, 95, nil, 97, 59, nil, - nil, 52, 72, 75, nil, nil, 80, nil, nil, nil, - nil, 68, 60, 65, nil, 77, 95, nil, 97, nil, - nil, nil, nil, nil, 59, nil, 52, nil, 72, 75, - nil, nil, 80, nil, 88, nil, nil, 68, 60, 65, - nil, 77, 95, nil, nil, 59, nil, nil, nil, 72, - 75, nil, 52, 80, nil, nil, nil, nil, 68, 93, - 60, 65, 77, nil, 95, 83, 97, nil, nil, nil, - nil, 59, nil, 52, nil, 72, 237, nil, nil, 80, - nil, nil, 88, nil, 131, nil, 60, 65, 77, nil, - 95, nil, 97, 59, nil, nil, nil, 72, 75, 52, - nil, 80, nil, nil, nil, nil, 68, 93, 88, nil, - 77, nil, nil, 83, nil, nil, 60, 65, nil, 59, - 95, 52, 97, 72, 75, nil, nil, 80, nil, nil, - nil, nil, 68, 93, nil, nil, 77, nil, 88, 83, - nil, nil, 60, 65, nil, nil, 95, 52, 97, 59, - nil, nil, nil, 72, 75, nil, nil, 80, nil, nil, - 60, 65, 68, 93, 88, nil, 77, nil, nil, 83, - nil, nil, nil, nil, nil, 59, nil, 52, nil, 72, - 75, nil, nil, 80, nil, nil, nil, nil, 68, 93, - 60, 65, 77, 186, 95, 83, 97, 72, 237, 172, - nil, 80, nil, 52, nil, nil, 131, nil, 165, 170, - 77, nil, 88, nil, nil, nil, nil, 161, 163, 166, - 169, 52, nil, 59, nil, nil, nil, 72, 75, 60, - 65, 80, nil, 95, 175, 97, 68, 93, nil, nil, - 77, 164, 168, 83, nil, 173, 157, 158, 159, 160, - 162, 52, 167, 171, 60, 65, nil, nil, 95, nil, - 97, nil, 59, nil, nil, nil, 72, 75, nil, nil, - 80, nil, nil, nil, nil, 68, 88, nil, nil, 77, - 60, 65, nil, nil, 95, nil, 97, 59, nil, nil, - 52, 72, 75, nil, nil, 80, nil, nil, nil, nil, - 68, 93, 88, nil, 77, nil, nil, 83, nil, nil, - nil, nil, nil, 59, nil, 52, nil, 72, 75, nil, - nil, 80, 227, 228, nil, nil, 68, 93, nil, nil, - 77, nil, nil, 83, nil, 165, 170, nil, nil, nil, - nil, 52, nil, nil, 161, 163, 166, 169, 165, 170, - nil, nil, nil, nil, nil, nil, 246, 161, 163, 166, - 169, nil, nil, nil, nil, nil, nil, nil, 164, 168, - nil, nil, 173, 157, 158, 159, 160, 162, nil, 167, - 171, 164, 168, nil, nil, 173, 157, 158, 159, 160, - 162, nil, 167, 171, 165, 170, nil, nil, nil, nil, - nil, nil, nil, 161, 163, 166, 169, 165, 170, nil, - nil, nil, nil, nil, nil, nil, 161, 163, 166, 169, - nil, nil, nil, nil, nil, nil, nil, 164, 168, nil, - nil, 173, 157, 158, 159, 160, 162, nil, 167, 171, - 164, 168, nil, nil, 173, 157, 158, 159, 160, 162, - nil, 167, 171, 165, 170, nil, nil, nil, nil, nil, - nil, nil, 161, 163, 166, 169, 165, 170, nil, nil, - nil, nil, nil, nil, nil, 161, 163, 166, 169, nil, - nil, 173, 157, 158, 159, 160, 162, 168, 167, 171, - 173, 157, 158, 159, 160, 162, nil, 167, 171, nil, - nil, nil, nil, 173, 157, 158, 159, 160, 162, nil, - 167, 171, 165, 170, nil, nil, nil, nil, nil, nil, - nil, 161, 163, 166, 169, 170, nil, nil, nil, nil, - nil, nil, nil, 161, 170, nil, nil, nil, nil, nil, - nil, nil, 161, nil, nil, 164, 168, nil, nil, 173, - 157, 158, 159, 160, 162, nil, 167, 171, 263, nil, - nil, 173, 157, 158, 159, 160, 162, nil, 167, 171, - 173, 157, 158, 159, 160, 162, nil, 167, 171, 26, - 342, 30, 1, nil, 8, 12, nil, 19, nil, 24, - nil, 28, nil, 2, nil, nil, 11, 16, nil, 316, - nil, 26, nil, 30, 1, nil, 8, 12, nil, 19, - nil, 24, nil, 28, nil, 2, nil, nil, 11, 16, - 26, 344, 30, 1, nil, 8, 12, nil, 19, nil, - 24, nil, 28, nil, 2, nil, nil, 11, 16, nil, - 345, nil, 26, nil, 30, 1, nil, 8, 12, nil, - 19, nil, 24, nil, 28, nil, 2, nil, nil, 11, - 16, 26, 298, 30, 1, nil, 8, 12, nil, 19, - nil, 24, nil, 28, nil, 2, nil, nil, 11, 16, - nil, 356, nil, 26, nil, 30, 1, nil, 8, 12, - nil, 19, nil, 24, nil, 28, nil, 2, nil, nil, - 11, 16, 26, 360, 30, 1, nil, 8, 12, nil, - 19, nil, 24, nil, 28, nil, 2, nil, nil, 11, - 16, nil, 362, nil, 26, nil, 30, 1, nil, 8, - 12, nil, 19, nil, 24, nil, 28, nil, 2, nil, - nil, 11, 16, 26, 292, 30, 1, nil, 8, 12, - nil, 19, nil, 24, nil, 28, nil, 2, nil, nil, - 11, 16, nil, 363, nil, 26, nil, 30, 1, nil, - 8, 12, nil, 19, nil, 24, nil, 28, nil, 2, - nil, nil, 11, 16, 26, 364, 30, 1, nil, 8, - 12, nil, 19, nil, 24, nil, 28, nil, 2, nil, - nil, 11, 16, nil, nil, nil, 26, nil, 30, 1, - nil, 8, 12, nil, 19, nil, 24, nil, 28, nil, - 2, nil, nil, 11, 16, 26, nil, 30, 1, nil, - 8, 12, nil, 19, nil, 24, nil, 28, nil, 2, - nil, nil, 11, 16, 26, nil, 30, 1, nil, 8, - 12, nil, 19, nil, 24, nil, 28, nil, 2, nil, - nil, 11, 16 ] + 64, 68, 49, 57, 96, 58, 101, 49, 75, 226, + 322, 253, 155, 118, 149, 75, 155, 49, 60, 64, + 68, 302, 92, 154, 254, 115, 176, 154, 161, 64, + 68, 226, 161, 63, 303, 242, 243, 76, 79, 151, + 52, 86, 56, 55, 176, 52, 71, 94, 55, -167, + 81, 227, 63, 88, 250, 52, 76, 79, 55, 300, + 86, 53, 154, 53, 69, 71, 76, 261, 53, 81, + 86, 64, 68, 64, 68, 127, 169, 262, 53, 81, + 53, 155, 242, 243, 244, 363, 44, 64, 68, 340, + 53, 96, 154, 101, 37, 42, 43, 161, 38, 301, + 64, 68, 155, 177, 154, 9, 154, 186, 76, 261, + 76, 261, 86, 154, 86, 64, 68, 127, 161, 127, + 63, 81, 344, 81, 76, 79, 215, 304, 86, 64, + 68, 219, 53, 71, 53, 64, 68, 81, 183, 96, + 37, 101, 351, 37, 38, -164, 275, 208, 53, 274, + 352, 9, 269, 183, 9, 13, 239, 92, 215, 199, + 203, 307, 63, 219, 238, 57, 76, 79, 63, 166, + 86, 310, 76, 79, 69, 71, 86, 64, 68, 81, + 166, 71, 94, 64, 68, 81, -166, 75, 88, -163, + 53, 37, 142, 64, 68, 38, 53, 96, 315, 101, + 37, 53, 9, 13, 208, 66, 199, 203, 319, 202, + 154, 9, 13, -182, 76, 261, 63, 193, 86, -165, + 76, 79, 172, 127, 86, 169, 63, 81, 69, 71, + 76, 79, -163, 81, 86, 44, 64, 68, 53, 71, + 96, 333, 101, 81, 53, 205, 189, 190, 191, 192, + 194, 228, 199, 203, 53, 64, 68, -166, 92, 96, + 37, 101, 64, 68, 38, 336, 96, 318, 101, 63, + 176, 9, 167, 76, 79, 190, 191, 86, 166, 53, + 199, 203, 71, 94, 92, 341, 81, 342, 63, 88, + -164, -169, 76, 79, -168, 63, 86, 53, -167, 76, + 79, 71, -165, 86, 58, 81, 64, 68, 71, 94, + 96, 206, 81, 64, 68, 88, 53, 96, 212, 101, + 64, 68, 276, 53, 96, 148, 101, 64, 68, 205, + 189, 190, 191, 120, 350, 142, 199, 203, 120, 63, + 220, 222, -168, 76, 134, 347, 63, 86, -163, 115, + 76, 79, 127, 63, 86, 223, 81, 76, 79, 71, + 154, 86, 142, 81, 76, 261, 71, 53, 86, 226, + 81, 241, 223, 127, 53, 242, 243, 81, 64, 68, + -166, 53, 96, 223, 101, 235, -164, -163, 53, 25, + -166, 32, 1, -164, 7, 10, -168, 16, -165, 22, + 92, 29, 361, 2, 64, 68, 9, 13, 96, 46, + 101, 63, 190, 191, 231, 76, 79, 199, 203, 86, + 113, 114, 110, 112, 71, 94, 92, 347, 81, 367, + 230, 88, 369, 225, 64, 68, -217, 63, 96, 53, + 101, 76, 79, 267, 41, 86, 372, 244, 245, 40, + 71, 94, 39, 228, 81, -165, 92, 88, 273, nil, + 64, 68, 244, 272, 96, 53, 101, 63, nil, 247, + nil, 76, 79, 244, 245, 86, 113, 114, 110, 112, + 71, 94, 92, nil, 81, nil, nil, 88, nil, nil, + 64, 68, nil, 63, 96, 53, 101, 76, 79, nil, + nil, 86, -23, -23, -23, -23, 71, 94, nil, nil, + 81, nil, 92, 88, nil, nil, 64, 68, nil, nil, + 96, 53, 101, 63, nil, nil, nil, 76, 79, nil, + nil, 86, -21, -21, -21, -21, 71, 94, 92, nil, + 81, 64, 68, 88, nil, 96, nil, 101, nil, 63, + nil, 53, nil, 76, 79, nil, nil, 86, nil, nil, + nil, nil, 71, 94, nil, nil, 81, 64, 68, 88, + nil, 96, nil, 101, 63, nil, nil, 53, 76, 79, + nil, nil, 86, nil, nil, nil, nil, 71, nil, 92, + nil, 81, nil, 64, 68, nil, nil, 96, nil, 101, + 63, nil, 53, nil, 76, 79, nil, nil, 86, nil, + nil, nil, nil, 71, 94, 92, nil, 81, nil, nil, + 88, nil, nil, 64, 68, nil, 63, 96, 53, 101, + 76, 79, nil, nil, 86, nil, nil, nil, nil, 71, + 94, nil, nil, 81, nil, 92, 88, nil, nil, 64, + 68, nil, nil, 96, 53, 101, 63, nil, nil, nil, + 76, 79, nil, nil, 86, nil, nil, nil, nil, 71, + 94, 64, 68, 81, nil, 96, 88, 101, nil, nil, + nil, nil, 63, nil, 53, nil, 76, 79, nil, nil, + 86, nil, 64, 68, nil, 71, 96, nil, 101, 81, + nil, nil, nil, nil, 63, nil, nil, nil, 76, 79, + 53, nil, 86, nil, 92, nil, nil, 71, 64, 68, + nil, 81, nil, nil, nil, 63, nil, nil, nil, 76, + 79, nil, 53, 86, nil, nil, 64, 68, 71, 94, + nil, 335, 81, 64, 68, 88, nil, 96, nil, 101, + nil, 63, nil, 53, nil, 76, 79, nil, nil, 86, + nil, nil, nil, 69, 71, 64, 68, nil, 81, 154, + nil, nil, nil, 76, 261, nil, 63, 86, nil, 53, + 76, 79, 127, nil, 86, nil, 81, nil, 171, 71, + 64, 68, nil, 81, nil, nil, nil, 53, 63, nil, + nil, nil, 76, 79, 53, nil, 86, nil, 64, 68, + 69, 71, 96, nil, 101, 81, nil, 205, 189, 190, + 191, 192, 194, 154, 199, 203, 53, 76, 261, nil, + 92, 86, nil, nil, nil, nil, 127, nil, 64, 68, + 81, 63, 96, nil, 101, 76, 79, nil, nil, 86, + nil, 53, nil, nil, 71, 94, nil, nil, 81, nil, + 92, 88, nil, nil, 64, 68, nil, nil, 96, 53, + 101, 63, nil, nil, nil, 76, 79, nil, nil, 86, + nil, nil, nil, nil, 71, 94, 64, 68, 81, nil, + 96, 88, 101, nil, nil, nil, nil, 63, nil, 53, + nil, 76, 79, nil, nil, 86, nil, 64, 68, nil, + 71, 96, nil, nil, 81, nil, nil, nil, nil, 63, + nil, nil, nil, 76, 79, 53, nil, 86, nil, 64, + 68, nil, 71, 96, nil, 101, 81, nil, nil, nil, + 63, nil, nil, nil, 76, 261, nil, 53, 86, nil, + 64, 68, nil, 127, 96, nil, 101, 81, nil, nil, + nil, nil, 63, nil, nil, nil, 76, 79, 53, nil, + 86, nil, 92, nil, nil, 71, 64, 68, nil, 81, + 96, nil, 101, 63, nil, nil, nil, 76, 79, nil, + 53, 86, nil, nil, 64, 68, 71, 94, 92, nil, + 81, nil, nil, 88, nil, nil, nil, nil, nil, 63, + nil, 53, nil, 76, 79, nil, nil, 86, nil, nil, + nil, nil, 71, 94, 64, 68, 81, 154, 96, 88, + 101, 76, 261, 204, nil, 86, nil, 53, nil, nil, + 127, nil, 197, 202, 81, nil, 92, nil, nil, nil, + nil, 193, 195, 198, 201, 53, nil, 63, nil, nil, + nil, 76, 79, 64, 68, 86, nil, 96, 182, 101, + 71, 94, nil, nil, 81, 196, 200, 88, nil, 205, + 189, 190, 191, 192, 194, 53, 199, 203, 64, 68, + nil, nil, 96, nil, 101, nil, 63, nil, nil, nil, + 76, 79, nil, nil, 86, nil, nil, nil, nil, 71, + 92, nil, nil, 81, 64, 68, nil, nil, 96, nil, + 101, 63, nil, nil, 53, 76, 79, nil, nil, 86, + nil, nil, nil, nil, 71, 94, 92, nil, 81, nil, + nil, 88, nil, nil, 64, 68, nil, 63, 96, 53, + 101, 76, 79, nil, nil, 86, nil, nil, nil, nil, + 71, 94, nil, nil, 81, nil, 92, 88, nil, nil, + 64, 68, nil, nil, 96, 53, 101, 63, nil, nil, + nil, 76, 79, nil, nil, 86, nil, nil, nil, nil, + 71, 94, 92, nil, 81, nil, nil, 88, nil, nil, + nil, nil, nil, 63, nil, 53, nil, 76, 79, nil, + nil, 86, 264, 265, nil, nil, 71, 94, nil, nil, + 81, nil, nil, 88, nil, 197, 202, nil, nil, nil, + nil, 53, nil, nil, 193, 195, 198, 201, 197, 202, + nil, nil, nil, nil, nil, nil, 271, 193, 195, 198, + 201, nil, nil, 205, 189, 190, 191, nil, 196, 200, + 199, 203, 205, 189, 190, 191, 192, 194, nil, 199, + 203, 196, 200, nil, nil, 205, 189, 190, 191, 192, + 194, nil, 199, 203, 197, 202, nil, nil, nil, nil, + nil, nil, nil, 193, 195, 198, 201, 197, 202, nil, + nil, nil, nil, nil, nil, nil, 193, 195, 198, 201, + nil, nil, nil, nil, nil, nil, nil, 196, 200, nil, + nil, 205, 189, 190, 191, 192, 194, nil, 199, 203, + 196, 200, nil, nil, 205, 189, 190, 191, 192, 194, + nil, 199, 203, 197, 202, nil, nil, nil, nil, nil, + nil, nil, 193, 195, 198, 201, 197, 202, nil, nil, + nil, nil, nil, nil, nil, 193, 195, 198, 201, nil, + nil, 205, 189, 190, 191, 192, 194, 200, 199, 203, + 205, 189, 190, 191, 192, 194, nil, 199, 203, nil, + nil, nil, nil, 205, 189, 190, 191, 192, 194, nil, + 199, 203, 197, 202, nil, nil, nil, nil, nil, nil, + nil, 193, 195, 198, 201, 202, nil, nil, nil, nil, + nil, nil, nil, 193, 202, nil, nil, nil, nil, nil, + nil, nil, 193, nil, nil, 196, 200, 202, nil, 205, + 189, 190, 191, 192, 194, 193, 199, 203, nil, nil, + nil, 205, 189, 190, 191, 192, 194, nil, 199, 203, + 205, 189, 190, 191, 192, 194, 359, 199, 203, nil, + nil, nil, nil, 205, 189, 190, 191, 192, 194, nil, + 199, 203, nil, nil, nil, 306, nil, 25, nil, 32, + 1, nil, 7, 10, nil, 16, nil, 22, nil, 29, + nil, 2, nil, nil, 9, 13, 25, 321, 32, 1, + nil, 7, 10, nil, 16, nil, 22, nil, 29, nil, + 2, nil, nil, 9, 13, nil, 346, nil, 25, nil, + 32, 1, nil, 7, 10, nil, 16, nil, 22, nil, + 29, nil, 2, nil, nil, 9, 13, 25, 360, 32, + 1, nil, 7, 10, nil, 16, nil, 22, nil, 29, + nil, 2, nil, nil, 9, 13, nil, 370, nil, 25, + nil, 32, 1, nil, 7, 10, nil, 16, nil, 22, + nil, 29, nil, 2, nil, nil, 9, 13, 25, 374, + 32, 1, nil, 7, 10, nil, 16, nil, 22, nil, + 29, nil, 2, nil, nil, 9, 13, nil, 376, nil, + 25, nil, 32, 1, nil, 7, 10, nil, 16, nil, + 22, nil, 29, nil, 2, nil, nil, 9, 13, 25, + 377, 32, 1, nil, 7, 10, nil, 16, nil, 22, + nil, 29, nil, 2, nil, nil, 9, 13, nil, 293, + nil, 25, nil, 32, 1, nil, 7, 10, nil, 16, + nil, 22, nil, 29, nil, 2, nil, nil, 9, 13, + 25, 356, 32, 1, nil, 7, 10, nil, 16, nil, + 22, nil, 29, nil, 2, nil, nil, 9, 13, nil, + 378, nil, 25, nil, 32, 1, nil, 7, 10, nil, + 16, nil, 22, nil, 29, nil, 2, nil, nil, 9, + 13, 25, nil, 32, 1, nil, 7, 10, nil, 16, + nil, 22, nil, 29, nil, 2, nil, nil, 9, 13, + 25, nil, 32, 1, nil, 7, 10, nil, 16, nil, + 22, nil, 29, nil, 2, nil, nil, 9, 13 ] racc_action_check = [ - 54, 54, 147, 147, 54, 48, 147, 144, 147, 110, - 75, 44, 31, 106, 31, 19, 199, 198, 192, 122, - 110, 150, 150, 133, 106, 110, 192, 31, 75, 106, - 48, 121, 195, 54, 272, 147, 133, 54, 54, 147, - 147, 54, 272, 147, 199, 199, 54, 256, 147, 144, - 54, 31, 147, 19, 150, 256, 19, 122, 150, 150, - 122, 54, 150, 147, 153, 153, 150, 150, 245, 121, - 153, 150, 121, 275, 349, 349, 19, 249, 249, 201, - 122, 245, 150, 256, 256, 256, 256, 256, 256, 202, - 256, 256, 121, 154, 154, 325, 325, 153, 275, 275, - 146, 153, 153, 314, 314, 153, 187, 349, 204, 8, - 153, 349, 349, 146, 153, 349, 154, 187, 8, 8, - 349, 204, 187, 203, 349, 153, 154, 184, 325, 259, - 154, 154, 325, 325, 154, 349, 325, 259, 154, 154, - 12, 325, 277, 154, 12, 325, 312, 312, 97, 97, - 312, 12, 312, 277, 154, 97, 325, 113, 277, 86, - 24, 24, 113, 209, 24, 259, 259, 259, 259, 259, - 259, 196, 259, 259, 210, 196, 196, 177, 210, 312, - 177, 210, 24, 312, 312, 210, 97, 312, 267, 267, - 248, 248, 312, 24, 91, 267, 312, 24, 24, 152, - 85, 24, 214, 152, 152, 24, 24, 312, 26, 26, - 24, 5, 26, 1, 26, 5, 84, 1, 82, 217, - 289, 24, 5, 5, 1, 289, 267, 28, 28, 218, - 26, 28, 188, 28, 157, 157, 188, 188, 157, 219, - 157, 26, 247, 247, 220, 26, 26, 247, 247, 26, - 221, 81, 79, 225, 26, 26, 157, 78, 26, 180, - 28, 26, 236, 237, 28, 28, 74, 157, 28, 26, - 98, 157, 157, 28, 176, 157, 171, 28, 176, 176, - 157, 157, 99, 101, 157, 158, 158, 157, 28, 158, - 102, 158, 264, 264, 167, 157, 104, 264, 264, 70, - 68, 67, 63, 59, 287, 287, 58, 158, 287, 107, - 287, 286, 286, 57, 263, 286, 109, 286, 158, 265, - 111, 55, 158, 158, 114, 117, 158, 118, 123, 281, - 281, 158, 158, 197, 40, 158, 282, 287, 158, 284, - 35, 287, 287, 33, 286, 287, 158, 128, 286, 286, - 287, 30, 286, 23, 287, 20, 304, 286, 13, 132, - 316, 286, 281, 318, 134, 287, 281, 281, 326, 329, - 281, 331, 286, 332, 334, 281, 41, 41, 335, 281, - 41, 337, 41, 135, 252, 252, 252, 252, 348, 136, - 281, 252, 252, 350, 140, 43, 43, 2, 41, 43, - 139, 43, 42, 42, 138, nil, 42, nil, 42, 41, - nil, nil, nil, 41, 41, nil, nil, 41, nil, nil, - 280, 280, 41, 41, 42, nil, 41, nil, 43, 41, - nil, nil, 43, 43, nil, 42, 43, 41, nil, 42, - 42, 43, nil, 42, nil, 43, nil, nil, 42, 42, - nil, nil, 42, 280, nil, 42, 43, 280, 280, nil, - nil, 280, nil, 42, nil, nil, 280, 45, 45, nil, - 280, 45, nil, 45, nil, 251, 251, 251, 251, 251, - 251, 280, 251, 251, nil, 270, 270, nil, nil, 45, - nil, nil, 270, nil, 250, 250, 250, 250, nil, nil, - 45, 250, 250, nil, 45, 45, nil, nil, 45, nil, - nil, nil, nil, 45, 45, 159, 159, 45, 270, 159, - 45, 159, 270, 270, nil, nil, 270, nil, 45, nil, - nil, 270, nil, nil, nil, 270, nil, 159, nil, nil, - nil, 269, 269, nil, nil, 269, 270, 269, 159, nil, - nil, nil, 159, 159, nil, nil, 159, nil, nil, nil, - nil, 159, 159, 160, 160, 159, nil, 160, 159, 160, - nil, nil, nil, nil, 269, nil, 159, nil, 269, 269, - nil, nil, 269, nil, nil, 160, nil, 269, nil, 161, - 161, 269, nil, 161, nil, 161, 160, nil, nil, nil, - 160, 160, 269, nil, 160, nil, nil, nil, nil, 160, - 160, 161, nil, 160, nil, nil, 160, nil, nil, 162, - 162, nil, 161, 162, 160, 162, 161, 161, nil, nil, - 161, nil, nil, nil, nil, 161, 161, nil, nil, 161, - nil, 162, 161, nil, 62, 62, nil, nil, nil, nil, - 161, nil, 162, nil, nil, nil, 162, 162, nil, nil, - 162, nil, nil, nil, nil, 162, 162, 62, nil, 162, - 163, 163, 162, nil, 163, nil, 163, 62, nil, nil, - 162, 62, 62, nil, nil, 62, nil, nil, nil, 62, - 62, nil, 163, nil, 62, nil, 65, 65, nil, nil, - 65, nil, 65, 163, nil, 62, nil, 163, 163, nil, - nil, 163, nil, nil, nil, nil, 163, 163, 65, nil, - 163, 108, 108, 163, nil, 108, nil, 108, nil, 65, - nil, 163, nil, 65, 65, nil, nil, 65, nil, nil, - nil, nil, 65, 65, nil, nil, 65, 164, 164, 65, - nil, 164, nil, 164, 108, nil, nil, 65, 108, 108, - nil, nil, 108, nil, nil, nil, nil, 108, nil, 164, - nil, 108, nil, 170, 170, nil, nil, 170, nil, 170, - 164, nil, 108, nil, 164, 164, nil, nil, 164, nil, - nil, 239, 239, 164, 164, 170, nil, 164, 71, 71, - 164, nil, 71, nil, 71, nil, 170, nil, 164, nil, - 170, 170, 234, 234, 170, nil, 234, nil, 234, 170, - 170, nil, nil, 170, 239, nil, 170, nil, 239, 239, - nil, 71, 239, nil, 170, 71, 71, 239, nil, 71, - nil, 239, 223, 223, 71, 234, nil, nil, 71, 234, - 234, nil, 239, 234, nil, nil, nil, nil, 234, 71, - 227, 227, 234, nil, 227, 223, 227, nil, nil, nil, - nil, nil, nil, 234, nil, 223, nil, nil, nil, 223, - 223, nil, 227, 223, nil, 222, 222, 223, 223, 222, - nil, 222, 223, 227, nil, nil, nil, 227, 227, nil, - nil, 227, nil, 223, nil, nil, 227, 227, nil, nil, - 227, 216, 216, 227, nil, 216, nil, 216, 222, nil, - nil, 227, 222, 222, nil, nil, 222, nil, nil, nil, - nil, 222, 83, 83, nil, 222, 83, nil, 83, nil, - nil, nil, nil, nil, 216, nil, 222, nil, 216, 216, - nil, nil, 216, nil, 83, nil, nil, 216, 215, 215, - nil, 216, 215, nil, nil, 83, nil, nil, nil, 83, - 83, nil, 216, 83, nil, nil, nil, nil, 83, 83, - 166, 166, 83, nil, 166, 83, 166, nil, nil, nil, - nil, 215, nil, 83, nil, 215, 215, nil, nil, 215, - nil, nil, 166, nil, 215, nil, 168, 168, 215, nil, - 168, nil, 168, 166, nil, nil, nil, 166, 166, 215, - nil, 166, nil, nil, nil, nil, 166, 166, 168, nil, - 166, nil, nil, 166, nil, nil, 88, 88, nil, 168, - 88, 166, 88, 168, 168, nil, nil, 168, nil, nil, - nil, nil, 168, 168, nil, nil, 168, nil, 88, 168, - nil, nil, 169, 169, nil, nil, 169, 168, 169, 88, - nil, nil, nil, 88, 88, nil, nil, 88, nil, nil, - 183, 183, 88, 88, 169, nil, 88, nil, nil, 88, - nil, nil, nil, nil, nil, 169, nil, 88, nil, 169, - 169, nil, nil, 169, nil, nil, nil, nil, 169, 169, - 93, 93, 169, 183, 93, 169, 93, 183, 183, 89, - nil, 183, nil, 169, nil, nil, 183, nil, 89, 89, - 183, nil, 93, nil, nil, nil, nil, 89, 89, 89, - 89, 183, nil, 93, nil, nil, nil, 93, 93, 95, - 95, 93, nil, 95, 95, 95, 93, 93, nil, nil, - 93, 89, 89, 93, nil, 89, 89, 89, 89, 89, - 89, 93, 89, 89, 173, 173, nil, nil, 173, nil, - 173, nil, 95, nil, nil, nil, 95, 95, nil, nil, - 95, nil, nil, nil, nil, 95, 173, nil, nil, 95, - 165, 165, nil, nil, 165, nil, 165, 173, nil, nil, - 95, 173, 173, nil, nil, 173, nil, nil, nil, nil, - 173, 173, 165, nil, 173, nil, nil, 173, nil, nil, - nil, nil, nil, 165, nil, 173, nil, 165, 165, nil, - nil, 165, 149, 149, nil, nil, 165, 165, nil, nil, - 165, nil, nil, 165, nil, 149, 149, nil, nil, nil, - nil, 165, nil, nil, 149, 149, 149, 149, 156, 156, - nil, nil, nil, nil, nil, nil, 156, 156, 156, 156, - 156, nil, nil, nil, nil, nil, nil, nil, 149, 149, - nil, nil, 149, 149, 149, 149, 149, 149, nil, 149, - 149, 156, 156, nil, nil, 156, 156, 156, 156, 156, - 156, nil, 156, 156, 115, 115, nil, nil, nil, nil, - nil, nil, nil, 115, 115, 115, 115, 119, 119, nil, - nil, nil, nil, nil, nil, nil, 119, 119, 119, 119, - nil, nil, nil, nil, nil, nil, nil, 115, 115, nil, - nil, 115, 115, 115, 115, 115, 115, nil, 115, 115, - 119, 119, nil, nil, 119, 119, 119, 119, 119, 119, - nil, 119, 119, 254, 254, nil, nil, nil, nil, nil, - nil, nil, 254, 254, 254, 254, 258, 258, nil, nil, - nil, nil, nil, nil, nil, 258, 258, 258, 258, nil, - nil, 260, 260, 260, 260, 260, 260, 254, 260, 260, - 254, 254, 254, 254, 254, 254, nil, 254, 254, nil, - nil, nil, nil, 258, 258, 258, 258, 258, 258, nil, - 258, 258, 116, 116, nil, nil, nil, nil, nil, nil, - nil, 116, 116, 116, 116, 255, nil, nil, nil, nil, - nil, nil, nil, 255, 253, nil, nil, nil, nil, nil, - nil, nil, 253, nil, nil, 116, 116, nil, nil, 116, - 116, 116, 116, 116, 116, nil, 116, 116, 172, nil, - nil, 255, 255, 255, 255, 255, 255, nil, 255, 255, - 253, 253, 253, 253, 253, 253, nil, 253, 253, 172, - 291, 172, 172, nil, 172, 172, nil, 172, nil, 172, - nil, 172, nil, 172, nil, nil, 172, 172, nil, 262, - nil, 291, nil, 291, 291, nil, 291, 291, nil, 291, - nil, 291, nil, 291, nil, 291, nil, nil, 291, 291, - 262, 293, 262, 262, nil, 262, 262, nil, 262, nil, - 262, nil, 262, nil, 262, nil, nil, 262, 262, nil, - 297, nil, 293, nil, 293, 293, nil, 293, 293, nil, - 293, nil, 293, nil, 293, nil, 293, nil, nil, 293, - 293, 297, 213, 297, 297, nil, 297, 297, nil, 297, - nil, 297, nil, 297, nil, 297, nil, nil, 297, 297, - nil, 343, nil, 213, nil, 213, 213, nil, 213, 213, - nil, 213, nil, 213, nil, 213, nil, 213, nil, nil, - 213, 213, 343, 352, 343, 343, nil, 343, 343, nil, - 343, nil, 343, nil, 343, nil, 343, nil, nil, 343, - 343, nil, 354, nil, 352, nil, 352, 352, nil, 352, - 352, nil, 352, nil, 352, nil, 352, nil, 352, nil, - nil, 352, 352, 354, 206, 354, 354, nil, 354, 354, - nil, 354, nil, 354, nil, 354, nil, 354, nil, nil, - 354, 354, nil, 359, nil, 206, nil, 206, 206, nil, - 206, 206, nil, 206, nil, 206, nil, 206, nil, 206, - nil, nil, 206, 206, 359, 361, 359, 359, nil, 359, - 359, nil, 359, nil, 359, nil, 359, nil, 359, nil, - nil, 359, 359, nil, nil, nil, 361, nil, 361, 361, - nil, 361, 361, nil, 361, nil, 361, nil, 361, nil, - 361, nil, nil, 361, 361, 4, nil, 4, 4, nil, - 4, 4, nil, 4, nil, 4, nil, 4, nil, 4, - nil, nil, 4, 4, 0, nil, 0, 0, nil, 0, - 0, nil, 0, nil, 0, nil, 0, nil, 0, nil, - nil, 0, 0 ] + 197, 197, 149, 19, 197, 19, 197, 151, 79, 142, + 237, 170, 56, 33, 48, 208, 155, 16, 19, 169, + 169, 217, 197, 56, 170, 212, 79, 155, 56, 364, + 364, 134, 155, 197, 217, 237, 237, 197, 197, 48, + 149, 197, 19, 149, 134, 151, 197, 197, 151, 82, + 197, 142, 169, 197, 168, 16, 169, 169, 16, 215, + 169, 197, 364, 149, 169, 169, 364, 364, 151, 169, + 364, 172, 172, 351, 351, 364, 268, 172, 16, 364, + 169, 60, 168, 168, 338, 338, 7, 336, 336, 268, + 364, 336, 60, 336, 1, 7, 7, 60, 1, 216, + 101, 101, 240, 84, 172, 1, 351, 101, 172, 172, + 351, 351, 172, 240, 351, 274, 274, 172, 240, 351, + 336, 172, 274, 351, 336, 336, 302, 219, 336, 176, + 176, 302, 172, 336, 351, 94, 94, 336, 101, 94, + 10, 94, 297, 111, 10, 77, 184, 111, 336, 184, + 297, 10, 176, 274, 111, 111, 157, 94, 120, 278, + 278, 221, 176, 120, 157, 74, 176, 176, 94, 223, + 176, 224, 94, 94, 176, 176, 94, 262, 262, 176, + 225, 94, 94, 22, 22, 94, 73, 22, 94, 72, + 176, 26, 228, 177, 177, 26, 94, 177, 229, 177, + 119, 203, 26, 26, 119, 22, 279, 279, 233, 283, + 262, 119, 119, 71, 262, 262, 22, 283, 262, 87, + 22, 22, 67, 262, 22, 65, 177, 262, 22, 22, + 177, 177, 93, 22, 177, 63, 25, 25, 262, 177, + 25, 248, 25, 177, 22, 283, 283, 283, 283, 283, + 283, 249, 283, 283, 177, 29, 29, 95, 25, 29, + 231, 29, 118, 118, 231, 255, 118, 231, 118, 25, + 261, 231, 59, 25, 25, 294, 294, 25, 58, 199, + 294, 294, 25, 25, 118, 270, 25, 272, 29, 25, + 98, 99, 29, 29, 100, 118, 29, 25, 102, 118, + 118, 29, 106, 118, 107, 29, 40, 40, 118, 118, + 40, 109, 118, 304, 304, 118, 29, 304, 117, 304, + 300, 300, 188, 118, 300, 46, 300, 295, 295, 280, + 280, 280, 280, 45, 295, 41, 280, 280, 36, 40, + 122, 125, 80, 40, 40, 293, 304, 40, 126, 32, + 304, 304, 40, 300, 304, 128, 40, 300, 300, 304, + 295, 300, 167, 304, 295, 295, 300, 40, 295, 166, + 300, 162, 165, 295, 304, 162, 162, 295, 189, 189, + 129, 300, 189, 311, 189, 150, 131, 323, 295, 0, + 325, 0, 0, 326, 0, 0, 327, 0, 329, 0, + 189, 0, 334, 0, 190, 190, 0, 0, 190, 12, + 190, 189, 277, 277, 147, 189, 189, 277, 277, 189, + 34, 34, 34, 34, 189, 189, 190, 346, 189, 347, + 146, 189, 352, 132, 191, 191, 363, 190, 191, 189, + 191, 190, 190, 175, 5, 190, 365, 175, 175, 4, + 190, 190, 2, 143, 190, 138, 191, 190, 181, nil, + 192, 192, 181, 181, 192, 190, 192, 191, nil, 164, + nil, 191, 191, 164, 164, 191, 30, 30, 30, 30, + 191, 191, 192, nil, 191, nil, nil, 191, nil, nil, + 42, 42, nil, 192, 42, 191, 42, 192, 192, nil, + nil, 192, 31, 31, 31, 31, 192, 192, nil, nil, + 192, nil, 42, 192, nil, nil, 43, 43, nil, nil, + 43, 192, 43, 42, nil, nil, nil, 42, 42, nil, + nil, 42, 24, 24, 24, 24, 42, 42, 43, nil, + 42, 44, 44, 42, nil, 44, nil, 44, nil, 43, + nil, 42, nil, 43, 43, nil, nil, 43, nil, nil, + nil, nil, 43, 43, nil, nil, 43, 193, 193, 43, + nil, 193, nil, 193, 44, nil, nil, 43, 44, 44, + nil, nil, 44, nil, nil, nil, nil, 44, nil, 193, + nil, 44, nil, 201, 201, nil, nil, 201, nil, 201, + 193, nil, 44, nil, 193, 193, nil, nil, 193, nil, + nil, nil, nil, 193, 193, 201, nil, 193, nil, nil, + 193, nil, nil, 194, 194, nil, 201, 194, 193, 194, + 201, 201, nil, nil, 201, nil, nil, nil, nil, 201, + 201, nil, nil, 201, nil, 194, 201, nil, nil, 276, + 276, nil, nil, 276, 201, 276, 194, nil, nil, nil, + 194, 194, nil, nil, 194, nil, nil, nil, nil, 194, + 194, 57, 57, 194, nil, 57, 194, 57, nil, nil, + nil, nil, 276, nil, 194, nil, 276, 276, nil, nil, + 276, nil, 264, 264, nil, 276, 264, nil, 264, 276, + nil, nil, nil, nil, 57, nil, nil, nil, 57, 57, + 276, nil, 57, nil, 264, nil, nil, 57, 253, 253, + nil, 57, nil, nil, nil, 264, nil, nil, nil, 264, + 264, nil, 57, 264, nil, nil, 239, 239, 264, 264, + nil, 253, 264, 246, 246, 264, nil, 246, nil, 246, + nil, 253, nil, 264, nil, 253, 253, nil, nil, 253, + nil, nil, nil, 253, 253, 66, 66, nil, 253, 239, + nil, nil, nil, 239, 239, nil, 246, 239, nil, 253, + 246, 246, 239, nil, 246, nil, 239, nil, 66, 246, + 238, 238, nil, 246, nil, nil, nil, 239, 66, nil, + nil, nil, 66, 66, 246, nil, 66, nil, 68, 68, + 66, 66, 68, nil, 68, 66, nil, 281, 281, 281, + 281, 281, 281, 238, 281, 281, 66, 238, 238, nil, + 68, 238, nil, nil, nil, nil, 238, nil, 195, 195, + 238, 68, 195, nil, 195, 68, 68, nil, nil, 68, + nil, 238, nil, nil, 68, 68, nil, nil, 68, nil, + 195, 68, nil, nil, 227, 227, nil, nil, 227, 68, + 227, 195, nil, nil, nil, 195, 195, nil, nil, 195, + nil, nil, nil, nil, 195, 195, 226, 226, 195, nil, + 226, 195, 226, nil, nil, nil, nil, 227, nil, 195, + nil, 227, 227, nil, nil, 227, nil, 222, 222, nil, + 227, 222, nil, nil, 227, nil, nil, nil, nil, 226, + nil, nil, nil, 226, 226, 227, nil, 226, nil, 75, + 75, nil, 226, 75, nil, 75, 226, nil, nil, nil, + 222, nil, nil, nil, 222, 222, nil, 226, 222, nil, + 196, 196, nil, 222, 196, nil, 196, 222, nil, nil, + nil, nil, 75, nil, nil, nil, 75, 75, 222, nil, + 75, nil, 196, nil, nil, 75, 198, 198, nil, 75, + 198, nil, 198, 196, nil, nil, nil, 196, 196, nil, + 75, 196, nil, nil, 206, 206, 196, 196, 198, nil, + 196, nil, nil, 196, nil, nil, nil, nil, nil, 198, + nil, 196, nil, 198, 198, nil, nil, 198, nil, nil, + nil, nil, 198, 198, 205, 205, 198, 206, 205, 198, + 205, 206, 206, 104, nil, 206, nil, 198, nil, nil, + 206, nil, 104, 104, 206, nil, 205, nil, nil, nil, + nil, 104, 104, 104, 104, 206, nil, 205, nil, nil, + nil, 205, 205, 96, 96, 205, nil, 96, 96, 96, + 205, 205, nil, nil, 205, 104, 104, 205, nil, 104, + 104, 104, 104, 104, 104, 205, 104, 104, 202, 202, + nil, nil, 202, nil, 202, nil, 96, nil, nil, nil, + 96, 96, nil, nil, 96, nil, nil, nil, nil, 96, + 202, nil, nil, 96, 88, 88, nil, nil, 88, nil, + 88, 202, nil, nil, 96, 202, 202, nil, nil, 202, + nil, nil, nil, nil, 202, 202, 88, nil, 202, nil, + nil, 202, nil, nil, 92, 92, nil, 88, 92, 202, + 92, 88, 88, nil, nil, 88, nil, nil, nil, nil, + 88, 88, nil, nil, 88, nil, 92, 88, nil, nil, + 200, 200, nil, nil, 200, 88, 200, 92, nil, nil, + nil, 92, 92, nil, nil, 92, nil, nil, nil, nil, + 92, 92, 200, nil, 92, nil, nil, 92, nil, nil, + nil, nil, nil, 200, nil, 92, nil, 200, 200, nil, + nil, 200, 174, 174, nil, nil, 200, 200, nil, nil, + 200, nil, nil, 200, nil, 174, 174, nil, nil, nil, + nil, 200, nil, nil, 174, 174, 174, 174, 179, 179, + nil, nil, nil, nil, nil, nil, 179, 179, 179, 179, + 179, nil, nil, 282, 282, 282, 282, nil, 174, 174, + 282, 282, 174, 174, 174, 174, 174, 174, nil, 174, + 174, 179, 179, nil, nil, 179, 179, 179, 179, 179, + 179, nil, 179, 179, 213, 213, nil, nil, nil, nil, + nil, nil, nil, 213, 213, 213, 213, 145, 145, nil, + nil, nil, nil, nil, nil, nil, 145, 145, 145, 145, + nil, nil, nil, nil, nil, nil, nil, 213, 213, nil, + nil, 213, 213, 213, 213, 213, 213, nil, 213, 213, + 145, 145, nil, nil, 145, 145, 145, 145, 145, 145, + nil, 145, 145, 284, 284, nil, nil, nil, nil, nil, + nil, nil, 284, 284, 284, 284, 288, 288, nil, nil, + nil, nil, nil, nil, nil, 288, 288, 288, 288, nil, + nil, 290, 290, 290, 290, 290, 290, 284, 290, 290, + 284, 284, 284, 284, 284, 284, nil, 284, 284, nil, + nil, nil, nil, 288, 288, 288, 288, 288, 288, nil, + 288, 288, 144, 144, nil, nil, nil, nil, nil, nil, + nil, 144, 144, 144, 144, 285, nil, nil, nil, nil, + nil, nil, nil, 285, 289, nil, nil, nil, nil, nil, + nil, nil, 289, nil, nil, 144, 144, 286, nil, 144, + 144, 144, 144, 144, 144, 286, 144, 144, nil, nil, + nil, 285, 285, 285, 285, 285, 285, nil, 285, 285, + 289, 289, 289, 289, 289, 289, 319, 289, 289, nil, + nil, nil, nil, 286, 286, 286, 286, 286, 286, nil, + 286, 286, nil, nil, nil, 220, nil, 319, nil, 319, + 319, nil, 319, 319, nil, 319, nil, 319, nil, 319, + nil, 319, nil, nil, 319, 319, 220, 235, 220, 220, + nil, 220, 220, nil, 220, nil, 220, nil, 220, nil, + 220, nil, nil, 220, 220, nil, 292, nil, 235, nil, + 235, 235, nil, 235, 235, nil, 235, nil, 235, nil, + 235, nil, 235, nil, nil, 235, 235, 292, 320, 292, + 292, nil, 292, 292, nil, 292, nil, 292, nil, 292, + nil, 292, nil, nil, 292, 292, nil, 358, nil, 320, + nil, 320, 320, nil, 320, 320, nil, 320, nil, 320, + nil, 320, nil, 320, nil, nil, 320, 320, 358, 367, + 358, 358, nil, 358, 358, nil, 358, nil, 358, nil, + 358, nil, 358, nil, nil, 358, 358, nil, 369, nil, + 367, nil, 367, 367, nil, 367, 367, nil, 367, nil, + 367, nil, 367, nil, 367, nil, nil, 367, 367, 369, + 373, 369, 369, nil, 369, 369, nil, 369, nil, 369, + nil, 369, nil, 369, nil, nil, 369, 369, nil, 204, + nil, 373, nil, 373, 373, nil, 373, 373, nil, 373, + nil, 373, nil, 373, nil, 373, nil, nil, 373, 373, + 204, 305, 204, 204, nil, 204, 204, nil, 204, nil, + 204, nil, 204, nil, 204, nil, nil, 204, 204, nil, + 375, nil, 305, nil, 305, 305, nil, 305, 305, nil, + 305, nil, 305, nil, 305, nil, 305, nil, nil, 305, + 305, 375, nil, 375, 375, nil, 375, 375, nil, 375, + nil, 375, nil, 375, nil, 375, nil, nil, 375, 375, + 15, nil, 15, 15, nil, 15, 15, nil, 15, nil, + 15, nil, 15, nil, 15, nil, nil, 15, 15 ] racc_action_pointer = [ - 1734, 177, 353, nil, 1715, 175, nil, nil, 103, nil, - nil, nil, 104, 343, nil, nil, nil, nil, nil, 13, - 347, nil, nil, 345, 158, nil, 206, nil, 225, nil, - 349, 6, nil, 343, nil, 316, nil, nil, nil, nil, - 326, 374, 400, 393, -13, 465, nil, nil, -7, nil, - nil, nil, nil, nil, -2, 281, nil, 290, 283, 297, - nil, nil, 642, 296, nil, 694, nil, 278, 294, nil, - 287, 796, nil, nil, 243, 4, nil, nil, 234, 229, - nil, 245, 195, 930, 193, 177, 136, nil, 1034, 1111, - nil, 171, nil, 1108, nil, 1147, nil, 146, 247, 259, - nil, 260, 282, nil, 284, nil, -11, 301, 719, 276, - -15, 320, nil, 122, 316, 1297, 1415, 318, 290, 1310, - nil, 29, 17, 320, nil, nil, nil, nil, 324, nil, - nil, nil, 318, 12, 341, 371, 366, nil, 381, 380, - 382, nil, nil, nil, -4, nil, 88, 0, nil, 1238, - 19, nil, 192, 62, 91, nil, 1251, 232, 283, 513, - 561, 587, 617, 668, 745, 1198, 978, 231, 1004, 1060, - 771, 213, 1469, 1172, nil, nil, 267, 168, nil, nil, - 248, nil, nil, 1078, 125, nil, nil, 82, 186, nil, - nil, nil, 0, nil, nil, -8, 164, 322, 5, -6, - nil, 64, 74, 98, 96, nil, 1655, nil, nil, 155, - 138, nil, nil, 1573, 193, 956, 909, 179, 220, 199, - 204, 241, 883, 840, nil, 246, nil, 858, nil, nil, - nil, nil, nil, nil, 810, nil, 251, 239, nil, 789, - nil, nil, nil, nil, nil, 56, nil, 186, 129, 16, - 440, 421, 330, 1436, 1356, 1427, 29, nil, 1369, 111, - 1347, nil, 1510, 283, 236, 312, nil, 186, nil, 539, - 483, nil, 22, nil, nil, 48, nil, 118, nil, nil, - 418, 327, 324, nil, 330, nil, 309, 302, nil, 185, - nil, 1491, nil, 1532, nil, nil, nil, 1551, nil, nil, - nil, nil, nil, nil, 344, nil, nil, nil, nil, nil, - nil, nil, 144, nil, 92, nil, 329, nil, 355, nil, - nil, nil, nil, nil, nil, 93, 360, nil, nil, 346, - nil, 348, 350, nil, 351, 355, nil, 372, nil, nil, - nil, nil, nil, 1592, nil, nil, nil, nil, 379, 72, - 384, nil, 1614, nil, 1633, nil, nil, nil, nil, 1674, - nil, 1696, nil, nil, nil ] + 359, 58, 408, nil, 441, 436, nil, 80, nil, nil, + 104, nil, 409, nil, nil, 1700, 15, nil, nil, -3, + nil, nil, 181, nil, 468, 234, 155, nil, nil, 253, + 412, 438, 347, -2, 356, nil, 314, nil, nil, nil, + 304, 295, 488, 514, 539, 309, 325, nil, 2, nil, + nil, nil, nil, nil, nil, nil, -12, 669, 238, 264, + 57, nil, nil, 229, nil, 213, 763, 199, 806, nil, + nil, 207, 166, 163, 159, 927, nil, 122, nil, 2, + 319, nil, 26, nil, 97, nil, nil, 196, 1112, nil, + nil, nil, 1142, 209, 133, 234, 1061, nil, 267, 268, + 271, 98, 275, nil, 1025, nil, 279, 296, nil, 303, + nil, 107, nil, nil, nil, nil, nil, 306, 260, 164, + 123, nil, 332, nil, nil, 300, 325, nil, 343, 357, + nil, 363, 413, nil, 20, nil, nil, nil, 432, nil, + nil, nil, -2, 441, 1385, 1280, 423, 377, nil, 0, + 377, 5, nil, nil, nil, -8, nil, 138, nil, nil, + nil, nil, 325, nil, 462, 360, 358, 322, 32, 17, + -1, nil, 69, nil, 1208, 436, 127, 191, nil, 1221, + nil, 451, nil, nil, 137, nil, nil, nil, 311, 376, + 402, 432, 458, 565, 621, 836, 948, -2, 974, 216, + 1168, 591, 1086, 138, 1640, 1022, 992, nil, 9, nil, + nil, nil, 23, 1267, nil, 44, 74, 9, nil, 112, + 1476, 152, 905, 129, 162, 140, 884, 862, 152, 189, + nil, 224, nil, 200, nil, 1498, nil, -15, 788, 734, + 78, nil, nil, nil, nil, nil, 741, nil, 232, 239, + nil, nil, nil, 716, nil, 254, nil, nil, nil, nil, + nil, 246, 175, nil, 690, nil, nil, nil, 64, nil, + 278, nil, 280, nil, 113, nil, 647, 356, 98, 145, + 275, 763, 1199, 191, 1326, 1397, 1419, nil, 1339, 1406, + 1317, nil, 1517, 314, 219, 325, nil, 130, nil, nil, + 318, nil, 91, nil, 311, 1662, nil, nil, nil, nil, + nil, 371, nil, nil, nil, nil, nil, nil, nil, 1457, + 1539, nil, nil, 364, nil, 367, 370, 373, nil, 375, + nil, nil, nil, nil, 393, nil, 85, nil, 73, nil, + nil, nil, nil, nil, nil, nil, 396, 421, nil, nil, + nil, 71, 424, nil, nil, nil, nil, nil, 1558, nil, + nil, nil, nil, 427, 27, 437, nil, 1580, nil, 1599, + nil, nil, nil, 1621, nil, 1681, nil, nil, nil ] racc_action_default = [ - -183, -220, -40, -13, -1, -220, -14, -2, -220, -15, - -3, -174, -175, -220, -16, -5, -172, -17, -6, -220, - -220, -7, -8, -220, -173, -9, -220, -10, -220, -11, - -220, -220, -12, -220, -175, -183, -173, -41, -4, -39, - -220, -220, -220, -220, -183, -220, -180, -182, -183, -176, - -179, -178, -208, -181, -75, -82, -159, -29, -30, -200, - -107, -31, -220, -218, -161, -220, -34, -32, -64, -33, - -21, -220, -112, -22, -220, -63, -23, -62, -26, -27, - -160, -220, -28, -220, -104, -96, -103, -99, -220, -220, - -97, -93, -101, -220, -120, -220, -102, -220, -94, -98, - -100, -95, -220, -163, -165, -162, -183, -43, -220, -75, - -183, -220, -185, -184, -220, -72, -74, -220, -183, -73, - -194, -220, -220, -220, -158, -157, -70, -68, -65, -76, - -71, -64, -60, -63, -66, -206, -69, -58, -67, -220, - -206, -80, -81, -83, -220, -20, -220, -220, -108, -220, - -220, -85, -220, -220, -220, -129, -220, -220, -220, -220, - -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, - -220, -220, -220, -220, -136, -203, -220, -220, -212, -216, - -220, -215, -211, -220, -220, -46, -200, -183, -220, -47, - -49, -63, -220, -56, -55, -82, -220, -220, -206, -220, - 365, -193, -191, -220, -220, -188, -220, -217, -196, -220, - -220, -177, -195, -220, -220, -61, -220, -207, -220, -75, - -207, -220, -220, -220, -18, -220, -109, -220, -110, -24, - -25, -204, -205, -113, -220, -155, -220, -63, -153, -220, - -147, -156, -148, -154, -106, -220, -139, -124, -126, -125, - -127, -131, -128, -133, -138, -135, -132, -121, -137, -134, - -130, -122, -220, -117, -123, -205, -201, -220, -209, -220, - -220, -141, -220, -145, -164, -220, -44, -220, -52, -51, - -220, -220, -206, -114, -220, -45, -220, -220, -186, -220, - -187, -220, -167, -220, -197, -198, -199, -220, -171, -35, - -59, -78, -77, -36, -206, -84, -38, -79, -19, -219, - -111, -86, -220, -150, -206, -105, -117, -116, -220, -202, - -213, -210, -214, -142, -140, -220, -220, -50, -48, -90, - -91, -87, -88, -53, -92, -89, -54, -220, -37, -192, - -190, -189, -166, -220, -169, -170, -57, -152, -205, -220, - -220, -115, -220, -146, -220, -42, -168, -151, -149, -220, - -119, -220, -144, -118, -143 ] + -193, -230, -50, -9, -230, -22, -10, -230, -11, -184, + -185, -12, -230, -182, -13, -1, -230, -14, -2, -230, + -15, -3, -183, -16, -5, -230, -230, -17, -6, -230, + -18, -7, -230, -230, -230, -8, -193, -185, -183, -51, + -85, -92, -230, -230, -230, -193, -230, -4, -193, -190, + -186, -188, -189, -218, -192, -191, -193, -230, -85, -53, + -193, -43, -33, -210, -117, -31, -230, -230, -230, -44, + -32, -74, -36, -37, -230, -230, -122, -38, -169, -73, + -39, -72, -40, -41, -228, -171, -170, -42, -230, -111, + -130, -112, -230, -104, -230, -108, -230, -110, -105, -114, + -106, -230, -113, -109, -230, -107, -103, -230, -49, -230, + -26, -230, -27, -24, -25, -172, -173, -175, -230, -230, + -194, -195, -230, -86, -81, -70, -76, -74, -216, -79, + -68, -77, -230, -168, -73, -167, -80, -78, -75, -90, + -91, -93, -230, -216, -82, -84, -230, -193, 379, -230, + -230, -230, -204, -57, -210, -193, -59, -230, -66, -65, + -56, -73, -230, -95, -230, -216, -230, -92, -230, -230, + -230, -30, -230, -118, -230, -230, -230, -230, -139, -230, + -146, -230, -213, -225, -230, -222, -221, -226, -230, -230, + -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, + -230, -230, -230, -230, -230, -230, -230, -22, -183, -21, + -23, -20, -230, -83, -19, -203, -230, -230, -198, -201, + -230, -230, -71, -217, -230, -85, -230, -230, -217, -230, + -227, -230, -206, -230, -187, -230, -205, -230, -230, -230, + -230, -54, -62, -61, -214, -215, -230, -124, -230, -216, + -55, -35, -34, -230, -28, -230, -163, -157, -166, -158, + -164, -73, -230, -165, -230, -120, -119, -123, -230, -116, + -230, -149, -215, -211, -230, -219, -230, -134, -136, -135, + -137, -141, -138, -143, -148, -145, -142, -131, -147, -144, + -140, -132, -230, -127, -133, -230, -151, -230, -155, -174, + -230, -196, -230, -197, -230, -230, -177, -45, -69, -87, + -46, -216, -88, -89, -94, -48, -208, -207, -209, -230, + -230, -181, -60, -98, -63, -102, -99, -100, -101, -97, + -64, -58, -96, -47, -230, -29, -230, -160, -216, -121, + -115, -229, -212, -223, -220, -224, -127, -230, -126, -152, + -150, -230, -230, -202, -199, -200, -176, -67, -230, -179, + -180, -52, -162, -215, -230, -230, -125, -230, -156, -230, + -178, -161, -159, -230, -129, -230, -154, -128, -153 ] racc_goto_table = [ - 31, 69, 205, 13, 31, 40, 178, 13, 35, 242, - 218, 148, 67, 23, 38, 221, 4, 23, 236, 44, - 126, 61, 135, 137, 58, 140, 103, 49, 70, 141, - 7, 130, 271, 229, 47, 317, 188, 76, 114, 69, - 199, 270, 128, 152, 333, 336, 226, 118, 273, 349, - 67, 127, 305, 240, 125, 39, 314, 132, 104, 61, - 214, 209, 58, 48, 123, 112, 146, 176, 328, 212, - 203, 204, 56, 284, 112, 76, 107, 198, 120, 294, - 196, 177, 33, nil, nil, 179, nil, nil, 351, nil, - nil, nil, nil, nil, nil, 313, nil, nil, nil, nil, - nil, nil, 56, nil, 236, nil, 229, nil, nil, nil, - 56, nil, nil, nil, nil, nil, nil, 275, nil, 323, - nil, nil, nil, nil, nil, nil, nil, 69, nil, 211, - nil, 69, nil, nil, nil, 273, 47, 47, 67, nil, - nil, 235, 67, nil, nil, nil, nil, 61, 208, nil, - 58, 61, nil, 125, 58, nil, nil, 337, 245, nil, - nil, nil, nil, 230, nil, 282, nil, 76, nil, 141, - nil, 235, 31, 310, nil, 13, 320, nil, 341, 346, - 274, 126, 257, 125, 300, 23, 261, 304, 262, 350, - 353, 302, 130, nil, 141, nil, nil, nil, 56, nil, - 69, 56, 56, 128, nil, 357, 31, nil, nil, 13, - nil, 67, 127, 31, 236, 125, 13, 295, nil, 23, - 61, nil, 291, 58, nil, nil, 23, 235, nil, 297, - nil, 56, nil, nil, nil, nil, 230, nil, nil, 125, + 33, 87, 173, 5, 47, 259, 218, 36, 185, 139, + 15, 65, 54, 18, 109, 33, 45, 50, 5, 138, + 128, 61, 19, 255, 108, 62, 143, 162, 130, 146, + 296, 168, 252, 164, 136, 348, 111, 19, 165, 124, + 119, 122, 163, 295, 116, 87, 83, 364, 107, 121, + 147, 175, 324, 330, 210, 170, 224, 298, 121, 82, + 163, 152, 210, 266, 137, 61, 211, 257, 314, 62, + 338, 229, 181, 125, 214, 117, 221, 135, 233, 48, + 187, 163, 150, 59, 236, 216, 72, 217, 366, 331, + 83, 317, 184, 248, 12, 337, nil, nil, nil, nil, + nil, nil, nil, 82, 126, nil, nil, nil, nil, 209, + nil, nil, nil, 255, 207, nil, 252, 209, nil, 349, + 158, nil, 207, nil, 158, nil, 237, nil, nil, nil, + 72, nil, nil, 19, nil, 139, nil, nil, nil, nil, + nil, 19, nil, nil, nil, 54, 298, 54, 87, nil, + 234, 263, 249, nil, nil, 87, nil, nil, nil, nil, + 232, nil, 270, nil, nil, 268, nil, nil, 61, nil, + nil, nil, 251, nil, nil, 61, nil, 334, nil, 62, + nil, 343, nil, nil, nil, 263, nil, nil, 354, nil, + 78, 309, nil, 83, nil, 287, 139, 371, 339, 291, + 83, 138, 368, nil, 33, 311, 82, 5, 78, 135, + 308, 312, 313, 82, 292, 255, 136, 329, 329, 158, + 33, 124, nil, 5, 299, nil, 19, nil, nil, nil, + 305, 332, 87, 72, 78, 33, 256, 316, 5, 357, + 72, 263, 19, 135, nil, 320, 137, nil, nil, 77, + nil, nil, 61, 187, nil, nil, 251, 19, nil, 135, + nil, 345, 328, 328, nil, nil, 365, 131, nil, 80, + 256, nil, nil, nil, 263, 135, 135, 83, nil, nil, + nil, 47, nil, nil, nil, 353, 126, 133, nil, 355, + 82, nil, 33, 77, 47, 5, nil, nil, nil, 135, + nil, nil, 323, 323, 158, 33, nil, nil, 5, 47, + nil, nil, nil, 80, 19, nil, nil, 72, nil, 33, + 33, 362, 5, 5, nil, nil, 256, 19, nil, 358, + 263, nil, 135, nil, nil, nil, nil, 78, nil, nil, + 78, 19, 19, 263, 78, nil, nil, 47, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 33, 256, + nil, 5, 47, nil, 47, nil, 73, 33, nil, 33, + 5, nil, 5, 33, 78, 33, 5, 373, 5, 375, + 19, nil, nil, nil, 129, nil, nil, nil, 135, 19, + 78, 19, nil, nil, nil, 19, 77, 19, nil, 260, + 159, 135, nil, 77, 159, nil, 78, 78, nil, nil, + 73, nil, nil, nil, nil, 256, 80, nil, nil, 133, + nil, 78, nil, 80, nil, nil, nil, nil, 256, nil, + 78, nil, nil, 260, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 131, + nil, nil, nil, 133, 104, nil, nil, nil, nil, nil, + nil, nil, nil, 78, nil, 326, 326, nil, nil, 133, + nil, 144, 145, nil, nil, nil, nil, nil, nil, nil, + 77, nil, nil, nil, nil, 327, 327, nil, nil, 260, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 159, + 80, nil, nil, nil, nil, nil, nil, nil, nil, 133, + nil, nil, nil, 73, nil, nil, 258, 178, nil, 78, + 73, 179, 260, 180, nil, nil, nil, nil, nil, nil, + nil, nil, 78, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 133, nil, nil, nil, nil, 213, nil, nil, + 258, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 129, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 260, nil, + nil, nil, 325, 325, 159, nil, nil, nil, nil, nil, + nil, 260, nil, nil, nil, nil, nil, 73, 133, nil, + nil, nil, nil, nil, nil, nil, 258, nil, nil, nil, + nil, 133, nil, nil, nil, nil, nil, nil, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, nil, 288, + 289, 290, nil, nil, 294, nil, nil, nil, nil, 258, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 78, nil, 79, 179, nil, nil, 235, nil, - nil, nil, 31, 56, nil, 13, nil, nil, 331, 331, - 125, 56, 38, 57, nil, 23, nil, 330, 330, nil, - 125, 125, 134, nil, 136, nil, nil, 56, nil, nil, - 78, 31, 79, 31, 13, nil, 13, 31, nil, nil, - 13, 38, nil, 124, 23, nil, 23, 38, 102, 343, - 23, 57, nil, 235, nil, nil, nil, nil, 56, nil, - nil, nil, nil, 117, nil, 125, nil, nil, 56, 56, - nil, nil, nil, nil, 193, nil, 194, 235, 193, nil, - 194, nil, nil, 31, nil, nil, 13, 82, nil, 125, - nil, 151, 31, 38, 31, 13, 23, 13, nil, 31, - nil, 31, 13, nil, 13, 23, nil, 23, 359, 38, - 361, 38, 23, 56, 23, 151, nil, 138, 78, nil, - 79, 238, 78, 241, 79, 82, nil, nil, 151, nil, - nil, nil, nil, nil, nil, nil, nil, 56, nil, 57, - nil, nil, 124, 57, nil, nil, nil, nil, nil, nil, - nil, 238, nil, 241, nil, 193, nil, 194, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, - nil, nil, 124, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 134, nil, 136, nil, nil, nil, nil, - nil, 78, nil, 79, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 124, nil, nil, 238, nil, 241, - nil, nil, 57, 82, 89, nil, 243, 82, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 124, 115, - 116, nil, nil, 119, nil, nil, 301, nil, 238, nil, - 241, nil, 307, nil, nil, 193, 243, 194, 332, 332, - 334, 334, nil, nil, 311, nil, nil, nil, nil, 124, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 329, - 329, 155, nil, nil, nil, nil, 156, nil, 138, nil, - nil, 174, nil, nil, nil, nil, 82, nil, nil, 322, - nil, nil, nil, 238, nil, 241, nil, nil, nil, nil, - nil, nil, 243, nil, nil, nil, 339, 340, nil, nil, - nil, nil, nil, nil, 124, nil, nil, 238, nil, 241, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 347, 243, nil, nil, nil, nil, 124, nil, - nil, nil, nil, 335, 335, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, nil, 258, 259, 260, nil, - nil, 264, 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, nil, 243, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 243 ] + nil, nil, nil, nil, nil, 258, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 258 ] racc_goto_check = [ - 34, 28, 78, 49, 34, 34, 81, 49, 29, 66, - 33, 57, 27, 20, 4, 33, 2, 20, 64, 29, - 47, 26, 32, 44, 25, 35, 68, 74, 18, 50, - 3, 28, 62, 19, 60, 59, 38, 20, 70, 28, - 38, 61, 27, 54, 43, 43, 58, 70, 64, 55, - 27, 26, 53, 65, 25, 5, 67, 30, 69, 26, - 31, 71, 25, 72, 73, 3, 18, 54, 39, 75, - 76, 77, 46, 33, 3, 20, 37, 32, 3, 79, - 54, 80, 1, nil, nil, 27, nil, nil, 59, nil, - nil, nil, nil, nil, nil, 66, nil, nil, nil, nil, - nil, nil, 46, nil, 64, nil, 19, nil, nil, nil, - 46, nil, nil, nil, nil, nil, nil, 38, nil, 62, - nil, nil, nil, nil, nil, nil, nil, 28, nil, 74, - nil, 28, nil, nil, nil, 64, 60, 60, 27, nil, - nil, 27, 27, nil, nil, nil, nil, 26, 3, nil, - 25, 26, nil, 25, 25, nil, nil, 33, 18, nil, - nil, nil, nil, 20, nil, 35, nil, 20, nil, 50, - nil, 27, 34, 57, nil, 49, 81, nil, 78, 33, - 68, 47, 60, 25, 44, 20, 60, 32, 2, 33, - 64, 50, 28, nil, 50, nil, nil, nil, 46, nil, - 28, 46, 46, 27, nil, 66, 34, nil, nil, 49, - nil, 27, 26, 34, 64, 25, 49, 29, nil, 20, - 26, nil, 2, 25, nil, nil, 20, 27, nil, 2, - nil, 46, nil, nil, nil, nil, 20, nil, nil, 25, + 52, 30, 60, 21, 4, 69, 81, 32, 84, 53, + 2, 22, 63, 3, 54, 52, 32, 77, 21, 30, + 35, 31, 37, 67, 5, 21, 38, 41, 47, 54, + 65, 41, 23, 57, 50, 62, 20, 37, 35, 31, + 20, 73, 54, 64, 71, 30, 29, 58, 37, 3, + 73, 57, 46, 46, 7, 22, 36, 67, 3, 28, + 54, 3, 7, 61, 29, 31, 19, 68, 56, 21, + 70, 36, 57, 33, 19, 72, 34, 28, 74, 75, + 30, 54, 76, 40, 78, 79, 24, 80, 62, 42, + 29, 82, 83, 36, 1, 69, nil, nil, nil, nil, + nil, nil, nil, 28, 24, nil, nil, nil, nil, 5, + nil, nil, nil, 67, 21, nil, 23, 5, nil, 65, + 24, nil, 21, nil, 24, nil, 41, nil, nil, nil, + 24, nil, nil, 37, nil, 53, nil, nil, nil, nil, + nil, 37, nil, nil, nil, 63, 67, 63, 30, nil, + 77, 30, 38, nil, nil, 30, nil, nil, nil, nil, + 3, nil, 54, nil, nil, 22, nil, nil, 31, nil, + nil, nil, 21, nil, nil, 31, nil, 36, nil, 21, + nil, 84, nil, nil, nil, 30, nil, nil, 81, nil, + 49, 53, nil, 29, nil, 63, 53, 69, 60, 63, + 29, 30, 67, nil, 52, 35, 28, 21, 49, 28, + 47, 54, 54, 28, 2, 67, 50, 30, 30, 24, + 52, 31, nil, 21, 71, nil, 37, nil, nil, nil, + 2, 54, 30, 24, 49, 52, 24, 32, 21, 36, + 24, 30, 37, 28, nil, 2, 29, nil, nil, 26, + nil, nil, 31, 30, nil, nil, 21, 37, nil, 28, + nil, 54, 29, 29, nil, nil, 36, 26, nil, 27, + 24, nil, nil, nil, 30, 28, 28, 29, nil, nil, + nil, 4, nil, nil, nil, 54, 24, 27, nil, 54, + 28, nil, 52, 26, 4, 21, nil, nil, nil, 28, + nil, nil, 24, 24, 24, 52, nil, nil, 21, 4, + nil, nil, nil, 27, 37, nil, nil, 24, nil, 52, + 52, 54, 21, 21, nil, nil, 24, 37, nil, 2, + 30, nil, 28, nil, nil, nil, nil, 49, nil, nil, + 49, 37, 37, 30, 49, nil, nil, 4, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 52, 24, + nil, 21, 4, nil, 4, nil, 25, 52, nil, 52, + 21, nil, 21, 52, 49, 52, 21, 2, 21, 2, + 37, nil, nil, nil, 25, nil, nil, nil, 28, 37, + 49, 37, nil, nil, nil, 37, 26, 37, nil, 26, + 25, 28, nil, 26, 25, nil, 49, 49, nil, nil, + 25, nil, nil, nil, nil, 24, 27, nil, nil, 27, + nil, 49, nil, 27, nil, nil, nil, nil, 24, nil, + 49, nil, nil, 26, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, 27, 51, nil, nil, nil, nil, nil, + nil, nil, nil, 49, nil, 26, 26, nil, nil, 27, + nil, 51, 51, nil, nil, nil, nil, nil, nil, nil, + 26, nil, nil, nil, nil, 27, 27, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 25, + 27, nil, nil, nil, nil, nil, nil, nil, nil, 27, + nil, nil, nil, 25, nil, nil, 25, 51, nil, 49, + 25, 51, 26, 51, nil, nil, nil, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 27, nil, nil, nil, nil, 51, nil, nil, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, 25, 25, 25, nil, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, 25, 27, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, 27, nil, nil, nil, nil, nil, nil, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, nil, 51, + 51, 51, nil, nil, 51, nil, nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 21, nil, 22, 27, nil, nil, 27, nil, - nil, nil, 34, 46, nil, 49, nil, nil, 27, 27, - 25, 46, 4, 24, nil, 20, nil, 26, 26, nil, - 25, 25, 21, nil, 22, nil, nil, 46, nil, nil, - 21, 34, 22, 34, 49, nil, 49, 34, nil, nil, - 49, 4, nil, 24, 20, nil, 20, 4, 51, 2, - 20, 24, nil, 27, nil, nil, nil, nil, 46, nil, - nil, nil, nil, 51, nil, 25, nil, nil, 46, 46, - nil, nil, nil, nil, 21, nil, 22, 27, 21, nil, - 22, nil, nil, 34, nil, nil, 49, 23, nil, 25, - nil, 51, 34, 4, 34, 49, 20, 49, nil, 34, - nil, 34, 49, nil, 49, 20, nil, 20, 2, 4, - 2, 4, 20, 46, 20, 51, nil, 23, 21, nil, - 22, 21, 21, 22, 22, 23, nil, nil, 51, nil, - nil, nil, nil, nil, nil, nil, nil, 46, nil, 24, - nil, nil, 24, 24, nil, nil, nil, nil, nil, nil, - nil, 21, nil, 22, nil, 21, nil, 22, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 51, nil, nil, - nil, nil, 24, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 21, nil, 22, nil, nil, nil, nil, - nil, 21, nil, 22, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 24, nil, nil, 21, nil, 22, - nil, nil, 24, 23, 48, nil, 23, 23, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 24, 48, - 48, nil, nil, 48, nil, nil, 51, nil, 21, nil, - 22, nil, 51, nil, nil, 21, 23, 22, 21, 21, - 22, 22, nil, nil, 51, nil, nil, nil, nil, 24, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, - 24, 48, nil, nil, nil, nil, 48, nil, 23, nil, - nil, 48, nil, nil, nil, nil, 23, nil, nil, 51, - nil, nil, nil, 21, nil, 22, nil, nil, nil, nil, - nil, nil, 23, nil, nil, nil, 51, 51, nil, nil, - nil, nil, nil, nil, 24, nil, nil, 21, nil, 22, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 51, 23, nil, nil, nil, nil, 24, nil, - nil, nil, nil, 23, 23, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, nil, 48, 48, 48, nil, - nil, 48, 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, nil, 23, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 23 ] + nil, nil, nil, nil, nil, 25, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25 ] racc_goto_pointer = [ - nil, 82, 16, 30, 10, 50, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 4, -117, - 13, 228, 230, 323, 249, 0, -3, -12, -23, 7, - 3, -72, -32, -125, 0, -30, nil, 45, -70, -209, - nil, nil, nil, -236, -31, nil, 48, -34, 448, 3, - -26, 280, nil, -168, -28, -265, nil, -54, -103, -228, - 15, -142, -151, nil, -135, -100, -144, -183, -4, 28, - 3, -57, 44, 16, 8, -53, -43, -42, -111, -131, - -16, -91, nil ] + nil, 94, 10, 13, -11, -2, nil, -57, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -45, + 6, 3, -11, -137, 64, 344, 227, 247, 37, 24, + -21, -1, 6, 33, -49, -20, -72, 22, -15, nil, + 64, -29, -151, nil, nil, nil, -186, -12, nil, 168, + -6, 429, 0, -32, -15, nil, -160, -24, -291, nil, + -66, -111, -258, -4, -163, -176, nil, -149, -105, -167, + -192, 12, 43, 5, -69, 63, 34, 1, -67, -35, + -33, -114, -140, -9, -93, nil ] racc_goto_default = [ - nil, nil, nil, 185, 10, 15, 18, 21, 22, 25, - 27, 29, 32, 3, 6, 9, 14, 17, nil, 73, - 96, 98, 99, 101, 85, 86, 90, 91, 92, 20, - nil, nil, nil, nil, 81, nil, 5, nil, nil, 189, - 277, 190, 192, nil, nil, 139, 84, 87, 149, 63, - 129, 94, 142, 143, nil, 234, 100, nil, nil, nil, - 64, nil, nil, 272, 74, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 51, nil, nil, nil, nil, - nil, nil, 180 ] - -racc_reduce_table = [ - 0, 0, :racc_error, - 1, 65, :_reduce_1, - 1, 65, :_reduce_none, - 1, 66, :_reduce_none, - 2, 66, :_reduce_4, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 4, 76, :_reduce_18, - 5, 76, :_reduce_19, - 3, 76, :_reduce_20, - 2, 76, :_reduce_21, - 1, 82, :_reduce_none, - 1, 82, :_reduce_none, - 3, 82, :_reduce_24, - 3, 82, :_reduce_25, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 1, 83, :_reduce_34, - 5, 69, :_reduce_35, - 5, 69, :_reduce_36, - 5, 69, :_reduce_37, - 5, 80, :_reduce_38, - 2, 70, :_reduce_39, - 1, 100, :_reduce_40, - 2, 100, :_reduce_41, - 6, 71, :_reduce_42, - 2, 71, :_reduce_43, - 3, 101, :_reduce_44, - 3, 101, :_reduce_45, - 1, 102, :_reduce_none, - 1, 102, :_reduce_none, - 3, 102, :_reduce_48, - 1, 103, :_reduce_none, - 3, 103, :_reduce_50, - 1, 104, :_reduce_51, - 1, 104, :_reduce_52, - 3, 105, :_reduce_53, - 3, 105, :_reduce_54, - 1, 106, :_reduce_none, - 1, 106, :_reduce_none, - 4, 108, :_reduce_57, - 1, 94, :_reduce_none, - 3, 94, :_reduce_59, - 0, 95, :_reduce_none, - 1, 95, :_reduce_none, - 1, 110, :_reduce_62, - 1, 85, :_reduce_63, - 1, 87, :_reduce_64, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 1, 109, :_reduce_none, - 3, 72, :_reduce_72, - 3, 72, :_reduce_73, - 3, 81, :_reduce_74, - 0, 96, :_reduce_75, - 1, 96, :_reduce_76, - 3, 96, :_reduce_77, - 3, 114, :_reduce_78, - 3, 116, :_reduce_79, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 0, 99, :_reduce_82, - 1, 99, :_reduce_83, - 3, 99, :_reduce_84, - 1, 118, :_reduce_none, - 3, 118, :_reduce_86, - 1, 107, :_reduce_none, - 1, 107, :_reduce_none, - 1, 107, :_reduce_none, - 1, 107, :_reduce_none, - 1, 107, :_reduce_none, - 1, 107, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 4, 89, :_reduce_105, - 3, 89, :_reduce_106, - 1, 91, :_reduce_107, - 2, 91, :_reduce_108, - 2, 121, :_reduce_109, - 1, 122, :_reduce_110, - 2, 122, :_reduce_111, - 1, 88, :_reduce_112, - 4, 84, :_reduce_113, - 4, 84, :_reduce_114, - 6, 74, :_reduce_115, - 5, 74, :_reduce_116, - 0, 123, :_reduce_none, - 4, 123, :_reduce_118, - 3, 123, :_reduce_119, - 1, 112, :_reduce_none, - 3, 112, :_reduce_121, - 3, 112, :_reduce_122, - 3, 112, :_reduce_123, - 3, 112, :_reduce_124, - 3, 112, :_reduce_125, - 3, 112, :_reduce_126, - 3, 112, :_reduce_127, - 3, 112, :_reduce_128, - 2, 112, :_reduce_129, - 3, 112, :_reduce_130, - 3, 112, :_reduce_131, - 3, 112, :_reduce_132, - 3, 112, :_reduce_133, - 3, 112, :_reduce_134, - 3, 112, :_reduce_135, - 2, 112, :_reduce_136, - 3, 112, :_reduce_137, - 3, 112, :_reduce_138, - 3, 112, :_reduce_139, - 5, 73, :_reduce_140, - 1, 125, :_reduce_none, - 2, 125, :_reduce_142, - 5, 126, :_reduce_143, - 4, 126, :_reduce_144, - 1, 127, :_reduce_none, - 3, 127, :_reduce_146, - 3, 90, :_reduce_147, - 1, 129, :_reduce_none, - 4, 129, :_reduce_149, - 1, 131, :_reduce_none, - 3, 131, :_reduce_151, - 3, 130, :_reduce_152, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_none, - 1, 128, :_reduce_160, - 1, 128, :_reduce_none, - 1, 132, :_reduce_162, - 1, 133, :_reduce_none, - 3, 133, :_reduce_164, - 2, 75, :_reduce_165, - 6, 77, :_reduce_166, - 5, 77, :_reduce_167, - 7, 78, :_reduce_168, - 6, 78, :_reduce_169, - 6, 79, :_reduce_170, - 5, 79, :_reduce_171, - 1, 98, :_reduce_172, - 1, 93, :_reduce_173, - 1, 93, :_reduce_174, - 1, 93, :_reduce_175, - 1, 136, :_reduce_none, - 3, 136, :_reduce_177, - 1, 138, :_reduce_178, - 1, 139, :_reduce_179, - 1, 139, :_reduce_180, - 1, 139, :_reduce_181, - 1, 139, :_reduce_none, - 0, 67, :_reduce_183, - 0, 140, :_reduce_184, - 1, 134, :_reduce_none, - 3, 134, :_reduce_186, - 3, 134, :_reduce_187, - 1, 141, :_reduce_none, - 3, 141, :_reduce_189, - 3, 142, :_reduce_190, - 1, 142, :_reduce_191, - 3, 142, :_reduce_192, - 1, 142, :_reduce_193, - 1, 137, :_reduce_none, - 2, 137, :_reduce_195, - 1, 135, :_reduce_none, - 2, 135, :_reduce_197, - 1, 143, :_reduce_none, - 1, 143, :_reduce_none, - 1, 86, :_reduce_200, - 3, 111, :_reduce_201, - 4, 111, :_reduce_202, - 2, 111, :_reduce_203, - 1, 119, :_reduce_none, - 1, 119, :_reduce_none, - 0, 97, :_reduce_none, - 1, 97, :_reduce_207, - 1, 124, :_reduce_208, - 3, 120, :_reduce_209, - 4, 120, :_reduce_210, - 2, 120, :_reduce_211, - 1, 144, :_reduce_none, - 3, 144, :_reduce_213, - 3, 145, :_reduce_214, - 1, 146, :_reduce_215, - 1, 146, :_reduce_216, - 4, 113, :_reduce_217, - 1, 92, :_reduce_none, - 4, 92, :_reduce_219 ] - -racc_reduce_n = 220 - -racc_shift_n = 365 + nil, nil, nil, 160, 21, 24, 28, 31, 35, 3, + 6, 8, 11, 14, 17, 20, 23, 27, 30, 34, + nil, 91, nil, 70, 93, 95, 98, 100, 102, 105, + 106, 89, 4, nil, nil, nil, nil, 74, nil, 26, + nil, nil, 153, 240, 156, 157, nil, nil, 132, 99, + 103, 174, 84, 123, 90, 140, 141, nil, 246, 97, + nil, nil, nil, 85, nil, nil, 297, 67, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 51, nil, + nil, nil, nil, nil, nil, 188 ] 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, - :LESSEQUAL => 17, - :NOTEQUAL => 18, - :DOT => 19, - :COLON => 20, - :LLCOLLECT => 21, - :RRCOLLECT => 22, - :QMARK => 23, - :LPAREN => 24, - :RPAREN => 25, - :ISEQUAL => 26, - :GREATEREQUAL => 27, - :GREATERTHAN => 28, - :LESSTHAN => 29, - :IF => 30, - :ELSE => 31, - :IMPORT => 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, - :LCOLLECT => 45, - :RCOLLECT => 46, - :CLASSNAME => 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 } - -racc_nt_base = 64 + false => 0, + Object.new => 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, + :LESSEQUAL => 17, + :NOTEQUAL => 18, + :DOT => 19, + :COLON => 20, + :LLCOLLECT => 21, + :RRCOLLECT => 22, + :QMARK => 23, + :LPAREN => 24, + :RPAREN => 25, + :ISEQUAL => 26, + :GREATEREQUAL => 27, + :GREATERTHAN => 28, + :LESSTHAN => 29, + :IF => 30, + :ELSE => 31, + :IMPORT => 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, + :LCOLLECT => 45, + :RCOLLECT => 46, + :CLASSNAME => 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 } racc_use_result_var = true +racc_nt_base = 68 + 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_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", - "LESSEQUAL", - "NOTEQUAL", - "DOT", - "COLON", - "LLCOLLECT", - "RRCOLLECT", - "QMARK", - "LPAREN", - "RPAREN", - "ISEQUAL", - "GREATEREQUAL", - "GREATERTHAN", - "LESSTHAN", - "IF", - "ELSE", - "IMPORT", - "DEFINE", - "ELSIF", - "VARIABLE", - "CLASS", - "INHERITS", - "NODE", - "BOOLEAN", - "NAME", - "SEMIC", - "CASE", - "DEFAULT", - "AT", - "LCOLLECT", - "RCOLLECT", - "CLASSNAME", - "CLASSREF", - "NOT", - "OR", - "AND", - "UNDEF", - "PARROW", - "PLUS", - "MINUS", - "TIMES", - "DIV", - "LSHIFT", - "RSHIFT", - "UMINUS", - "MATCH", - "NOMATCH", - "REGEX", - "$start", - "program", - "statements", - "nil", - "statement", - "resource", - "virtualresource", - "collection", - "assignment", - "casestatement", - "ifstatement", - "import", - "fstatement", - "definition", - "hostclass", - "nodedef", - "resourceoverride", - "append", - "funcvalues", - "namestring", - "resourceref", - "name", - "variable", - "type", - "boolean", - "funcrvalue", - "selector", - "quotedtext", - "hasharrayaccesses", - "classname", - "resourceinstances", - "endsemi", - "params", - "endcomma", - "classref", - "anyparams", - "at", - "collectrhand", - "collstatements", - "collstatement", - "colljoin", - "collexpr", - "colllval", - "simplervalue", - "resourceinst", - "resourcename", - "undef", - "array", - "expression", - "hasharrayaccess", - "param", - "rvalue", - "addparam", - "anyparam", - "rvalues", - "comma", - "hash", - "dqrval", - "dqtail", - "else", - "regex", - "caseopts", - "caseopt", - "casevalues", - "selectlhand", - "svalues", - "selectval", - "sintvalues", - "string", - "strings", - "argumentlist", - "classparent", - "hostnames", - "nodeparent", - "nodename", - "hostname", - "nothing", - "arguments", - "argument", - "classnameordefault", - "hashpairs", - "hashpair", - "key" ] +'$end', +'error', +'STRING', +'DQPRE', +'DQMID', +'DQPOST', +'LBRACK', +'RBRACK', +'LBRACE', +'RBRACE', +'SYMBOL', +'FARROW', +'COMMA', +'TRUE', +'FALSE', +'EQUALS', +'APPENDS', +'LESSEQUAL', +'NOTEQUAL', +'DOT', +'COLON', +'LLCOLLECT', +'RRCOLLECT', +'QMARK', +'LPAREN', +'RPAREN', +'ISEQUAL', +'GREATEREQUAL', +'GREATERTHAN', +'LESSTHAN', +'IF', +'ELSE', +'IMPORT', +'DEFINE', +'ELSIF', +'VARIABLE', +'CLASS', +'INHERITS', +'NODE', +'BOOLEAN', +'NAME', +'SEMIC', +'CASE', +'DEFAULT', +'AT', +'LCOLLECT', +'RCOLLECT', +'CLASSNAME', +'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', +'$start', +'program', +'statements', +'nil', +'statement', +'resource', +'virtualresource', +'collection', +'assignment', +'casestatement', +'ifstatement', +'import', +'fstatement', +'definition', +'hostclass', +'nodedef', +'resourceoverride', +'append', +'relationship', +'relationship_side', +'edge', +'resourceref', +'funcvalues', +'namestring', +'name', +'variable', +'type', +'boolean', +'funcrvalue', +'selector', +'quotedtext', +'hasharrayaccesses', +'classname', +'resourceinstances', +'endsemi', +'params', +'endcomma', +'classref', +'anyparams', +'at', +'collectrhand', +'collstatements', +'collstatement', +'colljoin', +'collexpr', +'colllval', +'simplervalue', +'resourceinst', +'resourcename', +'undef', +'array', +'expression', +'hasharrayaccess', +'param', +'rvalue', +'addparam', +'anyparam', +'rvalues', +'comma', +'hash', +'dqrval', +'dqtail', +'else', +'regex', +'caseopts', +'caseopt', +'casevalues', +'selectlhand', +'svalues', +'selectval', +'sintvalues', +'string', +'strings', +'argumentlist', +'classparent', +'hostnames', +'nodeparent', +'nodename', +'hostname', +'nothing', +'arguments', +'argument', +'classnameordefault', +'hashpairs', +'hashpair', +'key'] Racc_debug_parser = false -##### State transition tables end ##### +##### racc system variables end ##### -# reduce 0 omitted + # reduce 0 omitted -module_eval(<<'.,.,', 'grammar.ra', 30) - def _reduce_1(val, _values, result) - if val[0] +module_eval <<'.,.,', 'grammar.ra', 45 + def _reduce_1( val, _values, result ) + if val[0] # Make sure we always return an array. if val[0].is_a?(AST::ASTArray) if val[0].children.empty? result = nil else result = val[0] end else result = aryfy(val[0]) end else result = nil end - - result + result end .,., -# reduce 2 omitted + # reduce 2 omitted -# reduce 3 omitted + # reduce 3 omitted -module_eval(<<'.,.,', 'grammar.ra', 49) - def _reduce_4(val, _values, result) - if val[0] and val[1] +module_eval <<'.,.,', 'grammar.ra', 61 + def _reduce_4( val, _values, result ) + if val[0] and val[1] if val[0].instance_of?(AST::ASTArray) val[0].push(val[1]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[1]] end elsif obj = (val[0] || val[1]) result = obj else result = nil end - - result + result end .,., -# reduce 5 omitted + # reduce 5 omitted + + # reduce 6 omitted + + # reduce 7 omitted + + # reduce 8 omitted + + # reduce 9 omitted + + # reduce 10 omitted + + # reduce 11 omitted + + # reduce 12 omitted + + # reduce 13 omitted -# reduce 6 omitted + # reduce 14 omitted -# reduce 7 omitted + # reduce 15 omitted -# reduce 8 omitted + # reduce 16 omitted -# reduce 9 omitted + # reduce 17 omitted -# reduce 10 omitted + # reduce 18 omitted -# reduce 11 omitted +module_eval <<'.,.,', 'grammar.ra', 81 + def _reduce_19( val, _values, result ) + result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) + result + end +.,., + +module_eval <<'.,.,', 'grammar.ra', 84 + def _reduce_20( val, _values, result ) + result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) + result + end +.,., + + # reduce 21 omitted -# reduce 12 omitted + # reduce 22 omitted -# reduce 13 omitted + # reduce 23 omitted -# reduce 14 omitted + # reduce 24 omitted -# reduce 15 omitted + # reduce 25 omitted -# reduce 16 omitted + # reduce 26 omitted -# reduce 17 omitted + # reduce 27 omitted -module_eval(<<'.,.,', 'grammar.ra', 78) - def _reduce_18(val, _values, result) - args = aryfy(val[2]) +module_eval <<'.,.,', 'grammar.ra', 97 + def _reduce_28( val, _values, result ) + args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 86) - def _reduce_19(val, _values, result) - args = aryfy(val[2]) +module_eval <<'.,.,', 'grammar.ra', 105 + def _reduce_29( val, _values, result ) + args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 93) - def _reduce_20(val, _values, result) - result = ast AST::Function, +module_eval <<'.,.,', 'grammar.ra', 111 + def _reduce_30( val, _values, result ) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => AST::ASTArray.new({}), :ftype => :statement - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 100) - def _reduce_21(val, _values, result) - args = aryfy(val[1]) +module_eval <<'.,.,', 'grammar.ra', 119 + def _reduce_31( val, _values, result ) + args = aryfy(val[1]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :statement - - result + result end .,., -# reduce 22 omitted + # reduce 32 omitted -# reduce 23 omitted + # reduce 33 omitted -module_eval(<<'.,.,', 'grammar.ra', 111) - def _reduce_24(val, _values, result) - result = aryfy(val[0], val[2]) +module_eval <<'.,.,', 'grammar.ra', 127 + def _reduce_34( val, _values, result ) + result = aryfy(val[0], val[2]) result.line = @lexer.line result.file = @lexer.file - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 116) - def _reduce_25(val, _values, result) - unless val[0].is_a?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 136 + def _reduce_35( val, _values, result ) + unless val[0].is_a?(AST::ASTArray) val[0] = aryfy(val[0]) end val[0].push(val[2]) result = val[0] - - result + result end .,., -# reduce 26 omitted + # reduce 36 omitted -# reduce 27 omitted + # reduce 37 omitted -# reduce 28 omitted + # reduce 38 omitted -# reduce 29 omitted + # reduce 39 omitted -# reduce 30 omitted + # reduce 40 omitted -# reduce 31 omitted + # reduce 41 omitted -# reduce 32 omitted + # reduce 42 omitted -# reduce 33 omitted + # reduce 43 omitted -module_eval(<<'.,.,', 'grammar.ra', 136) - def _reduce_34(val, _values, result) - result = ast AST::Name, :value => val[0][:value] - - result +module_eval <<'.,.,', 'grammar.ra', 150 + def _reduce_44( val, _values, result ) + result = ast AST::Name, :value => val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 140) - def _reduce_35(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 172 + def _reduce_45( val, _values, result ) + @lexer.commentpop array = val[2] if array.instance_of?(AST::ResourceInstance) array = [array] end result = ast AST::ASTArray # this iterates across each specified resourceinstance array.each { |instance| unless instance.instance_of?(AST::ResourceInstance) raise Puppet::Dev, "Got something that isn't an instance" end # now, i need to somehow differentiate between those things with # arrays in their names, and normal things result.push ast(AST::Resource, :type => val[0], :title => instance[0], :parameters => instance[1]) } - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 160) - def _reduce_36(val, _values, result) - # This is a deprecated syntax. +module_eval <<'.,.,', 'grammar.ra', 175 + def _reduce_46( val, _values, result ) + # This is a deprecated syntax. error "All resource specifications require names" - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 163) - def _reduce_37(val, _values, result) - # a defaults setting for a type +module_eval <<'.,.,', 'grammar.ra', 178 + def _reduce_47( val, _values, result ) + # a defaults setting for a type result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2]) - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 169) - def _reduce_38(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 184 + def _reduce_48( val, _values, result ) + @lexer.commentpop result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 176) - def _reduce_39(val, _values, result) - type = val[0] +module_eval <<'.,.,', 'grammar.ra', 211 + def _reduce_49( val, _values, result ) + type = val[0] if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect without storeconfigs being set") end if val[1].is_a? AST::ResourceDefaults error "Defaults are not virtualizable" end method = type.to_s + "=" # Just mark our resources as exported and pass them through. if val[1].instance_of?(AST::ASTArray) val[1].each do |obj| obj.send(method, true) end else val[1].send(method, true) end result = val[1] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 200) - def _reduce_40(val, _values, result) - result = :virtual - result +module_eval <<'.,.,', 'grammar.ra', 212 + def _reduce_50( val, _values, result ) + result = :virtual + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 201) - def _reduce_41(val, _values, result) - result = :exported - result +module_eval <<'.,.,', 'grammar.ra', 213 + def _reduce_51( val, _values, result ) + result = :exported + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 206) - def _reduce_42(val, _values, result) - if val[0] =~ /^[a-z]/ +module_eval <<'.,.,', 'grammar.ra', 237 + def _reduce_52( val, _values, result ) + if val[0] =~ /^[a-z]/ Puppet.warning addcontext("Collection names must now be capitalized") end type = val[0].downcase args = {:type => type} if val[1].is_a?(AST::CollExpr) args[:query] = val[1] args[:query].type = type args[:form] = args[:query].form else args[:form] = val[1] end if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored") end args[:override] = val[3] result = ast AST::Collection, args - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 226) - def _reduce_43(val, _values, result) - if val[0] =~ /^[a-z]/ +module_eval <<'.,.,', 'grammar.ra', 256 + def _reduce_53( val, _values, result ) + if val[0] =~ /^[a-z]/ Puppet.warning addcontext("Collection names must now be capitalized") end type = val[0].downcase args = {:type => type } if val[1].is_a?(AST::CollExpr) args[:query] = val[1] args[:query].type = type args[:form] = args[:query].form else args[:form] = val[1] end if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly] Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored") end result = ast AST::Collection, args - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 247) - def _reduce_44(val, _values, result) - if val[1] +module_eval <<'.,.,', 'grammar.ra', 266 + def _reduce_54( val, _values, result ) + if val[1] result = val[1] result.form = :virtual else result = :virtual end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 255) - def _reduce_45(val, _values, result) - if val[1] +module_eval <<'.,.,', 'grammar.ra', 274 + def _reduce_55( val, _values, result ) + if val[1] result = val[1] result.form = :exported else result = :exported end - - result + result end .,., -# reduce 46 omitted - -# reduce 47 omitted + # reduce 56 omitted -module_eval(<<'.,.,', 'grammar.ra', 268) - def _reduce_48(val, _values, result) - result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2] + # reduce 57 omitted - result +module_eval <<'.,.,', 'grammar.ra', 282 + def _reduce_58( val, _values, result ) + result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2] + result end .,., -# reduce 49 omitted + # reduce 59 omitted -module_eval(<<'.,.,', 'grammar.ra', 273) - def _reduce_50(val, _values, result) - result = val[1] +module_eval <<'.,.,', 'grammar.ra', 288 + def _reduce_60( val, _values, result ) + result = val[1] result.parens = true - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 277) - def _reduce_51(val, _values, result) - result=val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 289 + def _reduce_61( val, _values, result ) + result=val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 278) - def _reduce_52(val, _values, result) - result=val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 290 + def _reduce_62( val, _values, result ) + result=val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 281) - def _reduce_53(val, _values, result) - result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] +module_eval <<'.,.,', 'grammar.ra', 297 + def _reduce_63( val, _values, result ) + result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 286) - def _reduce_54(val, _values, result) - result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] +module_eval <<'.,.,', 'grammar.ra', 302 + def _reduce_64( val, _values, result ) + result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val - - result + result end .,., -# reduce 55 omitted - -# reduce 56 omitted + # reduce 65 omitted -module_eval(<<'.,.,', 'grammar.ra', 295) - def _reduce_57(val, _values, result) - result = ast AST::ResourceInstance, :children => [val[0],val[2]] + # reduce 66 omitted - result +module_eval <<'.,.,', 'grammar.ra', 309 + def _reduce_67( val, _values, result ) + result = ast AST::ResourceInstance, :children => [val[0],val[2]] + result end .,., -# reduce 58 omitted + # reduce 68 omitted -module_eval(<<'.,.,', 'grammar.ra', 300) - def _reduce_59(val, _values, result) - if val[0].instance_of?(AST::ResourceInstance) +module_eval <<'.,.,', 'grammar.ra', 319 + def _reduce_69( val, _values, result ) + if val[0].instance_of?(AST::ResourceInstance) result = ast AST::ASTArray, :children => [val[0],val[2]] else val[0].push val[2] result = val[0] end - - result + result end .,., -# reduce 60 omitted + # reduce 70 omitted -# reduce 61 omitted + # reduce 71 omitted -module_eval(<<'.,.,', 'grammar.ra', 312) - def _reduce_62(val, _values, result) - result = ast AST::Undef, :value => :undef - - result +module_eval <<'.,.,', 'grammar.ra', 326 + def _reduce_72( val, _values, result ) + result = ast AST::Undef, :value => :undef + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 316) - def _reduce_63(val, _values, result) - result = ast AST::Name, :value => val[0][:value], :line => val[0][:line] - - result +module_eval <<'.,.,', 'grammar.ra', 330 + def _reduce_73( val, _values, result ) + result = ast AST::Name, :value => val[0][:value], :line => val[0][:line] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 320) - def _reduce_64(val, _values, result) - result = ast AST::Type, :value => val[0][:value], :line => val[0][:line] - - result +module_eval <<'.,.,', 'grammar.ra', 334 + def _reduce_74( val, _values, result ) + result = ast AST::Type, :value => val[0][:value], :line => val[0][:line] + result end .,., -# reduce 65 omitted + # reduce 75 omitted -# reduce 66 omitted + # reduce 76 omitted -# reduce 67 omitted + # reduce 77 omitted -# reduce 68 omitted + # reduce 78 omitted -# reduce 69 omitted + # reduce 79 omitted -# reduce 70 omitted + # reduce 80 omitted -# reduce 71 omitted + # reduce 81 omitted -module_eval(<<'.,.,', 'grammar.ra', 332) - def _reduce_72(val, _values, result) - if val[0][:value] =~ /::/ +module_eval <<'.,.,', 'grammar.ra', 351 + def _reduce_82( val, _values, result ) + if val[0][:value] =~ /::/ raise Puppet::ParseError, "Cannot assign to variables in other namespaces" end # this is distinct from referencing a variable variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 340) - def _reduce_73(val, _values, result) - result = ast AST::VarDef, :name => val[0], :value => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 354 + def _reduce_83( val, _values, result ) + result = ast AST::VarDef, :name => val[0], :value => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 344) - def _reduce_74(val, _values, result) - variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] +module_eval <<'.,.,', 'grammar.ra', 359 + def _reduce_84( val, _values, result ) + variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 350) - def _reduce_75(val, _values, result) - result = ast AST::ASTArray - - result +module_eval <<'.,.,', 'grammar.ra', 364 + def _reduce_85( val, _values, result ) + result = ast AST::ASTArray + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 352) - def _reduce_76(val, _values, result) - result = val[0] - result +module_eval <<'.,.,', 'grammar.ra', 364 + def _reduce_86( val, _values, result ) + result = val[0] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 354) - def _reduce_77(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 373 + def _reduce_87( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 363) - def _reduce_78(val, _values, result) - result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 377 + def _reduce_88( val, _values, result ) + result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 367) - def _reduce_79(val, _values, result) - result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2], +module_eval <<'.,.,', 'grammar.ra', 382 + def _reduce_89( val, _values, result ) + result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2], :add => true - - result + result end .,., -# reduce 80 omitted - -# reduce 81 omitted + # reduce 90 omitted -module_eval(<<'.,.,', 'grammar.ra', 376) - def _reduce_82(val, _values, result) - result = ast AST::ASTArray + # reduce 91 omitted - result +module_eval <<'.,.,', 'grammar.ra', 390 + def _reduce_92( val, _values, result ) + result = ast AST::ASTArray + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 378) - def _reduce_83(val, _values, result) - result = val[0] - result +module_eval <<'.,.,', 'grammar.ra', 390 + def _reduce_93( val, _values, result ) + result = val[0] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 380) - def _reduce_84(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 399 + def _reduce_94( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end - - result + result end .,., -# reduce 85 omitted + # reduce 95 omitted -module_eval(<<'.,.,', 'grammar.ra', 390) - def _reduce_86(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 408 + def _reduce_96( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) result = val[0].push(val[2]) else result = ast AST::ASTArray, :children => [val[0],val[2]] end - - result + result end .,., -# reduce 87 omitted + # reduce 97 omitted -# reduce 88 omitted + # reduce 98 omitted -# reduce 89 omitted + # reduce 99 omitted -# reduce 90 omitted + # reduce 100 omitted -# reduce 91 omitted + # reduce 101 omitted -# reduce 92 omitted + # reduce 102 omitted -# reduce 93 omitted + # reduce 103 omitted -# reduce 94 omitted + # reduce 104 omitted -# reduce 95 omitted + # reduce 105 omitted -# reduce 96 omitted + # reduce 106 omitted -# reduce 97 omitted + # reduce 107 omitted -# reduce 98 omitted + # reduce 108 omitted -# reduce 99 omitted + # reduce 109 omitted -# reduce 100 omitted + # reduce 110 omitted -# reduce 101 omitted + # reduce 111 omitted -# reduce 102 omitted + # reduce 112 omitted -# reduce 103 omitted + # reduce 113 omitted -# reduce 104 omitted + # reduce 114 omitted -module_eval(<<'.,.,', 'grammar.ra', 419) - def _reduce_105(val, _values, result) - args = aryfy(val[2]) +module_eval <<'.,.,', 'grammar.ra', 437 + def _reduce_115( val, _values, result ) + args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => args, :ftype => :rvalue - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 425) - def _reduce_106(val, _values, result) - result = ast AST::Function, +module_eval <<'.,.,', 'grammar.ra', 442 + def _reduce_116( val, _values, result ) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => AST::ASTArray.new({}), :ftype => :rvalue - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 431) - def _reduce_107(val, _values, result) - result = ast AST::String, :value => val[0][:value], :line => val[0][:line] - result +module_eval <<'.,.,', 'grammar.ra', 443 + def _reduce_117( val, _values, result ) + result = ast AST::String, :value => val[0][:value], :line => val[0][:line] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 432) - def _reduce_108(val, _values, result) - result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] - result +module_eval <<'.,.,', 'grammar.ra', 444 + def _reduce_118( val, _values, result ) + result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 434) - def _reduce_109(val, _values, result) - result = [val[0]] + val[1] - result +module_eval <<'.,.,', 'grammar.ra', 446 + def _reduce_119( val, _values, result ) + result = [val[0]] + val[1] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 436) - def _reduce_110(val, _values, result) - result = [ast(AST::String,val[0])] - result +module_eval <<'.,.,', 'grammar.ra', 448 + def _reduce_120( val, _values, result ) + result = [ast(AST::String,val[0])] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 437) - def _reduce_111(val, _values, result) - result = [ast(AST::String,val[0])] + val[1] - result +module_eval <<'.,.,', 'grammar.ra', 449 + def _reduce_121( val, _values, result ) + result = [ast(AST::String,val[0])] + val[1] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 440) - def _reduce_112(val, _values, result) - result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line] - - result +module_eval <<'.,.,', 'grammar.ra', 454 + def _reduce_122( val, _values, result ) + result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 444) - def _reduce_113(val, _values, result) - Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized") +module_eval <<'.,.,', 'grammar.ra', 459 + def _reduce_123( val, _values, result ) + Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized") result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 447) - def _reduce_114(val, _values, result) - result = ast AST::ResourceReference, :type => val[0], :title => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 461 + def _reduce_124( val, _values, result ) + result = ast AST::ResourceReference, :type => val[0], :title => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 451) - def _reduce_115(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 475 + def _reduce_125( val, _values, result ) + @lexer.commentpop args = { :test => val[1], :statements => val[3] } if val[5] args[:else] = val[5] end result = ast AST::IfStatement, args - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 464) - def _reduce_116(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 488 + def _reduce_126( val, _values, result ) + @lexer.commentpop args = { :test => val[1], :statements => ast(AST::Nop) } if val[4] args[:else] = val[4] end result = ast AST::IfStatement, args - - result + result end .,., -# reduce 117 omitted + # reduce 127 omitted -module_eval(<<'.,.,', 'grammar.ra', 479) - def _reduce_118(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 494 + def _reduce_128( val, _values, result ) + @lexer.commentpop result = ast AST::Else, :statements => val[2] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 483) - def _reduce_119(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 498 + def _reduce_129( val, _values, result ) + @lexer.commentpop result = ast AST::Else, :statements => ast(AST::Nop) - - result + result end .,., -# reduce 120 omitted - -module_eval(<<'.,.,', 'grammar.ra', 501) - def _reduce_121(val, _values, result) - result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + # reduce 130 omitted - result +module_eval <<'.,.,', 'grammar.ra', 515 + def _reduce_131( val, _values, result ) + result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 504) - def _reduce_122(val, _values, result) - result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 518 + def _reduce_132( val, _values, result ) + result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 507) - def _reduce_123(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 521 + def _reduce_133( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 510) - def _reduce_124(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 524 + def _reduce_134( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 513) - def _reduce_125(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 527 + def _reduce_135( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 516) - def _reduce_126(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 530 + def _reduce_136( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 519) - def _reduce_127(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 533 + def _reduce_137( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 522) - def _reduce_128(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 536 + def _reduce_138( val, _values, result ) + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 525) - def _reduce_129(val, _values, result) - result = ast AST::Minus, :value => val[1] - - result +module_eval <<'.,.,', 'grammar.ra', 539 + def _reduce_139( val, _values, result ) + result = ast AST::Minus, :value => val[1] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 528) - def _reduce_130(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 542 + def _reduce_140( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 531) - def _reduce_131(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 545 + def _reduce_141( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 534) - def _reduce_132(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 548 + def _reduce_142( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 537) - def _reduce_133(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 551 + def _reduce_143( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 540) - def _reduce_134(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 554 + def _reduce_144( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 543) - def _reduce_135(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 557 + def _reduce_145( val, _values, result ) + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 546) - def _reduce_136(val, _values, result) - result = ast AST::Not, :value => val[1] - - result +module_eval <<'.,.,', 'grammar.ra', 560 + def _reduce_146( val, _values, result ) + result = ast AST::Not, :value => val[1] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 549) - def _reduce_137(val, _values, result) - result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 563 + def _reduce_147( val, _values, result ) + result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 552) - def _reduce_138(val, _values, result) - result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 566 + def _reduce_148( val, _values, result ) + result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 555) - def _reduce_139(val, _values, result) - result = val[1] - - result +module_eval <<'.,.,', 'grammar.ra', 569 + def _reduce_149( val, _values, result ) + result = val[1] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 559) - def _reduce_140(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 578 + def _reduce_150( val, _values, result ) + @lexer.commentpop options = val[3] unless options.instance_of?(AST::ASTArray) options = ast AST::ASTArray, :children => [val[3]] end result = ast AST::CaseStatement, :test => val[1], :options => options - - result + result end .,., -# reduce 141 omitted + # reduce 151 omitted -module_eval(<<'.,.,', 'grammar.ra', 569) - def _reduce_142(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 588 + def _reduce_152( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) val[0].push val[1] result = val[0] else result = ast AST::ASTArray, :children => [val[0], val[1]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 578) - def _reduce_143(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 593 + def _reduce_153( val, _values, result ) + @lexer.commentpop result = ast AST::CaseOpt, :value => val[0], :statements => val[3] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 581) - def _reduce_144(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 599 + def _reduce_154( val, _values, result ) + @lexer.commentpop result = ast(AST::CaseOpt, :value => val[0], :statements => ast(AST::ASTArray) ) - - result + result end .,., -# reduce 145 omitted + # reduce 155 omitted -module_eval(<<'.,.,', 'grammar.ra', 590) - def _reduce_146(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 609 + def _reduce_156( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 599) - def _reduce_147(val, _values, result) - result = ast AST::Selector, :param => val[0], :values => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 613 + def _reduce_157( val, _values, result ) + result = ast AST::Selector, :param => val[0], :values => val[2] + result end .,., -# reduce 148 omitted + # reduce 158 omitted -module_eval(<<'.,.,', 'grammar.ra', 604) - def _reduce_149(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 619 + def _reduce_159( val, _values, result ) + @lexer.commentpop result = val[1] - - result + result end .,., -# reduce 150 omitted + # reduce 160 omitted -module_eval(<<'.,.,', 'grammar.ra', 610) - def _reduce_151(val, _values, result) - if val[0].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 629 + def _reduce_161( val, _values, result ) + if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] else result = ast AST::ASTArray, :children => [val[0],val[2]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 619) - def _reduce_152(val, _values, result) - result = ast AST::ResourceParam, :param => val[0], :value => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 633 + def _reduce_162( val, _values, result ) + result = ast AST::ResourceParam, :param => val[0], :value => val[2] + result end .,., -# reduce 153 omitted - -# reduce 154 omitted + # reduce 163 omitted -# reduce 155 omitted + # reduce 164 omitted -# reduce 156 omitted + # reduce 165 omitted -# reduce 157 omitted + # reduce 166 omitted -# reduce 158 omitted + # reduce 167 omitted -# reduce 159 omitted + # reduce 168 omitted -module_eval(<<'.,.,', 'grammar.ra', 630) - def _reduce_160(val, _values, result) - result = ast AST::Default, :value => val[0][:value], :line => val[0][:line] + # reduce 169 omitted - result +module_eval <<'.,.,', 'grammar.ra', 644 + def _reduce_170( val, _values, result ) + result = ast AST::Default, :value => val[0][:value], :line => val[0][:line] + result end .,., -# reduce 161 omitted + # reduce 171 omitted -module_eval(<<'.,.,', 'grammar.ra', 635) - def _reduce_162(val, _values, result) - result = [val[0][:value]] - result +module_eval <<'.,.,', 'grammar.ra', 647 + def _reduce_172( val, _values, result ) + result = [val[0][:value]] + result end .,., -# reduce 163 omitted + # reduce 173 omitted -module_eval(<<'.,.,', 'grammar.ra', 637) - def _reduce_164(val, _values, result) - result = val[0] += val[2] - result +module_eval <<'.,.,', 'grammar.ra', 649 + def _reduce_174( val, _values, result ) + result = val[0] += val[2] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 640) - def _reduce_165(val, _values, result) - val[1].each do |file| +module_eval <<'.,.,', 'grammar.ra', 658 + def _reduce_175( val, _values, result ) + val[1].each do |file| import(file) end result = AST::ASTArray.new(:children => []) - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 650) - def _reduce_166(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 669 + def _reduce_176( val, _values, result ) + @lexer.commentpop newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line] @lexer.indefine = false result = nil #} | DEFINE NAME argumentlist parent LBRACE RBRACE { - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 657) - def _reduce_167(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 674 + def _reduce_177( val, _values, result ) + @lexer.commentpop newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line] @lexer.indefine = false result = nil - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 665) - def _reduce_168(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 683 + def _reduce_178( val, _values, result ) + @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line] result = nil - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 671) - def _reduce_169(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 689 + def _reduce_179( val, _values, result ) + @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line] result = nil - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 679) - def _reduce_170(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 695 + def _reduce_180( val, _values, result ) + @lexer.commentpop newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line] result = nil - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 683) - def _reduce_171(val, _values, result) - @lexer.commentpop +module_eval <<'.,.,', 'grammar.ra', 699 + def _reduce_181( val, _values, result ) + @lexer.commentpop newnode val[1], :parent => val[2], :line => val[0][:line] result = nil - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 688) - def _reduce_172(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 700 + def _reduce_182( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 690) - def _reduce_173(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 702 + def _reduce_183( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 691) - def _reduce_174(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 703 + def _reduce_184( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 692) - def _reduce_175(val, _values, result) - result = "class" - result +module_eval <<'.,.,', 'grammar.ra', 704 + def _reduce_185( val, _values, result ) + result = "class" + result end .,., -# reduce 176 omitted + # reduce 186 omitted -module_eval(<<'.,.,', 'grammar.ra', 698) - def _reduce_177(val, _values, result) - result = val[0] +module_eval <<'.,.,', 'grammar.ra', 714 + def _reduce_187( val, _values, result ) + result = val[0] result = [result] unless result.is_a?(Array) result << val[2] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 704) - def _reduce_178(val, _values, result) - result = ast AST::HostName, :value => val[0] - - result +module_eval <<'.,.,', 'grammar.ra', 718 + def _reduce_188( val, _values, result ) + result = ast AST::HostName, :value => val[0] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 707) - def _reduce_179(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 719 + def _reduce_189( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 708) - def _reduce_180(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 720 + def _reduce_190( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 709) - def _reduce_181(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 721 + def _reduce_191( val, _values, result ) + result = val[0][:value] + result end .,., -# reduce 182 omitted - -module_eval(<<'.,.,', 'grammar.ra', 713) - def _reduce_183(val, _values, result) - result = nil + # reduce 192 omitted - result +module_eval <<'.,.,', 'grammar.ra', 727 + def _reduce_193( val, _values, result ) + result = nil + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 717) - def _reduce_184(val, _values, result) - result = ast AST::ASTArray, :children => [] - - result +module_eval <<'.,.,', 'grammar.ra', 731 + def _reduce_194( val, _values, result ) + result = ast AST::ASTArray, :children => [] + result end .,., -# reduce 185 omitted + # reduce 195 omitted -module_eval(<<'.,.,', 'grammar.ra', 722) - def _reduce_186(val, _values, result) - result = nil - - result +module_eval <<'.,.,', 'grammar.ra', 736 + def _reduce_196( val, _values, result ) + result = nil + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 725) - def _reduce_187(val, _values, result) - result = val[1] +module_eval <<'.,.,', 'grammar.ra', 740 + def _reduce_197( val, _values, result ) + result = val[1] result = [result] unless result[0].is_a?(Array) - - result + result end .,., -# reduce 188 omitted + # reduce 198 omitted -module_eval(<<'.,.,', 'grammar.ra', 731) - def _reduce_189(val, _values, result) - result = val[0] +module_eval <<'.,.,', 'grammar.ra', 747 + def _reduce_199( val, _values, result ) + result = val[0] result = [result] unless result[0].is_a?(Array) result << val[2] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 737) - def _reduce_190(val, _values, result) - Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") +module_eval <<'.,.,', 'grammar.ra', 752 + def _reduce_200( val, _values, result ) + Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value], val[2]] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 741) - def _reduce_191(val, _values, result) - Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") +module_eval <<'.,.,', 'grammar.ra', 756 + def _reduce_201( val, _values, result ) + Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value]] - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 744) - def _reduce_192(val, _values, result) - result = [val[0][:value], val[2]] - - result +module_eval <<'.,.,', 'grammar.ra', 758 + def _reduce_202( val, _values, result ) + result = [val[0][:value], val[2]] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 746) - def _reduce_193(val, _values, result) - result = [val[0][:value]] - - result +module_eval <<'.,.,', 'grammar.ra', 760 + def _reduce_203( val, _values, result ) + result = [val[0][:value]] + result end .,., -# reduce 194 omitted + # reduce 204 omitted -module_eval(<<'.,.,', 'grammar.ra', 751) - def _reduce_195(val, _values, result) - result = val[1] - - result +module_eval <<'.,.,', 'grammar.ra', 765 + def _reduce_205( val, _values, result ) + result = val[1] + result end .,., -# reduce 196 omitted + # reduce 206 omitted -module_eval(<<'.,.,', 'grammar.ra', 756) - def _reduce_197(val, _values, result) - result = val[1] - - result +module_eval <<'.,.,', 'grammar.ra', 770 + def _reduce_207( val, _values, result ) + result = val[1] + result end .,., -# reduce 198 omitted + # reduce 208 omitted -# reduce 199 omitted + # reduce 209 omitted -module_eval(<<'.,.,', 'grammar.ra', 762) - def _reduce_200(val, _values, result) - result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] - - result +module_eval <<'.,.,', 'grammar.ra', 776 + def _reduce_210( val, _values, result ) + result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 766) - def _reduce_201(val, _values, result) - if val[1].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 784 + def _reduce_211( val, _values, result ) + if val[1].instance_of?(AST::ASTArray) result = val[1] else result = ast AST::ASTArray, :children => [val[1]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 773) - def _reduce_202(val, _values, result) - if val[1].instance_of?(AST::ASTArray) +module_eval <<'.,.,', 'grammar.ra', 791 + def _reduce_212( val, _values, result ) + if val[1].instance_of?(AST::ASTArray) result = val[1] else result = ast AST::ASTArray, :children => [val[1]] end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 779) - def _reduce_203(val, _values, result) - result = ast AST::ASTArray - - result +module_eval <<'.,.,', 'grammar.ra', 793 + def _reduce_213( val, _values, result ) + result = ast AST::ASTArray + result end .,., -# reduce 204 omitted + # reduce 214 omitted -# reduce 205 omitted + # reduce 215 omitted -# reduce 206 omitted + # reduce 216 omitted -module_eval(<<'.,.,', 'grammar.ra', 786) - def _reduce_207(val, _values, result) - result = nil - result +module_eval <<'.,.,', 'grammar.ra', 798 + def _reduce_217( val, _values, result ) + result = nil + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 789) - def _reduce_208(val, _values, result) - result = ast AST::Regex, :value => val[0][:value] - - result +module_eval <<'.,.,', 'grammar.ra', 803 + def _reduce_218( val, _values, result ) + result = ast AST::Regex, :value => val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 793) - def _reduce_209(val, _values, result) - if val[1].instance_of?(AST::ASTHash) +module_eval <<'.,.,', 'grammar.ra', 811 + def _reduce_219( val, _values, result ) + if val[1].instance_of?(AST::ASTHash) result = val[1] else result = ast AST::ASTHash, { :value => val[1] } end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 800) - def _reduce_210(val, _values, result) - if val[1].instance_of?(AST::ASTHash) +module_eval <<'.,.,', 'grammar.ra', 818 + def _reduce_220( val, _values, result ) + if val[1].instance_of?(AST::ASTHash) result = val[1] else result = ast AST::ASTHash, { :value => val[1] } end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 806) - def _reduce_211(val, _values, result) - result = ast AST::ASTHash - - result +module_eval <<'.,.,', 'grammar.ra', 820 + def _reduce_221( val, _values, result ) + result = ast AST::ASTHash + result end .,., -# reduce 212 omitted + # reduce 222 omitted -module_eval(<<'.,.,', 'grammar.ra', 811) - def _reduce_213(val, _values, result) - if val[0].instance_of?(AST::ASTHash) +module_eval <<'.,.,', 'grammar.ra', 830 + def _reduce_223( val, _values, result ) + if val[0].instance_of?(AST::ASTHash) result = val[0].merge(val[2]) else result = ast AST::ASTHash, :value => val[0] result.merge(val[2]) end - - result + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 820) - def _reduce_214(val, _values, result) - result = ast AST::ASTHash, { :value => { val[0] => val[2] } } - - result +module_eval <<'.,.,', 'grammar.ra', 834 + def _reduce_224( val, _values, result ) + result = ast AST::ASTHash, { :value => { val[0] => val[2] } } + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 823) - def _reduce_215(val, _values, result) - result = val[0][:value] - result +module_eval <<'.,.,', 'grammar.ra', 835 + def _reduce_225( val, _values, result ) + result = val[0][:value] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 824) - def _reduce_216(val, _values, result) - result = val[0] - result +module_eval <<'.,.,', 'grammar.ra', 836 + def _reduce_226( val, _values, result ) + result = val[0] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 827) - def _reduce_217(val, _values, result) - result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2] - - result +module_eval <<'.,.,', 'grammar.ra', 841 + def _reduce_227( val, _values, result ) + result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2] + result end .,., -# reduce 218 omitted - -module_eval(<<'.,.,', 'grammar.ra', 832) - def _reduce_219(val, _values, result) - result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2] + # reduce 228 omitted - result +module_eval <<'.,.,', 'grammar.ra', 846 + def _reduce_229( val, _values, result ) + result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2] + result end .,., -def _reduce_none(val, _values, result) - val[0] -end + def _reduce_none( val, _values, result ) + result + end end # class Parser - end # module Parser - end # module Puppet + + end # module Parser + +end # module Puppet diff --git a/lib/puppet/parser/relationship.rb b/lib/puppet/parser/relationship.rb new file mode 100644 index 000000000..1d1bad76c --- /dev/null +++ b/lib/puppet/parser/relationship.rb @@ -0,0 +1,43 @@ +class Puppet::Parser::Relationship + attr_accessor :source, :target, :type + + PARAM_MAP = {:relationship => :before, :subscription => :notify} + + def evaluate(catalog) + if source.is_a?(Puppet::Parser::Collector) + sources = source.collected.values + else + sources = [source] + end + if target.is_a?(Puppet::Parser::Collector) + targets = target.collected.values + else + targets = [target] + end + sources.each do |s| + targets.each do |t| + mk_relationship(s, t, catalog) + end + end + end + + def initialize(source, target, type) + @source, @target, @type = source, target, type + end + + def param_name + PARAM_MAP[type] || raise(ArgumentError, "Invalid relationship type #{type}") + end + + def mk_relationship(source, target, catalog) + unless source_resource = catalog.resource(source.to_s) + raise ArgumentError, "Could not find resource '#{source}' for relationship on '#{target}'" + end + unless target_resource = catalog.resource(target.to_s) + raise ArgumentError, "Could not find resource '#{target}' for relationship from '#{source}'" + end + Puppet.debug "Adding relationship from #{source.to_s} to #{target.to_s} with '#{param_name}'" + source_resource[param_name] ||= [] + source_resource[param_name] << target.to_s + end +end diff --git a/spec/integration/parser/parser.rb b/spec/integration/parser/parser.rb index 5a30f066e..ee476c02f 100755 --- a/spec/integration/parser/parser.rb +++ b/spec/integration/parser/parser.rb @@ -1,21 +1,113 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser::Parser do + module ParseMatcher + class ParseAs + def initialize(klass) + @parser = Puppet::Parser::Parser.new "development" + @class = klass + end + + def result_instance + @result.hostclass("").code[0] + end + + def matches?(string) + @string = string + @result = @parser.parse(string) + return result_instance.instance_of?(@class) + end + + def description + "parse as a #{@class}" + end + + def failure_message + " expected #{@string} to parse as #{@class} but was #{result_instance.class}" + end + + def negative_failure_message + " expected #{@string} not to parse as #{@class}" + end + end + + def parse_as(klass) + ParseAs.new(klass) + end + + class ParseWith + def initialize(block) + @parser = Puppet::Parser::Parser.new "development" + @block = block + end + + def result_instance + @result.hostclass("").code[0] + end + + def matches?(string) + @string = string + @result = @parser.parse(string) + return @block.call(result_instance) + end + + def description + "parse with the block evaluating to true" + end + + def failure_message + " expected #{@string} to parse with a true result in the block" + end + + def negative_failure_message + " expected #{@string} not to parse with a true result in the block" + end + end + + def parse_with(&block) + ParseWith.new(block) + end + end + + include ParseMatcher + before :each do @resource_type_collection = Puppet::Resource::TypeCollection.new("env") @parser = Puppet::Parser::Parser.new "development" end describe "when parsing comments before statement" do it "should associate the documentation to the statement AST node" do ast = @parser.parse(""" # comment class test {} """) ast.hostclass("test").doc.should == "comment\n" end end + + describe "when parsing" do + it "should be able to parse normal left to right relationships" do + "Notify[foo] -> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship) + end + + it "should be able to parse right to left relationships" do + "Notify[foo] <- Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship) + end + + it "should be able to parse normal left to right subscriptions" do + "Notify[foo] ~> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship) + end + + it "should be able to parse right to left subscriptions" do + "Notify[foo] <~ Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship) + end + + it "should correctly set the arrow type of a relationship" do + "Notify[foo] <~ Notify[bar]".should parse_with { |rel| rel.arrow == "<~" } + end + end end diff --git a/spec/unit/parser/ast/relationship.rb b/spec/unit/parser/ast/relationship.rb new file mode 100644 index 000000000..acb46e4ce --- /dev/null +++ b/spec/unit/parser/ast/relationship.rb @@ -0,0 +1,88 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe Puppet::Parser::AST::Relationship do + before do + @class = Puppet::Parser::AST::Relationship + end + + it "should set its 'left' and 'right' arguments accordingly" do + dep = @class.new(:left, :right, '->') + dep.left.should == :left + dep.right.should == :right + end + + it "should set its arrow to whatever arrow is passed" do + @class.new(:left, :right, '->').arrow.should == '->' + end + + it "should set its type to :relationship if the relationship type is '<-'" do + @class.new(:left, :right, '<-').type.should == :relationship + end + + it "should set its type to :relationship if the relationship type is '->'" do + @class.new(:left, :right, '->').type.should == :relationship + end + + it "should set its type to :subscription if the relationship type is '~>'" do + @class.new(:left, :right, '~>').type.should == :subscription + end + + it "should set its type to :subscription if the relationship type is '<~'" do + @class.new(:left, :right, '<~').type.should == :subscription + end + + it "should set its line and file if provided" do + dep = @class.new(:left, :right, '->', :line => 50, :file => "/foo") + dep.line.should == 50 + dep.file.should == "/foo" + end + + describe "when evaluating" do + before do + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + end + + it "should create a relationship with the evaluated source and target and add it to the scope" do + source = stub 'source', :safeevaluate => :left + target = stub 'target', :safeevaluate => :right + @class.new(source, target, '->').evaluate(@scope) + @compiler.relationships[0].source.should == :left + @compiler.relationships[0].target.should == :right + end + + describe "a chained relationship" do + before do + @left = stub 'left', :safeevaluate => :left + @middle = stub 'middle', :safeevaluate => :middle + @right = stub 'right', :safeevaluate => :right + @first = @class.new(@left, @middle, '->') + @second = @class.new(@first, @right, '->') + end + + it "should evaluate the relationship to the left" do + @first.expects(:evaluate).with(@scope).returns Puppet::Parser::Relationship.new(:left, :right, :relationship) + + @second.evaluate(@scope) + end + + it "should use the right side of the left relationship as its source" do + @second.evaluate(@scope) + + @compiler.relationships[0].source.should == :left + @compiler.relationships[0].target.should == :middle + @compiler.relationships[1].source.should == :middle + @compiler.relationships[1].target.should == :right + end + + it "should only evaluate a given AST node once" do + @left.expects(:safeevaluate).once.returns :left + @middle.expects(:safeevaluate).once.returns :middle + @right.expects(:safeevaluate).once.returns :right + @second.evaluate(@scope) + end + end + end +end diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb index 6fd4d1fb5..c36113ff6 100755 --- a/spec/unit/parser/compiler.rb +++ b/spec/unit/parser/compiler.rb @@ -1,604 +1,613 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' class CompilerTestResource attr_accessor :builtin, :virtual, :evaluated, :type, :title def initialize(type, title) @type = type @title = title end def ref "%s[%s]" % [type.to_s.capitalize, title] end def evaluated? @evaluated end def builtin? @builtin end def virtual? @virtual end def evaluate end end describe Puppet::Parser::Compiler do before :each do @node = Puppet::Node.new "testnode" @known_resource_types = Puppet::Resource::TypeCollection.new "development" @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]', :type => "class" @scope = stub 'scope', :resource => @scope_resource, :source => mock("source") @compiler = Puppet::Parser::Compiler.new(@node) @compiler.environment.stubs(:known_resource_types).returns @known_resource_types end it "should have a class method that compiles, converts, and returns a catalog" do compiler = stub 'compiler' Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler catalog = stub 'catalog' compiler.expects(:compile).returns catalog converted_catalog = stub 'converted_catalog' catalog.expects(:to_resource).returns converted_catalog Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog) end it "should fail intelligently when a class-level compile fails" do Puppet::Parser::Compiler.expects(:new).raises ArgumentError lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error) end it "should use the node's environment as its environment" do @compiler.environment.should equal(@node.environment) end it "should include the resource type collection helper" do Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) end it "should be able to return a class list containing all added classes" do @compiler.add_class "" @compiler.add_class "one" @compiler.add_class "two" @compiler.classlist.sort.should == %w{one two}.sort end describe "when initializing" do it "should set its node attribute" do @compiler.node.should equal(@node) end it "should detect when ast nodes are absent" do @compiler.ast_nodes?.should be_false end it "should detect when ast nodes are present" do @known_resource_types.expects(:nodes?).returns true @compiler.ast_nodes?.should be_true end it "should copy the known_resource_types version to the catalog" do @compiler.catalog.version.should == @known_resource_types.version end it "should copy any node classes into the class list" do node = Puppet::Node.new("mynode") node.classes = %w{foo bar} compiler = Puppet::Parser::Compiler.new(node) compiler.classlist.should include("foo") compiler.classlist.should include("bar") end end describe "when managing scopes" do it "should create a top scope" do @compiler.topscope.should be_instance_of(Puppet::Parser::Scope) end it "should be able to create new scopes" do @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope) end it "should correctly set the level of newly created scopes" do @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5 end it "should set the parent scope of the new scope to be the passed-in parent" do scope = mock 'scope' newscope = @compiler.newscope(scope) newscope.parent.should equal(scope) end it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do scope = mock 'scope' newscope = @compiler.newscope(nil) newscope.parent.should equal(@compiler.topscope) end end describe "when compiling" do def compile_methods [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated, - :finish, :store, :extract] + :finish, :store, :extract, :evaluate_relationships] end # Stub all of the main compile methods except the ones we're specifically interested in. def compile_stub(*except) (compile_methods - except).each { |m| @compiler.stubs(m) } end it "should set node parameters as variables in the top scope" do params = {"a" => "b", "c" => "d"} @node.stubs(:parameters).returns(params) compile_stub(:set_node_parameters) @compiler.compile @compiler.topscope.lookupvar("a").should == "b" @compiler.topscope.lookupvar("c").should == "d" end it "should set the client and server versions on the catalog" do params = {"clientversion" => "2", "serverversion" => "3"} @node.stubs(:parameters).returns(params) compile_stub(:set_node_parameters) @compiler.compile @compiler.catalog.client_version.should == "2" @compiler.catalog.server_version.should == "3" end it "should evaluate any existing classes named in the node" do classes = %w{one two three four} main = stub 'main' one = stub 'one', :name => "one" three = stub 'three', :name => "three" @node.stubs(:name).returns("whatever") @node.stubs(:classes).returns(classes) @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope) @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes } end it "should evaluate the main class if it exists" do compile_stub(:evaluate_main) main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "") main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) } @compiler.topscope.expects(:source=).with(main_class) @compiler.compile end it "should create a new, empty 'main' if no main class exists" do compile_stub(:evaluate_main) @compiler.compile @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type) end it "should evaluate any node classes" do @node.stubs(:classes).returns(%w{one two three four}) @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope) @compiler.send(:evaluate_node_classes) end it "should evaluate all added collections" do colls = [] # And when the collections fail to evaluate. colls << mock("coll1-false") colls << mock("coll2-false") colls.each { |c| c.expects(:evaluate).returns(false) } @compiler.add_collection(colls[0]) @compiler.add_collection(colls[1]) compile_stub(:evaluate_generators) @compiler.compile end it "should ignore builtin resources" do resource = stub 'builtin', :ref => "File[testing]", :builtin? => true, :type => "file" @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end it "should evaluate unevaluated resources" do resource = CompilerTestResource.new(:file, "testing") @compiler.add_resource(@scope, resource) # We have to now mark the resource as evaluated resource.expects(:evaluate).with { |*whatever| resource.evaluated = true } @compiler.compile end it "should not evaluate already-evaluated resources" do resource = stub 'already_evaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => true, :virtual? => false, :type => "file" @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end it "should evaluate unevaluated resources created by evaluating other resources" do resource = CompilerTestResource.new(:file, "testing") @compiler.add_resource(@scope, resource) resource2 = CompilerTestResource.new(:file, "other") # We have to now mark the resource as evaluated resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) } resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true } @compiler.compile end it "should call finish() on all resources" do # Add a resource that does respond to :finish resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope resource.expects(:finish) @compiler.add_resource(@scope, resource) # And one that does not dnf = stub "dnf", :ref => "File[dnf]", :type => "file" @compiler.add_resource(@scope, dnf) @compiler.send(:finish) end it "should call finish() in add_resource order" do resources = sequence('resources') resource1 = Puppet::Parser::Resource.new "file", "finish1", :scope => @scope resource1.expects(:finish).in_sequence(resources) @compiler.add_resource(@scope, resource1) resource2 = Puppet::Parser::Resource.new "file", "finish2", :scope => @scope resource2.expects(:finish).in_sequence(resources) @compiler.add_resource(@scope, resource2) @compiler.send(:finish) end it "should return added resources in add order" do resource1 = stub "1", :ref => "File[yay]", :type => "file" @compiler.add_resource(@scope, resource1) resource2 = stub "2", :ref => "File[youpi]", :type => "file" @compiler.add_resource(@scope, resource2) @compiler.resources.should == [resource1, resource2] end it "should add resources that do not conflict with existing resources" do resource = CompilerTestResource.new(:file, "yay") @compiler.add_resource(@scope, resource) @compiler.catalog.should be_vertex(resource) end it "should fail to add resources that conflict with existing resources" do file1 = Puppet::Type.type(:file).new :path => "/foo" file2 = Puppet::Type.type(:file).new :path => "/foo" @compiler.add_resource(@scope, file1) lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError) end it "should add an edge from the scope resource to the added resource" do resource = stub "noconflict", :ref => "File[yay]", :type => "file" @compiler.add_resource(@scope, resource) @compiler.catalog.should be_edge(@scope.resource, resource) end it "should add edges from the class resources to the main class" do main = CompilerTestResource.new(:class, :main) @compiler.add_resource(@scope, main) resource = CompilerTestResource.new(:class, "foo") @compiler.add_resource(@scope, resource) @compiler.catalog.should be_edge(main, resource) end it "should just add edges to the scope resource for the class resources when no main class can be found" do resource = CompilerTestResource.new(:class, "foo") @compiler.add_resource(@scope, resource) @compiler.catalog.should be_edge(@scope.resource, resource) end it "should have a method for looking up resources" do resource = stub 'resource', :ref => "Yay[foo]", :type => "file" @compiler.add_resource(@scope, resource) @compiler.findresource("Yay[foo]").should equal(resource) end it "should be able to look resources up by type and title" do resource = stub 'resource', :ref => "Yay[foo]", :type => "file" @compiler.add_resource(@scope, resource) @compiler.findresource("Yay", "foo").should equal(resource) end it "should not evaluate virtual defined resources" do resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => true, :type => "file" @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end end describe "when evaluating collections" do it "should evaluate each collection" do 2.times { |i| coll = mock 'coll%s' % i @compiler.add_collection(coll) # This is the hard part -- we have to emulate the fact that # collections delete themselves if they are done evaluating. coll.expects(:evaluate).with do @compiler.delete_collection(coll) end } @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections } end it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns(nil) @compiler.add_collection(coll) lambda { @compiler.compile }.should_not raise_error end it "should fail when there are unevaluated resource collections that refer to a specific resource" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns(:something) @compiler.add_collection(coll) lambda { @compiler.compile }.should raise_error(Puppet::ParseError) end it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns([:one, :two]) @compiler.add_collection(coll) lambda { @compiler.compile }.should raise_error(Puppet::ParseError) end end + describe "when evaluating relationships" do + it "should evaluate each relationship with its catalog" do + dep = stub 'dep' + dep.expects(:evaluate).with(@compiler.catalog) + @compiler.add_relationship dep + @compiler.evaluate_relationships + end + end + describe "when told to evaluate missing classes" do it "should fail if there's no source listed for the scope" do scope = stub 'scope', :source => nil proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) end it "should tag the catalog with the name of each not-found class" do @compiler.catalog.expects(:tag).with("notfound") @scope.expects(:find_hostclass).with("notfound").returns(nil) @compiler.evaluate_classes(%w{notfound}, @scope) end end describe "when evaluating found classes" do before do @class = stub 'class', :name => "my::class" @scope.stubs(:find_hostclass).with("myclass").returns(@class) @resource = stub 'resource', :ref => "Class[myclass]", :type => "file" end it "should evaluate each class" do @compiler.catalog.stubs(:tag) @class.expects(:mk_plain_resource).with(@scope) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope) end it "should not evaluate the resources created for found classes unless asked" do @compiler.catalog.stubs(:tag) @resource.expects(:evaluate).never @class.expects(:mk_plain_resource).returns(@resource) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope) end it "should immediately evaluate the resources created for found classes when asked" do @compiler.catalog.stubs(:tag) @resource.expects(:evaluate) @class.expects(:mk_plain_resource).returns(@resource) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope, false) end it "should skip classes that have already been evaluated" do @compiler.catalog.stubs(:tag) @scope.stubs(:class_scope).with(@class).returns("something") @compiler.expects(:add_resource).never @resource.expects(:evaluate).never Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{myclass}, @scope, false) end it "should skip classes previously evaluated with different capitalization" do @compiler.catalog.stubs(:tag) @scope.stubs(:find_hostclass).with("MyClass").returns(@class) @scope.stubs(:class_scope).with(@class).returns("something") @compiler.expects(:add_resource).never @resource.expects(:evaluate).never Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{MyClass}, @scope, false) end it "should return the list of found classes" do @compiler.catalog.stubs(:tag) @compiler.stubs(:add_resource) @scope.stubs(:find_hostclass).with("notfound").returns(nil) @scope.stubs(:class_scope).with(@class) Puppet::Parser::Resource.stubs(:new).returns(@resource) @class.stubs :mk_plain_resource @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass} end end describe "when evaluating AST nodes with no AST nodes present" do it "should do nothing" do @compiler.expects(:ast_nodes?).returns(false) @compiler.known_resource_types.expects(:nodes).never Puppet::Parser::Resource.expects(:new).never @compiler.send(:evaluate_ast_node) end end describe "when evaluating AST nodes with AST nodes present" do before do @compiler.known_resource_types.stubs(:nodes?).returns true # Set some names for our test @node.stubs(:names).returns(%w{a b c}) @compiler.known_resource_types.stubs(:node).with("a").returns(nil) @compiler.known_resource_types.stubs(:node).with("b").returns(nil) @compiler.known_resource_types.stubs(:node).with("c").returns(nil) # It should check this last, of course. @compiler.known_resource_types.stubs(:node).with("default").returns(nil) end it "should fail if the named node cannot be found" do proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError) end it "should evaluate the first node class matching the node name" do node_class = stub 'node', :name => "c", :evaluate_code => nil @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" node_class.expects(:mk_plain_resource).returns(node_resource) @compiler.compile end it "should match the default node if no matching node can be found" do node_class = stub 'node', :name => "default", :evaluate_code => nil @compiler.known_resource_types.stubs(:node).with("default").returns(node_class) node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node" node_class.expects(:mk_plain_resource).returns(node_resource) @compiler.compile end it "should evaluate the node resource immediately rather than using lazy evaluation" do node_class = stub 'node', :name => "c" @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) node_resource = stub 'node resource', :ref => "Node[c]", :type => "node" node_class.expects(:mk_plain_resource).returns(node_resource) node_resource.expects(:evaluate) @compiler.send(:evaluate_ast_node) end it "should set the node's scope as the top scope" do node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) # The #evaluate method normally does this. scope = stub 'scope', :source => "mysource" @compiler.topscope.expects(:class_scope).with(node_class).returns(scope) node_resource.stubs(:evaluate) @compiler.compile @compiler.topscope.should equal(scope) end end describe "when managing resource overrides" do before do @override = stub 'override', :ref => "My[ref]", :type => "my" @resource = stub 'resource', :ref => "My[ref]", :builtin? => true, :type => "my" end it "should be able to store overrides" do lambda { @compiler.add_override(@override) }.should_not raise_error end it "should apply overrides to the appropriate resources" do @compiler.add_resource(@scope, @resource) @resource.expects(:merge).with(@override) @compiler.add_override(@override) @compiler.compile end it "should accept overrides before the related resource has been created" do @resource.expects(:merge).with(@override) # First store the override @compiler.add_override(@override) # Then the resource @compiler.add_resource(@scope, @resource) # And compile, so they get resolved @compiler.compile end it "should fail if the compile is finished and resource overrides have not been applied" do @compiler.add_override(@override) lambda { @compiler.compile }.should raise_error(Puppet::ParseError) end end end diff --git a/spec/unit/parser/lexer.rb b/spec/unit/parser/lexer.rb index 2e58ef485..b1524f1e0 100755 --- a/spec/unit/parser/lexer.rb +++ b/spec/unit/parser/lexer.rb @@ -1,634 +1,638 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/parser/lexer' # This is a special matcher to match easily lexer output Spec::Matchers.create :be_like do |*expected| match do |actual| expected.zip(actual).all? { |e,a| !e or a[0] == e or (e.is_a? Array and a[0] == e[0] and (a[1] == e[1] or (a[1].is_a?(Hash) and a[1][:value] == e[1]))) } end end __ = nil describe Puppet::Parser::Lexer do describe "when reading strings" do before { @lexer = Puppet::Parser::Lexer.new } it "should increment the line count for every carriage return in the string" do @lexer.line = 10 @lexer.string = "this\nis\natest'" @lexer.slurpstring("'") @lexer.line.should == 12 end it "should not increment the line count for escapes in the string" do @lexer.line = 10 @lexer.string = "this\\nis\\natest'" @lexer.slurpstring("'") @lexer.line.should == 10 end end end describe Puppet::Parser::Lexer::Token do before do @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME) end [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param| it "should have a #{param.to_s} reader" do @token.should be_respond_to(param) end it "should have a #{param.to_s} writer" do @token.should be_respond_to(param.to_s + "=") end end end describe Puppet::Parser::Lexer::Token, "when initializing" do it "should create a regex if the first argument is a string" do Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something} end it "should set the string if the first argument is one" do Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something" end it "should set the regex if the first argument is one" do Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something} end end describe Puppet::Parser::Lexer::TokenList do before do @list = Puppet::Parser::Lexer::TokenList.new end it "should have a method for retrieving tokens by the name" do token = @list.add_token :name, "whatever" @list[:name].should equal(token) end it "should have a method for retrieving string tokens by the string" do token = @list.add_token :name, "whatever" @list.lookup("whatever").should equal(token) end it "should add tokens to the list when directed" do token = @list.add_token :name, "whatever" @list[:name].should equal(token) end it "should have a method for adding multiple tokens at once" do @list.add_tokens "whatever" => :name, "foo" => :bar @list[:name].should_not be_nil @list[:bar].should_not be_nil end it "should fail to add tokens sharing a name with an existing token" do @list.add_token :name, "whatever" lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError) end it "should set provided options on tokens being added" do token = @list.add_token :name, "whatever", :skip_text => true token.skip_text.should == true end it "should define any provided blocks as a :convert method" do token = @list.add_token(:name, "whatever") do "foo" end token.convert.should == "foo" end it "should store all string tokens in the :string_tokens list" do one = @list.add_token(:name, "1") @list.string_tokens.should be_include(one) end it "should store all regex tokens in the :regex_tokens list" do one = @list.add_token(:name, %r{one}) @list.regex_tokens.should be_include(one) end it "should not store string tokens in the :regex_tokens list" do one = @list.add_token(:name, "1") @list.regex_tokens.should_not be_include(one) end it "should not store regex tokens in the :string_tokens list" do one = @list.add_token(:name, %r{one}) @list.string_tokens.should_not be_include(one) end it "should sort the string tokens inversely by length when asked" do one = @list.add_token(:name, "1") two = @list.add_token(:other, "12") @list.sort_tokens @list.string_tokens.should == [two, one] end end describe Puppet::Parser::Lexer::TOKENS do before do @lexer = Puppet::Parser::Lexer.new() end { :LBRACK => '[', :RBRACK => ']', :LBRACE => '{', :RBRACE => '}', :LPAREN => '(', :RPAREN => ')', :EQUALS => '=', :ISEQUAL => '==', :GREATEREQUAL => '>=', :GREATERTHAN => '>', :LESSTHAN => '<', :LESSEQUAL => '<=', :NOTEQUAL => '!=', :NOT => '!', :COMMA => ',', :DOT => '.', :COLON => ':', :AT => '@', :LLCOLLECT => '<<|', :RRCOLLECT => '|>>', :LCOLLECT => '<|', :RCOLLECT => '|>', :SEMIC => ';', :QMARK => '?', :BACKSLASH => '\\', :FARROW => '=>', :PARROW => '+>', :APPENDS => '+=', :PLUS => '+', :MINUS => '-', :DIV => '/', :TIMES => '*', :LSHIFT => '<<', :RSHIFT => '>>', :MATCH => '=~', :NOMATCH => '!~', + :IN_EDGE => '->', + :OUT_EDGE => '<-', + :IN_EDGE_SUB => '~>', + :OUT_EDGE_SUB => '<~', }.each do |name, string| it "should have a token named #{name.to_s}" do Puppet::Parser::Lexer::TOKENS[name].should_not be_nil end it "should match '#{string}' for the token #{name.to_s}" do Puppet::Parser::Lexer::TOKENS[name].string.should == string end end { "case" => :CASE, "class" => :CLASS, "default" => :DEFAULT, "define" => :DEFINE, "import" => :IMPORT, "if" => :IF, "elsif" => :ELSIF, "else" => :ELSE, "inherits" => :INHERITS, "node" => :NODE, "and" => :AND, "or" => :OR, "undef" => :UNDEF, "false" => :FALSE, "true" => :TRUE }.each do |string, name| it "should have a keyword named #{name.to_s}" do Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil end it "should have the keyword for #{name.to_s} set to #{string}" do Puppet::Parser::Lexer::KEYWORDS[name].string.should == string end end # These tokens' strings don't matter, just that the tokens exist. [:STRING, :DQPRE, :DQMID, :DQPOST, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :MLCOMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name| it "should have a token named #{name.to_s}" do Puppet::Parser::Lexer::TOKENS[name].should_not be_nil end end end describe Puppet::Parser::Lexer::TOKENS[:CLASSNAME] do before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] } it "should match against lower-case alpha-numeric terms separated by double colons" do @token.regex.should =~ "one::two" end it "should match against many lower-case alpha-numeric terms separated by double colons" do @token.regex.should =~ "one::two::three::four::five" end it "should match against lower-case alpha-numeric terms prefixed by double colons" do @token.regex.should =~ "::one" end end describe Puppet::Parser::Lexer::TOKENS[:CLASSREF] do before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] } it "should match against single upper-case alpha-numeric terms" do @token.regex.should =~ "One" end it "should match against upper-case alpha-numeric terms separated by double colons" do @token.regex.should =~ "One::Two" end it "should match against many upper-case alpha-numeric terms separated by double colons" do @token.regex.should =~ "One::Two::Three::Four::Five" end it "should match against upper-case alpha-numeric terms prefixed by double colons" do @token.regex.should =~ "::One" end end describe Puppet::Parser::Lexer::TOKENS[:NAME] do before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] } it "should match against lower-case alpha-numeric terms" do @token.regex.should =~ "one-two" end it "should return itself and the value if the matched term is not a keyword" do Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil) @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] end it "should return the keyword token and the value if the matched term is a keyword" do keyword = stub 'keyword', :name => :testing Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) @token.convert(stub("lexer"), "myval").should == [keyword, "myval"] end it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do keyword = stub 'keyword', :name => :TRUE Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true] end it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do keyword = stub 'keyword', :name => :FALSE Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false] end end describe Puppet::Parser::Lexer::TOKENS[:NUMBER] do before do @token = Puppet::Parser::Lexer::TOKENS[:NUMBER] @regex = @token.regex end it "should match against numeric terms" do @regex.should =~ "2982383139" end it "should match against float terms" do @regex.should =~ "29823.235" end it "should match against hexadecimal terms" do @regex.should =~ "0xBEEF0023" end it "should match against float with exponent terms" do @regex.should =~ "10e23" end it "should match against float terms with negative exponents" do @regex.should =~ "10e-23" end it "should match against float terms with fractional parts and exponent" do @regex.should =~ "1.234e23" end it "should return the NAME token and the value" do @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] end end describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] } it "should match against lines starting with '#'" do @token.regex.should =~ "# this is a comment" end it "should be marked to get skipped" do @token.skip?.should be_true end it "should be marked to accumulate" do @token.accumulate?.should be_true end it "'s block should return the comment without the #" do @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment" end end describe Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] do before do @token = Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] @lexer = stub 'lexer', :line => 0 end it "should match against lines enclosed with '/*' and '*/'" do @token.regex.should =~ "/* this is a comment */" end it "should match multiple lines enclosed with '/*' and '*/'" do @token.regex.should =~ """/* this is a comment */""" end it "should increase the lexer current line number by the amount of lines spanned by the comment" do @lexer.expects(:line=).with(2) @token.convert(@lexer, "1\n2\n3") end it "should not greedily match comments" do match = @token.regex.match("/* first */ word /* second */") match[1].should == " first " end it "should be marked to accumulate" do @token.accumulate?.should be_true end it "'s block should return the comment without the comment marks" do @lexer.stubs(:line=).with(0) @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment" end end describe Puppet::Parser::Lexer::TOKENS[:RETURN] do before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] } it "should match against carriage returns" do @token.regex.should =~ "\n" end it "should be marked to initiate text skipping" do @token.skip_text.should be_true end it "should be marked to increment the line" do @token.incr_line.should be_true end end def tokens_scanned_from(s) lexer = Puppet::Parser::Lexer.new lexer.string = s lexer.fullscan[0..-2] end describe Puppet::Parser::Lexer,"when lexing strings" do { %q['single quoted string')] => [[:STRING,'single quoted string']], %q["double quoted string"] => [[:STRING,'double quoted string']], %q['single quoted string with an escaped "\\'"'] => [[:STRING,'single quoted string with an escaped "\'"']], %q["string with an escaped '\\"'"] => [[:STRING,"string with an escaped '\"'"]], %q["string with an escaped '\\$'"] => [[:STRING,"string with an escaped '$'"]], %q["string with $v (but no braces)"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' (but no braces)']], %q["string with ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' in braces']], %q["string with $v and $v (but no braces)"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," (but no braces)"]], %q["string with ${v} and ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," in braces"]], %q["string with ${'a nested single quoted string'} inside it."] => [[:DQPRE,"string with "],[:STRING,'a nested single quoted string'],[:DQPOST,' inside it.']], %q["string with ${['an array ',$v2]} in it."] => [[:DQPRE,"string with "],:LBRACK,[:STRING,"an array "],:COMMA,[:VARIABLE,"v2"],:RBRACK,[:DQPOST," in it."]], %q{a simple "scanner" test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"scanner"],[:NAME,"test"]], %q{a simple 'single quote scanner' test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"single quote scanner"],[:NAME,"test"]], %q{a harder 'a $b \c"'} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,'a $b \c"']], %q{a harder "scanner test"} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,"scanner test"]], %q{a hardest "scanner \"test\""} => [[:NAME,"a"],[:NAME,"hardest"],[:STRING,'scanner "test"']], %Q{a hardestest "scanner \\"test\\"\n"} => [[:NAME,"a"],[:NAME,"hardestest"],[:STRING,%Q{scanner "test"\n}]], %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:STRING,'call'],[:RPAREN,")"]], %q["string with ${(3+5)/4} nested math."] => [[:DQPRE,"string with "],:LPAREN,[:NAME,"3"],:PLUS,[:NAME,"5"],:RPAREN,:DIV,[:NAME,"4"],[:DQPOST," nested math."]] }.each { |src,expected_result| it "should handle #{src} correctly" do tokens_scanned_from(src).should be_like(*expected_result) end } end describe Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] do before { @token = Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] } it "should match against alpha words prefixed with '$'" do @token.regex.should =~ '$this_var' end it "should return the VARIABLE token and the variable name stripped of the '$'" do @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"] end end describe Puppet::Parser::Lexer::TOKENS[:REGEX] do before { @token = Puppet::Parser::Lexer::TOKENS[:REGEX] } it "should match against any expression enclosed in //" do @token.regex.should =~ '/this is a regex/' end it 'should not match if there is \n in the regex' do @token.regex.should_not =~ "/this is \n a regex/" end describe "when scanning" do it "should not consider escaped slashes to be the end of a regex" do tokens_scanned_from("$x =~ /this \\/ foo/").should be_like(__,__,[:REGEX,%r{this / foo}]) end it "should not lex chained division as a regex" do tokens_scanned_from("$x = $a/$b/$c").collect { |name, data| name }.should_not be_include( :REGEX ) end it "should accept a regular expression after NODE" do tokens_scanned_from("node /www.*\.mysite\.org/").should be_like(__,[:REGEX,Regexp.new("www.*\.mysite\.org")]) end it "should accept regular expressions in a CASE" do s = %q{case $variable { "something": {$othervar = 4096 / 2} /regex/: {notice("this notably sucks")} } } tokens_scanned_from(s).should be_like( :CASE,:VARIABLE,:LBRACE,:STRING,:COLON,:LBRACE,:VARIABLE,:EQUALS,:NAME,:DIV,:NAME,:RBRACE,[:REGEX,/regex/],:COLON,:LBRACE,:NAME,:LPAREN,:STRING,:RPAREN,:RBRACE,:RBRACE ) end end it "should return the REGEX token and a Regexp" do @token.convert(stub("lexer"), "/myregex/").should == [Puppet::Parser::Lexer::TOKENS[:REGEX], Regexp.new(/myregex/)] end end describe Puppet::Parser::Lexer, "when lexing comments" do before { @lexer = Puppet::Parser::Lexer.new } it "should accumulate token in munge_token" do token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"]) @lexer.munge_token(token, "# this is a comment") @lexer.munge_token(token, "# this is a comment") @lexer.getcomment.should == " this is a comment\n this is a comment\n" end it "should add a new comment stack level on LBRACE" do @lexer.string = "{" @lexer.expects(:commentpush) @lexer.fullscan end it "should return the current comments on getcomment" do @lexer.string = "# comment" @lexer.fullscan @lexer.getcomment.should == "comment\n" end it "should discard the previous comments on blank line" do @lexer.string = "# 1\n\n# 2" @lexer.fullscan @lexer.getcomment.should == "2\n" end it "should skip whitespace before lexing the next token after a non-token" do tokens_scanned_from("/* 1\n\n */ \ntest").should be_like([:NAME, "test"]) end it "should not return comments seen after the current line" do @lexer.string = "# 1\n\n# 2" @lexer.fullscan @lexer.getcomment(1).should == "" end it "should return a comment seen before the current line" do @lexer.string = "# 1\n# 2" @lexer.fullscan @lexer.getcomment(2).should == "1\n2\n" end end # FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now. describe "Puppet::Parser::Lexer in the old tests" do before { @lexer = Puppet::Parser::Lexer.new } it "should do simple lexing" do { %q{\\} => [[:BACKSLASH,"\\"]], %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"]], %Q{returned scanner test\n} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"]] }.each { |source,expected| tokens_scanned_from(source).should be_like(*expected) } end it "should fail usefully" do lambda { tokens_scanned_from('^') }.should raise_error(RuntimeError) end it "should fail if the string is not set" do lambda { @lexer.fullscan() }.should raise_error(Puppet::LexError) end it "should correctly identify keywords" do tokens_scanned_from("case").should be_like([:CASE, "case"]) end it "should correctly parse class references" do %w{Many Different Words A Word}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF,t])} end # #774 it "should correctly parse namespaced class refernces token" do %w{Foo ::Foo Foo::Bar ::Foo::Bar}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF, t]) } end it "should correctly parse names" do %w{this is a bunch of names}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } end it "should correctly parse names with numerals" do %w{1name name1 11names names11}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } end it "should correctly parse empty strings" do lambda { tokens_scanned_from('$var = ""') }.should_not raise_error end it "should correctly parse virtual resources" do tokens_scanned_from("@type {").should be_like([:AT, "@"], [:NAME, "type"], [:LBRACE, "{"]) end it "should correctly deal with namespaces" do @lexer.string = %{class myclass} @lexer.fullscan @lexer.namespace.should == "myclass" @lexer.namepop @lexer.namespace.should == "" @lexer.string = "class base { class sub { class more" @lexer.fullscan @lexer.namespace.should == "base::sub::more" @lexer.namepop @lexer.namespace.should == "base::sub" end it "should correctly handle fully qualified names" do @lexer.string = "class base { class sub::more {" @lexer.fullscan @lexer.namespace.should == "base::sub::more" @lexer.namepop @lexer.namespace.should == "base" end it "should correctly lex variables" do ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string| tokens_scanned_from(string).should be_like([:VARIABLE,string.sub(/^\$/,'')]) end end end require 'puppettest/support/utils' describe "Puppet::Parser::Lexer in the old tests when lexing example files" do extend PuppetTest extend PuppetTest::Support::Utils textfiles() do |file| it "should correctly lex #{file}" do lexer = Puppet::Parser::Lexer.new() lexer.file = file lambda { lexer.fullscan() }.should_not raise_error end end end diff --git a/spec/unit/parser/relationship.rb b/spec/unit/parser/relationship.rb new file mode 100644 index 000000000..bd4ff5632 --- /dev/null +++ b/spec/unit/parser/relationship.rb @@ -0,0 +1,70 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/parser/relationship' + +describe Puppet::Parser::Relationship do + before do + @source = Puppet::Resource.new(:mytype, "source") + @target = Puppet::Resource.new(:mytype, "target") + @dep = Puppet::Parser::Relationship.new(@source, @target, :relationship) + end + + describe "when evaluating" do + before do + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource(@source) + @catalog.add_resource(@target) + end + + it "should fail if the source resource cannot be found" do + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource @target + lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) + end + + it "should fail if the target resource cannot be found" do + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource @source + lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) + end + + it "should add the target as a 'before' value if the type is 'relationship'" do + @dep.type = :relationship + @dep.evaluate(@catalog) + @source[:before].should be_include("Mytype[target]") + end + + it "should add the target as a 'notify' value if the type is 'subscription'" do + @dep.type = :subscription + @dep.evaluate(@catalog) + @source[:notify].should be_include("Mytype[target]") + end + + it "should supplement rather than clobber existing relationship values" do + @source[:before] = "File[/bar]" + @dep.evaluate(@catalog) + @source[:before].should be_include("Mytype[target]") + @source[:before].should be_include("File[/bar]") + end + + it "should use the collected retargets if the target is a Collector" do + orig_target = @target + @target = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) + @target.collected[:foo] = @target + @dep.evaluate(@catalog) + + @source[:before].should be_include("Mytype[target]") + end + + it "should use the collected resources if the source is a Collector" do + orig_source = @source + @source = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) + @source.collected[:foo] = @source + @dep.evaluate(@catalog) + + orig_source[:before].should be_include("Mytype[target]") + end + end +end