summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-20 05:19:24 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-20 05:19:24 +0000
commit0747b4c34ee0aa2ba4430021c1c0e676f71c20ac (patch)
tree6ae5d78d8f31ce9a4121b2d0c4027aa1ca64a75c /lib/puppet/parser
parentd6982d59fc6db60a837967722ecd30f6c093547a (diff)
adding stinkloads of comments to ast.rb (I am trying to go through and better comment my code over time), refactoring some of the AST classes, and working towards a more sensible class/definition/node distinction
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@693 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/parser')
-rw-r--r--lib/puppet/parser/ast.rb435
-rw-r--r--lib/puppet/parser/grammar.ra43
-rw-r--r--lib/puppet/parser/parser.rb628
3 files changed, 590 insertions, 516 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 9b92d27c9..6f916c6bd 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -9,32 +9,42 @@
module Puppet
module Parser
class ASTError < RuntimeError; end
- #---------------------------------------------------------------
+
+ # 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 AST
Puppet.setdefault(:typecheck, true)
Puppet.setdefault(:paramcheck, true)
attr_accessor :line, :file, :parent
+ # Just used for 'tree', which is only used in debugging.
@@pink = ""
@@green = ""
@@yellow = ""
@@slate = ""
@@reset = ""
+ # Just used for 'tree', which is only used in debugging.
@@indent = " " * 4
@@indline = @@pink + ("-" * 4) + @@reset
@@midline = @@slate + ("-" * 4) + @@reset
@@settypes = {}
+ # Just used for 'tree', which is only used in debugging.
def AST.indention
return @@indent * @@indention
end
+ # Just used for 'tree', which is only used in debugging.
def AST.midline
return @@midline
end
+ # Evaluate the current object. Basically just iterates across all
+ # of the contained children and evaluates them in turn, returning a
+ # list of all of the collected values, rejecting nil values
def evaluate(scope)
#Puppet.debug("Evaluating ast %s" % @name)
value = self.collect { |obj|
@@ -44,6 +54,10 @@ module Puppet
}
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(*args)
begin
self.evaluate(*args)
@@ -64,6 +78,7 @@ module Puppet
end
end
+ # Again, just used for printing out the parse tree.
def typewrap(string)
#return self.class.to_s.sub(/.+::/,'') +
#"(" + @@green + string.to_s + @@reset + ")"
@@ -71,19 +86,15 @@ module Puppet
"(" + self.class.to_s.sub(/.+::/,'') + ")"
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)
- # this has to wait until all of the objects are defined
- unless defined? @@klassorder
- @@klassorder = [
- AST::VarDef, AST::TypeDefaults,
- AST::ObjectDef, AST::StatementArray
- ]
- end
-
args.each { |param,value|
method = param.to_s + "="
unless self.respond_to?(method)
- error = Puppet::ParseError.new(
+ error = Puppet::DevError.new(
"Invalid parameter %s to object class %s" %
[method,self.class.to_s]
)
@@ -107,50 +118,44 @@ module Puppet
}
end
- #---------------------------------------------------------------
- # this differentiation is used by the interpreter
- # these objects have children
+ # The parent class of all AST objects that contain other AST objects.
+ # Everything but the really simple objects descend from this. It is
+ # important to note that Branch objects contain other AST objects only --
+ # if you want to contain values, use a descendent of the AST::Leaf class.
class Branch < AST
include Enumerable
attr_accessor :pin, :children
+ # Yield each contained AST node in turn. Used mostly by 'evaluate'.
+ # This definition means that I don't have to override 'evaluate'
+ # every time, but each child of Branch will likely need to override
+ # this method.
def each
@children.each { |child|
yield child
}
end
- def evaluate(scope)
- self.collect { |item|
- item.safeevaluate(scope)
- }.reject { |obj|
- obj.nil
- }
- end
-
+ # Initialize our object. Largely relies on the method from the base
+ # class, but also does some verification.
def initialize(arghash)
super(arghash)
+ # Create the hash, if it was not set at initialization time.
unless defined? @children
@children = []
end
- #puts "children is '%s'" % [@children]
-
- self.each { |child|
- if child.class == Array
- error = Puppet::DevError.new(
- "child for %s(%s) is array" % [self.class,self.parent]
- )
- error.stack = caller
- raise error
- end
- unless child.nil?
- child.parent = self
+ # Verify that we only got valid AST nodes.
+ @children.each { |child|
+ unless child.is_a?(AST)
+ raise Puppet::DevError,
+ "child %s is not an ast" % child
end
}
end
+ # Pretty-print the parse tree.
def tree(indent = 0)
return ((@@indline * indent) +
self.typewrap(self.pin)) + "\n" + self.collect { |child|
@@ -158,25 +163,31 @@ module Puppet
}.join("\n")
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The basic container class. This object behaves almost identically
+ # to a normal array except at initialization time. Note that its name
+ # is 'AST::ASTArray', rather than plain 'AST::Array'; I had too many
+ # bugs when it was just 'AST::Array', because things like
+ # 'object.is_a?(Array)' never behaved as I expected.
class ASTArray < AST::Branch
include Enumerable
+ # Return a child by index. Probably never used.
def [](index)
@children[index]
end
+ # Evaluate our children.
def evaluate(scope)
rets = nil
+ # We basically always operate declaratively, and when we
+ # do we need to evaluate the settor-like statements first. This
+ # is basically variable and type-default declarations.
if scope.declarative
test = [
AST::VarDef, AST::TypeDefaults
]
- # if we're operating declaratively, then we want to get
- # all of our 'setting' operations done first
settors = []
others = []
@children.each { |child|
@@ -190,6 +201,7 @@ module Puppet
child.safeevaluate(scope)
}
else
+ # If we're not declarative, just do everything in order.
rets = @children.collect { |item|
item.safeevaluate(scope)
}
@@ -197,18 +209,6 @@ module Puppet
rets = rets.reject { |obj| obj.nil? }
end
- def initialize(hash)
- super(hash)
-
- @children.each { |child|
- unless child.is_a?(AST)
- raise Puppet::DevError,
- "child %s is not an ast" % child
- end
- }
- return self
- end
-
def push(*ary)
ary.each { |child|
#Puppet.debug "adding %s(%s) of type %s to %s" %
@@ -220,72 +220,40 @@ module Puppet
return self
end
+ # Convert to a string. Only used for printing the parse tree.
def to_s
return "[" + @children.collect { |child|
child.to_s
}.join(", ") + "]"
end
+ # Print the parse tree.
def tree(indent = 0)
#puts((AST.indent * indent) + self.pin)
self.collect { |child|
- if child.class == Array
- Puppet.debug "child is array for %s" % self.class
- end
child.tree(indent)
}.join("\n" + (AST.midline * (indent+1)) + "\n")
end
end
- #---------------------------------------------------------------
-
- #---------------------------------------------------------------
- class StatementArray < ASTArray
- def evaluate(scope)
- rets = nil
- if scope.declarative
- # if we're operating declaratively, then we want to get
- # all of our 'setting' operations done first
- rets = @children.sort { |a,b|
- [a,b].each { |i|
- unless @@klassorder.include?(i.class)
- error = Puppet::DevError.new(
- "Order not defined for %s" % i.class
- )
- error.stack = caller
- raise error
- end
- }
- @@klassorder.index(a.class) <=> @@klassorder.index(b.class)
- }.collect { |item|
- Puppet.debug "Decl evaluating %s" % item.class
- item.safeevaluate(scope)
- }.reject { |obj| obj.nil? }
- else
- rets = @children.collect { |item|
- item.safeevaluate(scope)
- }.reject { |obj| obj.nil? }
- end
-
- return rets
- end
- end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # A simple container class, containing the parameters for an object.
+ # Used for abstracting the grammar declarations. Basically unnecessary
+ # except that I kept finding bugs because I had too many arrays that
+ # meant completely different things.
class ObjectInst < ASTArray; end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # and these ones don't
+ # The base class for all of the leaves of the parse trees. These
+ # basically just have types and values. Both of these parameters
+ # are simple values, not AST objects.
class Leaf < AST
attr_accessor :value, :type
- # this only works if @value has already been evaluated
- # otherwise you get AST objects, which you don't likely want...
+ # Return our value.
def evaluate(scope)
return @value
end
+ # Print the value in parse tree context.
def tree(indent = 0)
return ((@@indent * indent) + self.typewrap(self.value))
end
@@ -294,10 +262,12 @@ module Puppet
return @value
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The boolean class. True or false. Converts the string it receives
+ # to a Ruby boolean.
class Boolean < AST::Leaf
+
+ # Use the parent method, but then convert to a real boolean.
def initialize(hash)
super
@@ -314,45 +284,35 @@ module Puppet
@value = false
end
end
-
- def evaluate(scope)
- return @value
- end
-
- def to_s
- return @value
- end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The base string class.
class String < AST::Leaf
+ # Interpolate the string looking for variables, and then return
+ # the result.
def evaluate(scope)
return scope.strinterp(@value)
end
end
#---------------------------------------------------------------
- #---------------------------------------------------------------
- class Word < AST::Leaf; end
- #---------------------------------------------------------------
-
- #---------------------------------------------------------------
+ # The 'default' option on case statements and selectors.
class Default < AST::Leaf; end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # Capitalized words; used mostly for type-defaults, but also
+ # get returned by the lexer any other time an unquoted capitalized
+ # word is found.
class Type < AST::Leaf; end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # Lower-case words.
class Name < AST::Leaf; end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- class Variable < Word
+ # A simple variable. This object is only used during interpolation;
+ # the VarDef class is used for assignment.
+ class Variable < Name
+ # Looks up the value of the object in the scope tree (does
+ # not include syntactical constructs, like '$' and '{}').
def evaluate(scope)
- # look up the variable value in the symbol table
begin
return scope.lookupvar(@value)
rescue Puppet::ParseError => except
@@ -368,32 +328,37 @@ module Puppet
end
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # Any normal puppet object declaration. Can result in a class or a
+ # component, in addition to builtin types.
class ObjectDef < AST::Branch
attr_accessor :name, :type
attr_reader :params
+ # probably not used at all
def []=(index,obj)
@params[index] = obj
end
+ # probably not used at all
def [](index)
return @params[index]
end
+ # Iterate across all of our children.
def each
- #Puppet.debug("each called on %s" % self)
[@type,@name,@params].flatten.each { |param|
#Puppet.debug("yielding param %s" % param)
yield param
}
end
+ # Does not actually return an object; instead sets an object
+ # in the current scope.
def evaluate(scope)
hash = {}
+ # Get our type and name.
objtype = @type.safeevaluate(scope)
objnames = @name.safeevaluate(scope)
@@ -401,11 +366,12 @@ module Puppet
begin
defaults = scope.lookupdefaults(objtype)
rescue => detail
- error = Puppet::DevError.new(
+ raise Puppet::DevError,
"Could not lookup defaults for %s: %s" %
[objtype, detail.to_s]
- )
end
+
+ # Add any found defaults to our argument list
defaults.each { |var,value|
Puppet.debug "Found default %s for %s" %
[var,objtype]
@@ -424,6 +390,7 @@ module Puppet
objnames = [objnames]
end
+ # See if our object was defined
begin
object = scope.lookuptype(objtype)
rescue Puppet::ParseError => except
@@ -438,10 +405,12 @@ module Puppet
raise error
end
+ # If not, verify that it's a builtin type
unless object
begin
Puppet::Type.type(objtype)
rescue TypeError
+ # otherwise, the user specified an invalid type
error = Puppet::ParseError.new(
"Invalid type %s" % objtype
)
@@ -490,6 +459,7 @@ module Puppet
}.reject { |obj| obj.nil? }
end
+ # Create our ObjectDef. Handles type checking for us.
def initialize(hash)
super
@@ -508,13 +478,11 @@ module Puppet
end
if builtin
# we're a builtin type
- #Puppet.debug "%s is a builtin type" % objtype
# like :typecheck, this always defaults to on, but
# at least it's easy to turn off if necessary
if Puppet[:paramcheck]
+ # Verify that each param is valid
@params.each { |param|
- #p self.name
- #p @params
unless param.is_a?(AST::ObjectParam)
raise Puppet::DevError,
"Got something other than param"
@@ -537,11 +505,14 @@ module Puppet
end
}
end
+ # Find the defined type and verify arguments are valid.
# FIXME this should use scoping rules to find the set type,
# not a global list
elsif @@settypes.include?(objtype)
# we've defined it locally
Puppet.debug "%s is a defined type" % objtype
+
+ # this is somewhat hackish, using a global type list...
type = @@settypes[objtype]
@params.each { |param|
# FIXME we might need to do more here eventually...
@@ -578,6 +549,7 @@ module Puppet
end
end
+ # Set the parameters for our object.
def params=(params)
if params.is_a?(AST::ASTArray)
@params = params
@@ -590,6 +562,7 @@ module Puppet
end
end
+ # Print this object out.
def tree(indent = 0)
return [
@type.tree(indent + 1),
@@ -618,20 +591,20 @@ module Puppet
]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # A reference to an object. Only valid as an rvalue.
class ObjectRef < AST::Branch
attr_accessor :name, :type
def each
- #Puppet.debug("each called on %s" % self)
[@type,@name].flatten.each { |param|
#Puppet.debug("yielding param %s" % param)
yield param
}
end
+ # Evaluate our object, but just return a simple array of the type
+ # and name.
def evaluate(scope)
objtype = @type.safeevaluate(scope)
objnames = @name.safeevaluate(scope)
@@ -641,6 +614,7 @@ module Puppet
objnames = [objnames]
end
+ # Verify we can find the object.
begin
object = scope.lookuptype(objtype)
rescue Puppet::ParseError => except
@@ -679,9 +653,8 @@ module Puppet
return "%s[%s]" % [@name,@type]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The AST object for the parameters inside ObjectDefs and Selectors.
class ObjectParam < AST::Branch
attr_accessor :value, :param
@@ -689,6 +662,7 @@ module Puppet
[@param,@value].each { |child| yield child }
end
+ # Return the parameter and the value.
def evaluate(scope)
param = @param.safeevaluate(scope)
value = @value.safeevaluate(scope)
@@ -707,32 +681,31 @@ module Puppet
return "%s => %s" % [@param,@value]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The basic logical structure in Puppet. Supports a list of
+ # tests and statement arrays.
class CaseStatement < AST::Branch
attr_accessor :test, :options, :default
- # 'if' is a bit special, since we don't want to continue
- # evaluating if a test turns up true
+ # Short-curcuit evaluation. Return the value of the statements for
+ # the first option that matches.
def evaluate(scope)
value = @test.safeevaluate(scope)
retvalue = nil
found = false
- default = nil
+
+ # Iterate across the options looking for a match.
@options.each { |option|
- if option.eachvalue { |opval|
- if opval == value
- break true
- end
- }
+ if option.eachvalue { |opval| break true if opval == value }
# we found a matching option
retvalue = option.safeevaluate(scope)
+ found = true
break
end
}
+ # Unless we found something, look for the default.
unless found
if defined? @default
retvalue = @default.safeevaluate(scope)
@@ -743,6 +716,7 @@ module Puppet
return retvalue
end
+ # Do some input validation on our options.
def initialize(hash)
values = {}
@@ -780,9 +754,8 @@ module Puppet
[@test,@options].each { |child| yield child }
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # Each individual option in a case statement.
class CaseOpt < AST::Branch
attr_accessor :value, :statements
@@ -790,6 +763,11 @@ module Puppet
# so that CaseStatement can compare, and then it will selectively
# decide whether to fully evaluate this option
+ def each
+ [@value,@statements].each { |child| yield child }
+ end
+
+ # Are we the default option?
def default?
if defined? @default
return @default
@@ -815,6 +793,7 @@ module Puppet
return @default
end
+ # You can specify a list of values; return each in turn.
def eachvalue
if @value.is_a?(AST::ASTArray)
@value.each { |subval|
@@ -825,6 +804,8 @@ module Puppet
end
end
+ # Evaluate the actual statements; this only gets called if
+ # our option matched.
def evaluate(scope)
return @statements.safeevaluate(scope.newscope)
end
@@ -837,42 +818,50 @@ module Puppet
]
return rettree.flatten.join("\n")
end
-
- def each
- [@value,@statements].each { |child| yield child }
- end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # The inline conditional operator. Unlike CaseStatement, which executes
+ # code, we just return a value.
class Selector < AST::Branch
- attr_accessor :param, :value
+ attr_accessor :param, :values
- # okay, here's a decision point...
- def evaluate(scope)
- # retrieve our values and make them a touch easier to manage
- hash = Hash[*(@value.safeevaluate(scope).flatten)]
+ def each
+ [@param,@values].each { |child| yield child }
+ end
+ # Find the value that corresponds with the test.
+ def evaluate(scope)
retvalue = nil
+ found = nil
+ # Get our parameter.
paramvalue = @param.safeevaluate(scope)
- retvalue = hash.detect { |test,value|
- # FIXME this will return variables named 'default'...
- if paramvalue == test
- break value
+ default = nil
+
+ # Then look for a match in the options.
+ @values.each { |obj|
+ param = obj.param.safeevaluate(scope)
+ if param == paramvalue
+ # we found a matching option
+ retvalue = obj.value.safeevaluate(scope)
+ found = true
+ break
+ elsif obj.param.is_a?(Default)
+ default = obj
end
}
- if retvalue.nil?
- if hash.include?("default")
- return hash["default"]
+
+ # Unless we found something, look for the default.
+ unless found
+ if default
+ retvalue = default.value.safeevaluate(scope)
else
error = Puppet::ParseError.new(
"No value for selector param '%s'" % paramvalue
)
error.line = self.line
error.file = self.file
- error.stack = self.stack
raise error
end
end
@@ -884,20 +873,17 @@ module Puppet
return [
@param.tree(indent + 1),
((@@indline * indent) + self.typewrap(self.pin)),
- @value.tree(indent + 1)
+ @values.tree(indent + 1)
].join("\n")
end
-
- def each
- [@param,@value].each { |child| yield child }
- end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # Define a variable. Stores the value in the current scope.
class VarDef < AST::Branch
attr_accessor :name, :value
+ # Look up our name and value, and store them appropriately. The
+ # lexer strips off the syntax stuff like '$'.
def evaluate(scope)
name = @name.safeevaluate(scope)
value = @value.safeevaluate(scope)
@@ -934,9 +920,9 @@ module Puppet
return "%s => %s" % [@name,@value]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
+ # A statement syntactically similar to an ObjectDef, but uses a
+ # capitalized object type and cannot have a name.
class TypeDefaults < AST::Branch
attr_accessor :type, :params
@@ -944,14 +930,12 @@ module Puppet
[@type,@params].each { |child| yield child }
end
+ # As opposed to ObjectDef, this stores each default for the given
+ # object type.
def evaluate(scope)
type = @type.safeevaluate(scope)
params = @params.safeevaluate(scope)
- #Puppet.info "Params are %s" % params.inspect
- #Puppet.debug("evaluating '%s.%s' with values [%s]" %
- # [type,name,values])
- # okay, now i need the interpreter's client object thing...
begin
scope.setdefaults(type.downcase,params)
rescue Puppet::ParseError => except
@@ -979,10 +963,15 @@ module Puppet
return "%s { %s }" % [@type,@params]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # these are analogous to defining new object types
+ # Define a new component. This basically just stores the associated parse
+ # tree by name in our current scope. Note that there is currently
+ # a mismatch in how we look up components -- it usually uses scopes, but
+ # sometimes uses '@@settypes'.
+ # FIXME This class should verify that each of its direct children
+ # has an abstractable name -- i.e., if a file does not include a variable
+ # in its name, then the user is essentially guaranteed to encounter
+ # an error if the component is instantiated more than once.
class CompDef < AST::Branch
attr_accessor :name, :args, :code
@@ -990,17 +979,11 @@ module Puppet
[@name,@args,@code].each { |child| yield child }
end
+ # Store the parse tree.
def evaluate(scope)
name = @name.safeevaluate(scope)
args = @args.safeevaluate(scope)
- #Puppet.debug("defining '%s' with arguments [%s]" %
- # [name,args])
- #p @args
- #p args
- # okay, now i need to evaluate all of the statements
- # within a component and a new lexical scope...
-
begin
scope.settype(name,
AST::Component.new(
@@ -1023,6 +1006,7 @@ module Puppet
end
def initialize(hash)
+ @parentclass = nil
super
Puppet.debug "Defining type %s" % @name.value
@@ -1048,6 +1032,8 @@ module Puppet
return "define %s(%s) {\n%s }" % [@name, @args, @code]
end
+ # Check whether a given argument is valid. Searches up through
+ # any parent classes that might exist.
def validarg?(param)
found = false
if @args.is_a?(AST::ASTArray)
@@ -1082,10 +1068,10 @@ module Puppet
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # these are analogous to defining new object types
+ # Define a new class. Syntactically similar to component definitions,
+ # but classes are always singletons -- only one can exist on a given
+ # host.
class ClassDef < AST::CompDef
attr_accessor :parentclass
@@ -1097,6 +1083,7 @@ module Puppet
end
end
+ # Store our parse tree according to name.
def evaluate(scope)
name = @name.safeevaluate(scope)
args = @args.safeevaluate(scope)
@@ -1117,27 +1104,17 @@ module Puppet
# [name,args])
begin
+ arghash = {
+ :name => name,
+ :args => args,
+ :code => @code
+ }
if parent
- scope.settype(name,
- HostClass.new(
- :name => name,
- :args => args,
- :parentclass => parent,
- :code => @code
- )
- )
- else
- scope.settype(name,
- HostClass.new(
- :name => name,
- :args => args,
- :code => @code
- )
- )
+ arghash[:parentclass] = parent
end
- #scope.settype(name,
- # HostClass.new(arghash)
- #)
+ scope.settype(name,
+ HostClass.new(arghash)
+ )
rescue Puppet::ParseError => except
except.line = self.line
except.file = self.file
@@ -1161,7 +1138,7 @@ module Puppet
@name.tree(indent + 1),
((@@indline * 4 * indent) + self.typewrap("class")),
@args.tree(indent + 1),
- @parentclass.tree(indent + 1),
+ @parentclass ? @parentclass.tree(indent + 1) : "",
@code.tree(indent + 1),
].join("\n")
end
@@ -1171,11 +1148,10 @@ module Puppet
[@name, @args, @parentclass, @code]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # host definitions are special, because they get called when a host
- # whose name matches connects
+ # Define a node. The node definition stores a parse tree for each
+ # specified node, and this parse tree is only ever looked up when
+ # a client connects.
class NodeDef < AST::Branch
attr_accessor :names, :code
@@ -1183,6 +1159,7 @@ module Puppet
[@names,@code].each { |child| yield child }
end
+ # Do implicit iteration over each of the names passed.
def evaluate(scope)
names = @names.safeevaluate(scope)
@@ -1194,7 +1171,7 @@ module Puppet
names.each { |name|
begin
scope.sethost(name,
- Host.new(
+ Node.new(
:name => name,
:code => @code
)
@@ -1225,11 +1202,10 @@ module Puppet
return "host %s {\n%s }" % [@name, @code]
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # this is not really an AST node; it's just a placeholder
- # for a bunch of AST code to evaluate later
+ # Evaluate the stored parse tree for a given component. This will
+ # receive the arguments passed to the component and also the type and
+ # name of the component.
class Component < AST::Branch
attr_accessor :name, :args, :code
@@ -1240,7 +1216,11 @@ module Puppet
# define all of the arguments in our local scope
if self.args
- #Puppet.debug "args are %s" % self.args.inspect
+
+ # Verify that all required arguments are either present or
+ # have been provided with defaults.
+ # FIXME This should probably also require each parent class's
+ # arguments...
self.args.each { |arg, default|
unless hash.include?(arg)
if defined? default
@@ -1259,6 +1239,8 @@ module Puppet
}
end
+ # Set each of the provided arguments as variables in the
+ # component's scope.
hash["name"] = objname
hash.each { |arg,value|
begin
@@ -1280,15 +1262,14 @@ module Puppet
end
}
- # now just evaluate the code with our new bindings
+ # Now just evaluate the code with our new bindings.
self.code.safeevaluate(scope)
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # this is not really an AST node; it's just a placeholder
- # for a bunch of AST code to evaluate later
+ # The code associated with a class. This is different from components
+ # in that each class is a singleton -- only one will exist for a given
+ # node.
class HostClass < AST::Component
attr_accessor :parentclass
@@ -1308,7 +1289,8 @@ module Puppet
end
unless parentobj
error = Puppet::ParseError.new(
- "Could not find parent '%s' of '%s'" % [@parentclass,@name])
+ "Could not find parent '%s' of '%s'" %
+ [@parentclass,@name])
error.line = self.line
error.file = self.file
raise error
@@ -1329,12 +1311,9 @@ module Puppet
end
end
- #---------------------------------------------------------------
- #---------------------------------------------------------------
- # this is not really an AST node; it's just a placeholder
- # for a bunch of AST code to evaluate later
- class Host < AST::Component
+ # The specific code associated with a host.
+ class Node < AST::Component
attr_accessor :name, :args, :code, :parentclass
def evaluate(scope,hash,objtype,objname)
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 8f9b713f2..2b183539b 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -60,6 +60,7 @@ statement: object
| import
| definition
| hostclass
+ | nodedef
#object: name LBRACE objectname COLON params endcomma RBRACE {
object: name LBRACE objectinstances endsemi RBRACE {
@@ -339,7 +340,7 @@ selector: variable QMARK svalues {
:line => @lexer.line,
:file => @lexer.file,
:param => val[0],
- :value => val[2]
+ :values => val[2]
)
}
@@ -457,18 +458,44 @@ hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE {
}
# It'll be an ASTArray if we didn't get a parent
if val[3].is_a?(AST::Name)
- Puppet.notice "Assigning parent of %s as %s" % [val[1], val[3].value]
args[:parentclass] = val[3]
end
result = AST::ClassDef.new(args)
}
-#nodedef: NODE words LBRACE statements RBRACE {
-# result = AST::NodeDef.new(
-# :names => val[1],
-# :code => val[3]
-# )
-#}
+nodedef: NODE names parent LBRACE statements RBRACE {
+ unless val[1].is_a?(AST::ASTArray)
+ val[1] = AST::ASTArray.new(
+ :line => val[1].line,
+ :file => val[1].file,
+ :children => [val[1]]
+ )
+ end
+ args = {
+ :file => @lexer.file,
+ :line => @lexer.line,
+ :names => val[1],
+ :code => val[4]
+ }
+ if val[3].is_a?(AST::Name)
+ args[:parentclass] = val[2]
+ end
+ result = AST::NodeDef.new(args)
+}
+
+names: name
+ | names name {
+ if val[0].is_a?(AST::ASTArray)
+ result = val[0]
+ result.push val[1]
+ else
+ result = AST::ASTArray.new(
+ :line => @lexer.line,
+ :file => @lexer.file,
+ :children => [val[0], val[1]]
+ )
+ end
+}
nothing: {
result = AST::ASTArray.new(
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index 330609d46..2f0c4f10c 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -31,7 +31,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..id29ad235e83', 'grammar.ra', 579
+module_eval <<'..end grammar.ra modeval..id68a1b36c80', 'grammar.ra', 606
attr_writer :stack
attr_reader :file
@@ -135,7 +135,7 @@ end
def string=(string)
@lexer.string = string
end
-..end grammar.ra modeval..id29ad235e83
+..end grammar.ra modeval..id68a1b36c80
##### racc 1.4.4 generates ###
@@ -150,205 +150,229 @@ racc_reduce_table = [
1, 42, :_reduce_none,
1, 42, :_reduce_none,
1, 42, :_reduce_none,
- 5, 43, :_reduce_10,
+ 1, 42, :_reduce_none,
5, 43, :_reduce_11,
5, 43, :_reduce_12,
- 3, 55, :_reduce_13,
- 1, 50, :_reduce_none,
- 3, 50, :_reduce_15,
- 0, 51, :_reduce_none,
+ 5, 43, :_reduce_13,
+ 3, 56, :_reduce_14,
1, 51, :_reduce_none,
- 1, 49, :_reduce_18,
- 1, 54, :_reduce_19,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 3, 44, :_reduce_26,
- 0, 52, :_reduce_27,
- 1, 52, :_reduce_28,
- 3, 52, :_reduce_29,
- 3, 62, :_reduce_30,
- 1, 63, :_reduce_none,
- 3, 63, :_reduce_32,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 57, :_reduce_42,
- 1, 65, :_reduce_43,
- 4, 66, :_reduce_44,
- 5, 45, :_reduce_45,
- 1, 67, :_reduce_none,
- 2, 67, :_reduce_47,
- 5, 68, :_reduce_48,
- 1, 69, :_reduce_none,
- 3, 69, :_reduce_50,
- 3, 58, :_reduce_51,
- 1, 71, :_reduce_none,
- 3, 71, :_reduce_53,
- 1, 73, :_reduce_none,
- 3, 73, :_reduce_55,
- 3, 72, :_reduce_56,
- 1, 70, :_reduce_57,
- 1, 70, :_reduce_58,
- 1, 70, :_reduce_59,
- 1, 70, :_reduce_60,
+ 3, 51, :_reduce_16,
+ 0, 52, :_reduce_none,
+ 1, 52, :_reduce_none,
+ 1, 50, :_reduce_19,
+ 1, 55, :_reduce_20,
+ 1, 57, :_reduce_none,
+ 1, 57, :_reduce_none,
+ 1, 57, :_reduce_none,
+ 1, 57, :_reduce_none,
+ 1, 57, :_reduce_none,
+ 1, 57, :_reduce_none,
+ 3, 44, :_reduce_27,
+ 0, 53, :_reduce_28,
+ 1, 53, :_reduce_29,
+ 3, 53, :_reduce_30,
+ 3, 63, :_reduce_31,
+ 1, 64, :_reduce_none,
+ 3, 64, :_reduce_33,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 62, :_reduce_none,
+ 1, 58, :_reduce_43,
+ 1, 66, :_reduce_44,
+ 4, 67, :_reduce_45,
+ 5, 45, :_reduce_46,
+ 1, 68, :_reduce_none,
+ 2, 68, :_reduce_48,
+ 5, 69, :_reduce_49,
1, 70, :_reduce_none,
- 2, 46, :_reduce_62,
- 6, 47, :_reduce_63,
- 7, 48, :_reduce_64,
- 0, 76, :_reduce_65,
+ 3, 70, :_reduce_51,
+ 3, 59, :_reduce_52,
+ 1, 72, :_reduce_none,
+ 3, 72, :_reduce_54,
1, 74, :_reduce_none,
- 3, 74, :_reduce_67,
- 3, 74, :_reduce_68,
+ 3, 74, :_reduce_56,
+ 3, 73, :_reduce_57,
+ 1, 71, :_reduce_58,
+ 1, 71, :_reduce_59,
+ 1, 71, :_reduce_60,
+ 1, 71, :_reduce_61,
+ 1, 71, :_reduce_none,
+ 2, 46, :_reduce_63,
+ 6, 47, :_reduce_64,
+ 7, 48, :_reduce_65,
+ 6, 49, :_reduce_66,
1, 77, :_reduce_none,
- 3, 77, :_reduce_70,
- 3, 78, :_reduce_71,
- 1, 78, :_reduce_72,
+ 2, 77, :_reduce_68,
+ 0, 78, :_reduce_69,
1, 75, :_reduce_none,
- 2, 75, :_reduce_74,
- 1, 59, :_reduce_75,
- 3, 60, :_reduce_76,
- 1, 64, :_reduce_none,
- 1, 64, :_reduce_none,
- 0, 53, :_reduce_none,
- 1, 53, :_reduce_80 ]
-
-racc_reduce_n = 81
-
-racc_shift_n = 136
+ 3, 75, :_reduce_71,
+ 3, 75, :_reduce_72,
+ 1, 79, :_reduce_none,
+ 3, 79, :_reduce_74,
+ 3, 80, :_reduce_75,
+ 1, 80, :_reduce_76,
+ 1, 76, :_reduce_none,
+ 2, 76, :_reduce_78,
+ 1, 60, :_reduce_79,
+ 3, 61, :_reduce_80,
+ 1, 65, :_reduce_none,
+ 1, 65, :_reduce_none,
+ 0, 54, :_reduce_none,
+ 1, 54, :_reduce_84 ]
+
+racc_reduce_n = 85
+
+racc_shift_n = 145
racc_action_table = [
- 77, 100, 80, 112, 48, 77, 91, 99, 4, 7,
- 77, 11, 13, 110, 126, 77, 72, 73, 2, 5,
- 77, 9, 93, 47, 95, 77, 36, 111, 31, 22,
- 24, 75, 76, 31, 90, 79, 75, 76, 31, 93,
- 79, 75, 76, 31, 90, 79, 75, 76, 31, 101,
- 79, 75, 76, 31, 27, 79, 75, 76, 31, 102,
- 79, 2, 5, 22, 24, 22, 24, 71, 22, 24,
- 5, 72, 73, 64, 22, 24, 105, 63, 108, 22,
- 24, 41, 40, 64, 22, 24, 46, 89, 27, 116,
- 27, 64, 31, 27, 31, 2, 5, 2, 5, 27,
- 2, 53, 118, 31, 27, 46, 2, 5, 31, 27,
- 120, 2, 5, 31, 22, 24, 2, 5, 121, 22,
- 24, 5, 41, 40, 22, 24, 38, 70, 128, 37,
- 130, 36, 35, 20, 64, 19, 119, nil, nil, 27,
- 135, nil, nil, nil, 27, 124, 2, 5, 31, 27,
- nil, 2, 5, 31, nil, nil, 2, 5, 4, 7,
- 134, 11, 13, 4, 7, nil, 11, 13, 2, 5,
- nil, 9, nil, 2, 5, nil, 9, nil, 4, 7,
- nil, 11, 13, 4, 7, nil, 11, 13, 2, 5,
- nil, 9, nil, 2, 5, nil, 9, 4, 7, nil,
- 11, 13, 4, 7, nil, 11, 13, 2, 5, nil,
- 9, nil, 2, 5, nil, 9, 4, 7, nil, 11,
- 13, nil, nil, nil, nil, nil, 2, 5, nil, 9 ]
+ 89, 123, 89, 72, 49, 101, 53, 112, 89, 6,
+ 89, 121, 92, 111, 54, 82, 89, 40, 89, 83,
+ 84, 134, 102, 83, 84, 122, 75, 105, 36, 106,
+ 36, 87, 88, 87, 88, 90, 36, 90, 36, 87,
+ 88, 87, 88, 90, 36, 90, 36, 87, 88, 87,
+ 88, 90, 21, 90, 27, 28, 27, 28, 45, 109,
+ 110, 72, 113, 53, 74, 27, 28, 27, 28, 116,
+ 27, 28, 45, 119, 55, 81, 27, 28, 124, 31,
+ 45, 31, 6, 36, 127, 36, 3, 6, 3, 6,
+ 31, 128, 31, 6, 36, 31, 36, 3, 6, 3,
+ 6, 31, 3, 60, 6, 36, 27, 28, 3, 6,
+ 41, 27, 28, 40, 39, 75, 27, 28, 136, 38,
+ 74, 27, 28, 139, 23, 22, 69, 21, 45, 49,
+ nil, 31, nil, nil, nil, 36, 31, 132, 3, 6,
+ 36, 31, nil, 3, 6, 36, 31, nil, 3, 6,
+ nil, 140, nil, 3, 6, 5, 8, nil, 12, 14,
+ nil, 17, nil, nil, nil, 3, 6, 143, 10, 5,
+ 8, nil, 12, 14, nil, 17, nil, nil, nil, 3,
+ 6, 144, 10, nil, nil, 5, 8, nil, 12, 14,
+ nil, 17, nil, nil, nil, 3, 6, nil, 10, 5,
+ 8, nil, 12, 14, nil, 17, nil, nil, nil, 3,
+ 6, nil, 10, 5, 8, nil, 12, 14, nil, 17,
+ nil, nil, nil, 3, 6, nil, 10, 5, 8, nil,
+ 12, 14, nil, 17, nil, nil, nil, 3, 6, nil,
+ 10, 5, 8, nil, 12, 14, nil, 17, nil, nil,
+ nil, 3, 6, nil, 10, 5, 8, nil, 12, 14,
+ nil, 17, nil, nil, nil, 3, 6, nil, 10, 5,
+ 8, nil, 12, 14, nil, 17, nil, nil, nil, 3,
+ 6, nil, 10, 5, 8, nil, 12, 14, nil, 17,
+ nil, nil, nil, 3, 6, nil, 10 ]
racc_action_check = [
- 46, 66, 46, 87, 30, 48, 58, 66, 120, 120,
- 85, 120, 120, 85, 107, 112, 107, 107, 120, 120,
- 127, 120, 60, 29, 62, 80, 29, 87, 46, 105,
- 105, 46, 46, 48, 64, 46, 48, 48, 85, 65,
- 48, 85, 85, 112, 53, 85, 112, 112, 127, 68,
- 112, 127, 127, 80, 105, 127, 80, 80, 105, 69,
- 80, 105, 105, 9, 9, 74, 74, 45, 36, 36,
- 41, 45, 45, 40, 101, 101, 78, 38, 84, 22,
- 22, 37, 34, 89, 35, 35, 55, 51, 9, 92,
- 74, 93, 9, 36, 74, 9, 9, 74, 74, 101,
- 36, 36, 94, 101, 22, 26, 101, 101, 22, 35,
- 96, 22, 22, 35, 91, 91, 35, 35, 98, 90,
- 90, 100, 20, 17, 47, 47, 14, 42, 111, 13,
- 113, 12, 11, 7, 130, 4, 95, nil, nil, 91,
- 133, nil, nil, nil, 90, 103, 91, 91, 90, 47,
- nil, 90, 90, 47, nil, nil, 47, 47, 133, 133,
- 131, 133, 133, 103, 103, nil, 103, 103, 133, 133,
- nil, 133, nil, 103, 103, nil, 103, nil, 131, 131,
- nil, 131, 131, 70, 70, nil, 70, 70, 131, 131,
- nil, 131, nil, 70, 70, nil, 70, 15, 15, nil,
- 15, 15, 128, 128, nil, 128, 128, 15, 15, nil,
- 15, nil, 128, 128, nil, 128, 0, 0, nil, 0,
- 0, nil, nil, nil, nil, nil, 0, 0, nil, 0 ]
+ 135, 98, 92, 42, 23, 61, 64, 78, 96, 42,
+ 53, 96, 53, 78, 34, 52, 55, 34, 123, 52,
+ 52, 118, 67, 118, 118, 98, 68, 72, 135, 73,
+ 92, 135, 135, 92, 92, 135, 96, 92, 53, 96,
+ 96, 53, 53, 96, 55, 53, 123, 55, 55, 123,
+ 123, 55, 25, 123, 54, 54, 116, 116, 75, 76,
+ 77, 57, 80, 32, 60, 113, 113, 10, 10, 91,
+ 40, 40, 21, 95, 35, 50, 38, 38, 100, 54,
+ 101, 116, 17, 54, 103, 116, 54, 54, 116, 116,
+ 113, 104, 10, 49, 113, 40, 10, 113, 113, 10,
+ 10, 38, 40, 40, 112, 38, 85, 85, 38, 38,
+ 16, 74, 74, 15, 14, 47, 27, 27, 122, 12,
+ 45, 102, 102, 125, 8, 5, 41, 1, 139, 39,
+ nil, 85, nil, nil, nil, 85, 74, 114, 85, 85,
+ 74, 27, nil, 74, 74, 27, 102, nil, 27, 27,
+ nil, 129, nil, 102, 102, 114, 114, nil, 114, 114,
+ nil, 114, nil, nil, nil, 114, 114, 138, 114, 129,
+ 129, nil, 129, 129, nil, 129, nil, nil, nil, 129,
+ 129, 142, 129, nil, nil, 138, 138, nil, 138, 138,
+ nil, 138, nil, nil, nil, 138, 138, nil, 138, 142,
+ 142, nil, 142, 142, nil, 142, nil, nil, nil, 142,
+ 142, nil, 142, 0, 0, nil, 0, 0, nil, 0,
+ nil, nil, nil, 0, 0, nil, 0, 18, 18, nil,
+ 18, 18, nil, 18, nil, nil, nil, 18, 18, nil,
+ 18, 124, 124, nil, 124, 124, nil, 124, nil, nil,
+ nil, 124, 124, nil, 124, 81, 81, nil, 81, 81,
+ nil, 81, nil, nil, nil, 81, 81, nil, 81, 136,
+ 136, nil, 136, 136, nil, 136, nil, nil, nil, 136,
+ 136, nil, 136, 106, 106, nil, 106, 106, nil, 106,
+ nil, nil, nil, 106, 106, nil, 106 ]
racc_action_pointer = [
- 192, nil, nil, nil, 132, nil, nil, 98, nil, 61,
- nil, 120, 126, 94, 126, 173, nil, 118, nil, nil,
- 108, nil, 77, nil, nil, nil, 92, nil, nil, 21,
- -1, nil, nil, nil, 77, 82, 66, 67, 77, nil,
- 38, 35, 122, nil, nil, 63, -3, 122, 2, nil,
- nil, 54, nil, 36, nil, 73, nil, nil, -30, nil,
- 13, nil, -5, nil, 26, 30, -8, nil, 37, 44,
- 159, nil, nil, nil, 63, nil, nil, nil, 68, nil,
- 22, nil, nil, nil, 74, 7, nil, -6, nil, 48,
- 117, 112, 83, 56, 96, 101, 105, nil, 112, nil,
- 86, 72, nil, 139, nil, 27, nil, 8, nil, nil,
- nil, 123, 12, 121, nil, nil, nil, nil, nil, nil,
- -16, nil, nil, nil, nil, nil, nil, 17, 178, nil,
- 99, 154, nil, 134, nil, nil ]
+ 189, 122, nil, nil, nil, 122, nil, nil, 89, nil,
+ 65, nil, 107, nil, 79, 108, 110, 47, 203, nil,
+ nil, 37, nil, -10, nil, 47, nil, 114, nil, nil,
+ nil, nil, 50, nil, 12, 69, nil, nil, 74, 115,
+ 68, 126, -26, nil, nil, 112, nil, 106, nil, 58,
+ 70, nil, 11, 7, 52, 13, nil, 32, nil, nil,
+ 56, -28, nil, nil, -7, nil, nil, -14, 17, nil,
+ nil, nil, -8, 24, 109, 23, 53, 45, -2, nil,
+ 50, 231, nil, nil, nil, 104, nil, nil, nil, nil,
+ nil, 61, -1, nil, nil, 69, 5, nil, -8, nil,
+ 73, 45, 119, 78, 85, nil, 259, nil, nil, nil,
+ nil, nil, 69, 63, 131, nil, 54, nil, 15, nil,
+ nil, nil, 113, 15, 217, 114, nil, nil, nil, 145,
+ nil, nil, nil, nil, nil, -3, 245, nil, 161, 93,
+ nil, nil, 175, nil, nil ]
racc_action_default = [
- -81, -5, -19, -6, -81, -18, -7, -81, -8, -81,
- -9, -81, -81, -81, -81, -1, -2, -81, -4, -62,
- -65, -41, -81, -33, -42, -37, -39, -75, -40, -34,
- -81, -43, -38, -36, -35, -81, -27, -65, -81, -3,
- -27, -65, -81, -66, -31, -81, -81, -81, -81, -26,
- -14, -81, -20, -18, -23, -24, -25, -21, -16, -28,
- -79, -22, -65, 136, -81, -79, -81, -69, -72, -81,
- -81, -76, -77, -78, -81, -58, -57, -59, -81, -60,
- -81, -51, -52, -61, -81, -81, -46, -81, -49, -27,
- -81, -17, -81, -80, -81, -81, -81, -73, -81, -68,
- -81, -81, -67, -81, -32, -81, -54, -81, -44, -47,
- -45, -81, -81, -13, -30, -15, -10, -29, -11, -74,
- -81, -12, -70, -71, -63, -56, -53, -81, -81, -50,
- -81, -81, -55, -81, -64, -48 ]
+ -85, -85, -5, -20, -6, -85, -19, -7, -85, -8,
+ -85, -9, -85, -10, -85, -85, -85, -85, -1, -2,
+ -4, -28, -63, -69, -37, -36, -42, -85, -43, -34,
+ -38, -79, -40, -41, -35, -85, -44, -39, -85, -69,
+ -28, -85, -69, -67, -3, -85, -29, -83, -70, -69,
+ -85, -32, -85, -85, -85, -85, -27, -69, -23, -15,
+ -19, -85, -21, -24, -25, -26, -22, -17, -83, 145,
+ -77, -68, -85, -85, -85, -84, -85, -85, -85, -73,
+ -76, -85, -80, -81, -82, -85, -62, -59, -58, -60,
+ -61, -85, -85, -52, -53, -85, -85, -47, -85, -50,
+ -85, -28, -18, -85, -85, -78, -85, -31, -30, -13,
+ -71, -72, -85, -85, -85, -33, -85, -55, -85, -45,
+ -48, -46, -85, -85, -85, -14, -16, -11, -12, -85,
+ -74, -75, -64, -57, -54, -85, -85, -51, -85, -85,
+ -66, -56, -85, -65, -49 ]
racc_goto_table = [
- 15, 39, 30, 32, 82, 67, 52, 54, 88, 74,
- 29, 55, 83, 117, 83, 44, 32, 86, 50, 56,
- 94, 107, 69, 29, 81, 98, 60, 58, 49, 32,
- 65, 34, 42, 92, 45, 96, 29, 57, 106, 85,
- 84, 32, 68, 97, 34, 88, 83, 66, 29, 62,
- 117, 83, 14, nil, 109, nil, nil, 34, 61, nil,
- nil, 52, 54, nil, 122, nil, 55, 104, 32, 34,
- 103, 127, 129, 115, 56, 29, nil, nil, 83, 113,
- nil, nil, nil, 114, 32, 132, nil, nil, nil, 39,
- nil, 29, 57, 83, 123, 32, 34, nil, 125, 32,
- nil, 68, 29, nil, nil, nil, 29, nil, nil, nil,
- nil, nil, 34, 61, nil, nil, nil, 39, nil, 39,
- 131, nil, nil, 34, nil, nil, nil, 34, 133 ]
+ 18, 44, 35, 94, 37, 85, 99, 64, 25, 47,
+ 86, 108, 86, 79, 97, 50, 65, 103, 76, 51,
+ 63, 37, 62, 67, 59, 25, 34, 118, 68, 73,
+ 56, 57, 37, 43, 93, 96, 25, 42, 58, 104,
+ 52, 78, 117, 34, 100, 16, 95, 99, 37, 86,
+ nil, nil, 25, 86, 34, 120, 66, nil, 71, nil,
+ nil, nil, nil, nil, nil, 80, 107, nil, 37, 64,
+ 34, 135, 25, nil, 137, 108, 130, 115, 65, 37,
+ 86, 114, 63, 25, 62, 141, 126, 70, nil, 125,
+ 34, nil, 86, nil, 77, nil, nil, 44, nil, nil,
+ 58, 34, 70, nil, nil, 131, 129, 37, 133, nil,
+ 37, 25, 44, nil, 25, nil, nil, nil, 66, nil,
+ nil, 44, nil, nil, 138, 44, nil, nil, 80, 34,
+ nil, nil, 34, nil, nil, nil, 142 ]
racc_goto_check = [
- 2, 3, 22, 4, 33, 39, 18, 19, 31, 25,
- 10, 20, 26, 23, 26, 22, 4, 29, 16, 21,
- 14, 34, 37, 10, 32, 14, 13, 11, 22, 4,
- 13, 15, 35, 12, 24, 36, 10, 10, 33, 28,
- 22, 4, 10, 37, 15, 31, 26, 38, 10, 35,
- 23, 26, 1, nil, 29, nil, nil, 15, 15, nil,
- nil, 18, 19, nil, 39, nil, 20, 22, 4, 15,
- 2, 25, 31, 16, 21, 10, nil, nil, 26, 13,
- nil, nil, nil, 22, 4, 33, nil, nil, nil, 3,
- nil, 10, 10, 26, 22, 4, 15, nil, 22, 4,
- nil, 10, 10, nil, nil, nil, 10, nil, nil, nil,
- nil, nil, 15, 15, nil, nil, nil, 3, nil, 3,
- 2, nil, nil, 15, nil, nil, nil, 15, 2 ]
+ 2, 3, 23, 34, 4, 26, 32, 21, 16, 14,
+ 27, 24, 27, 41, 30, 36, 22, 13, 15, 23,
+ 20, 4, 19, 12, 17, 16, 11, 35, 14, 37,
+ 23, 36, 4, 11, 33, 29, 16, 38, 16, 15,
+ 25, 40, 34, 11, 37, 1, 23, 32, 4, 27,
+ nil, nil, 16, 27, 11, 30, 11, nil, 11, nil,
+ nil, nil, nil, nil, nil, 11, 23, nil, 4, 21,
+ 11, 26, 16, nil, 32, 24, 41, 23, 22, 4,
+ 27, 2, 20, 16, 19, 34, 17, 39, nil, 14,
+ 11, nil, 27, nil, 39, nil, nil, 3, nil, nil,
+ 16, 11, 39, nil, nil, 23, 2, 4, 23, nil,
+ 4, 16, 3, nil, 16, nil, nil, nil, 11, nil,
+ nil, 3, nil, nil, 2, 3, nil, nil, 11, 11,
+ nil, nil, 11, nil, nil, nil, 2 ]
racc_goto_pointer = [
- nil, 52, 0, -14, -6, nil, nil, nil, nil, nil,
- 1, -9, -25, -10, -40, 22, -18, nil, -30, -29,
- -25, -17, -7, -80, 12, -36, -34, nil, -9, -31,
- nil, -40, -22, -42, -59, 12, -27, -19, 6, -36 ]
+ nil, 45, 0, -17, -6, nil, nil, nil, nil, nil,
+ nil, 16, -17, -50, -12, -29, -2, -16, nil, -18,
+ -20, -33, -24, -8, -64, 13, -47, -43, nil, -20,
+ -41, nil, -49, -19, -50, -65, -8, -13, 20, 45,
+ -8, -36 ]
racc_goto_default = [
- nil, nil, nil, 16, 18, 1, 3, 6, 8, 10,
- 12, nil, nil, nil, nil, 17, nil, 51, 23, 25,
- 26, 28, nil, 59, nil, nil, 33, 21, nil, nil,
- 87, 78, nil, nil, nil, nil, nil, 43, nil, nil ]
+ nil, nil, nil, 19, 20, 2, 4, 7, 9, 11,
+ 13, 15, nil, nil, nil, nil, 1, nil, 61, 29,
+ 30, 32, 33, nil, 46, nil, nil, 24, 26, nil,
+ nil, 98, 91, nil, nil, nil, nil, nil, nil, 48,
+ nil, nil ]
racc_token_table = {
false => 0,
@@ -461,6 +485,7 @@ Racc_token_to_s_table = [
'import',
'definition',
'hostclass',
+'nodedef',
'name',
'objectinstances',
'endsemi',
@@ -488,6 +513,7 @@ Racc_token_to_s_table = [
'sintvalues',
'argumentlist',
'parent',
+'names',
'nothing',
'arguments',
'argument']
@@ -557,8 +583,10 @@ module_eval <<'.,.,', 'grammar.ra', 54
# reduce 9 omitted
-module_eval <<'.,.,', 'grammar.ra', 93
- def _reduce_10( val, _values, result )
+ # reduce 10 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 94
+ def _reduce_11( val, _values, result )
if val[0].is_a?(AST::ASTArray)
raise Puppet::ParseError, "Invalid name"
end
@@ -590,8 +618,8 @@ module_eval <<'.,.,', 'grammar.ra', 93
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 116
- def _reduce_11( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 117
+ def _reduce_12( val, _values, result )
if val[0].is_a?(AST::ASTArray)
Puppet.notice "invalid name"
raise Puppet::ParseError, "Invalid name"
@@ -618,8 +646,8 @@ module_eval <<'.,.,', 'grammar.ra', 116
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 129
- def _reduce_12( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 130
+ def _reduce_13( val, _values, result )
# a template setting for a type
if val[0].is_a?(AST::ASTArray)
Puppet.notice "invalid type"
@@ -636,8 +664,8 @@ module_eval <<'.,.,', 'grammar.ra', 129
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 137
- def _reduce_13( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 138
+ def _reduce_14( val, _values, result )
result = AST::ObjectInst.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -647,10 +675,10 @@ module_eval <<'.,.,', 'grammar.ra', 137
end
.,.,
- # reduce 14 omitted
+ # reduce 15 omitted
-module_eval <<'.,.,', 'grammar.ra', 151
- def _reduce_15( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 152
+ def _reduce_16( val, _values, result )
if val[0].is_a?(AST::ObjectInst)
result = AST::ASTArray.new(
:line => @lexer.line,
@@ -665,12 +693,12 @@ module_eval <<'.,.,', 'grammar.ra', 151
end
.,.,
- # reduce 16 omitted
-
# reduce 17 omitted
-module_eval <<'.,.,', 'grammar.ra', 162
- def _reduce_18( val, _values, result )
+ # reduce 18 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 163
+ def _reduce_19( val, _values, result )
result = AST::Name.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -680,8 +708,8 @@ module_eval <<'.,.,', 'grammar.ra', 162
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 170
- def _reduce_19( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 171
+ def _reduce_20( val, _values, result )
result = AST::Type.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -691,8 +719,6 @@ module_eval <<'.,.,', 'grammar.ra', 170
end
.,.,
- # reduce 20 omitted
-
# reduce 21 omitted
# reduce 22 omitted
@@ -703,8 +729,10 @@ module_eval <<'.,.,', 'grammar.ra', 170
# reduce 25 omitted
-module_eval <<'.,.,', 'grammar.ra', 193
- def _reduce_26( val, _values, result )
+ # reduce 26 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 194
+ def _reduce_27( val, _values, result )
# this is distinct from referencing a variable
variable = AST::Name.new(
:line => @lexer.line,
@@ -722,8 +750,8 @@ module_eval <<'.,.,', 'grammar.ra', 193
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 202
- def _reduce_27( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 203
+ def _reduce_28( val, _values, result )
result = AST::ASTArray.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -733,15 +761,15 @@ module_eval <<'.,.,', 'grammar.ra', 202
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 202
- def _reduce_28( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 203
+ def _reduce_29( val, _values, result )
result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 215
- def _reduce_29( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 216
+ def _reduce_30( val, _values, result )
if val[0].is_a?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
@@ -756,8 +784,8 @@ module_eval <<'.,.,', 'grammar.ra', 215
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 230
- def _reduce_30( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 231
+ def _reduce_31( val, _values, result )
leaf = AST::String.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -774,10 +802,10 @@ module_eval <<'.,.,', 'grammar.ra', 230
end
.,.,
- # reduce 31 omitted
+ # reduce 32 omitted
-module_eval <<'.,.,', 'grammar.ra', 243
- def _reduce_32( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 244
+ def _reduce_33( val, _values, result )
if val[0].is_a?(AST::ASTArray)
result = val[0].push(val[2])
else
@@ -791,8 +819,6 @@ module_eval <<'.,.,', 'grammar.ra', 243
end
.,.,
- # reduce 33 omitted
-
# reduce 34 omitted
# reduce 35 omitted
@@ -809,8 +835,10 @@ module_eval <<'.,.,', 'grammar.ra', 243
# reduce 41 omitted
-module_eval <<'.,.,', 'grammar.ra', 261
- def _reduce_42( val, _values, result )
+ # reduce 42 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 262
+ def _reduce_43( val, _values, result )
result = AST::String.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -820,8 +848,8 @@ module_eval <<'.,.,', 'grammar.ra', 261
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 269
- def _reduce_43( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 270
+ def _reduce_44( val, _values, result )
result = AST::Boolean.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -831,8 +859,8 @@ module_eval <<'.,.,', 'grammar.ra', 269
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 279
- def _reduce_44( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 280
+ def _reduce_45( val, _values, result )
result = AST::ObjectRef.new(
:pin => '[]',
:line => @lexer.line,
@@ -844,8 +872,8 @@ module_eval <<'.,.,', 'grammar.ra', 279
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 296
- def _reduce_45( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 297
+ def _reduce_46( val, _values, result )
options = val[3]
unless options.is_a?(AST::ASTArray)
options = AST::ASTArray.new(
@@ -864,10 +892,10 @@ module_eval <<'.,.,', 'grammar.ra', 296
end
.,.,
- # reduce 46 omitted
+ # reduce 47 omitted
-module_eval <<'.,.,', 'grammar.ra', 310
- def _reduce_47( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 311
+ def _reduce_48( val, _values, result )
if val[0].is_a?(AST::ASTArray)
val[0].push val[1]
result = val[0]
@@ -882,8 +910,8 @@ module_eval <<'.,.,', 'grammar.ra', 310
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 320
- def _reduce_48( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 321
+ def _reduce_49( val, _values, result )
result = AST::CaseOpt.new(
:pin => ":",
:value => val[0],
@@ -895,10 +923,10 @@ module_eval <<'.,.,', 'grammar.ra', 320
end
.,.,
- # reduce 49 omitted
+ # reduce 50 omitted
-module_eval <<'.,.,', 'grammar.ra', 334
- def _reduce_50( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 335
+ def _reduce_51( val, _values, result )
if val[0].is_a?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
@@ -913,32 +941,32 @@ module_eval <<'.,.,', 'grammar.ra', 334
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 344
- def _reduce_51( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 345
+ def _reduce_52( val, _values, result )
result = AST::Selector.new(
:pin => "?",
:line => @lexer.line,
:file => @lexer.file,
:param => val[0],
- :value => val[2]
+ :values => val[2]
)
result
end
.,.,
- # reduce 52 omitted
+ # reduce 53 omitted
-module_eval <<'.,.,', 'grammar.ra', 346
- def _reduce_53( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 347
+ def _reduce_54( val, _values, result )
result = val[1]
result
end
.,.,
- # reduce 54 omitted
+ # reduce 55 omitted
-module_eval <<'.,.,', 'grammar.ra', 361
- def _reduce_55( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 362
+ def _reduce_56( val, _values, result )
if val[0].is_a?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
@@ -953,8 +981,8 @@ module_eval <<'.,.,', 'grammar.ra', 361
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 371
- def _reduce_56( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 372
+ def _reduce_57( val, _values, result )
result = AST::ObjectParam.new(
:pin => "=>",
:line => @lexer.line,
@@ -966,8 +994,8 @@ module_eval <<'.,.,', 'grammar.ra', 371
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 379
- def _reduce_57( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 380
+ def _reduce_58( val, _values, result )
result = AST::String.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -977,8 +1005,8 @@ module_eval <<'.,.,', 'grammar.ra', 379
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 386
- def _reduce_58( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 387
+ def _reduce_59( val, _values, result )
result = AST::String.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -988,8 +1016,8 @@ module_eval <<'.,.,', 'grammar.ra', 386
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 393
- def _reduce_59( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 394
+ def _reduce_60( val, _values, result )
result = AST::String.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -999,8 +1027,8 @@ module_eval <<'.,.,', 'grammar.ra', 393
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 400
- def _reduce_60( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 401
+ def _reduce_61( val, _values, result )
result = AST::Default.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -1010,10 +1038,10 @@ module_eval <<'.,.,', 'grammar.ra', 400
end
.,.,
- # reduce 61 omitted
+ # reduce 62 omitted
-module_eval <<'.,.,', 'grammar.ra', 438
- def _reduce_62( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 439
+ def _reduce_63( val, _values, result )
# importing files
# yuk, i hate keywords
# we'll probably have to have some kind of search path eventually
@@ -1052,8 +1080,8 @@ module_eval <<'.,.,', 'grammar.ra', 438
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 448
- def _reduce_63( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 449
+ def _reduce_64( val, _values, result )
result = AST::CompDef.new(
:name => AST::Name.new(:value => val[1], :line => @lexer.line),
:args => val[2],
@@ -1066,7 +1094,7 @@ module_eval <<'.,.,', 'grammar.ra', 448
.,.,
module_eval <<'.,.,', 'grammar.ra', 464
- def _reduce_64( val, _values, result )
+ def _reduce_65( val, _values, result )
args = {
:name => AST::Name.new(:value => val[1], :line => @lexer.line),
:args => val[2],
@@ -1076,7 +1104,6 @@ module_eval <<'.,.,', 'grammar.ra', 464
}
# It'll be an ASTArray if we didn't get a parent
if val[3].is_a?(AST::Name)
- Puppet.notice "Assigning parent of %s as %s" % [val[1], val[3].value]
args[:parentclass] = val[3]
end
result = AST::ClassDef.new(args)
@@ -1084,8 +1111,49 @@ module_eval <<'.,.,', 'grammar.ra', 464
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 479
- def _reduce_65( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 484
+ def _reduce_66( val, _values, result )
+ unless val[1].is_a?(AST::ASTArray)
+ val[1] = AST::ASTArray.new(
+ :line => val[1].line,
+ :file => val[1].file,
+ :children => [val[1]]
+ )
+ end
+ args = {
+ :file => @lexer.file,
+ :line => @lexer.line,
+ :names => val[1],
+ :code => val[4]
+ }
+ if val[3].is_a?(AST::Name)
+ args[:parentclass] = val[2]
+ end
+ result = AST::NodeDef.new(args)
+ result
+ end
+.,.,
+
+ # reduce 67 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 498
+ def _reduce_68( val, _values, result )
+ if val[0].is_a?(AST::ASTArray)
+ result = val[0]
+ result.push val[1]
+ else
+ result = AST::ASTArray.new(
+ :line => @lexer.line,
+ :file => @lexer.file,
+ :children => [val[0], val[1]]
+ )
+ end
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ra', 506
+ def _reduce_69( val, _values, result )
result = AST::ASTArray.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -1095,17 +1163,17 @@ module_eval <<'.,.,', 'grammar.ra', 479
end
.,.,
- # reduce 66 omitted
+ # reduce 70 omitted
-module_eval <<'.,.,', 'grammar.ra', 484
- def _reduce_67( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 511
+ def _reduce_71( val, _values, result )
result = val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 495
- def _reduce_68( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 522
+ def _reduce_72( val, _values, result )
if val[1].is_a?(AST::ASTArray)
result = val[1]
else
@@ -1119,10 +1187,10 @@ module_eval <<'.,.,', 'grammar.ra', 495
end
.,.,
- # reduce 69 omitted
+ # reduce 73 omitted
-module_eval <<'.,.,', 'grammar.ra', 509
- def _reduce_70( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 536
+ def _reduce_74( val, _values, result )
if val[0].is_a?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
@@ -1137,8 +1205,8 @@ module_eval <<'.,.,', 'grammar.ra', 509
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 517
- def _reduce_71( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 544
+ def _reduce_75( val, _values, result )
result = AST::ASTArray.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -1148,8 +1216,8 @@ module_eval <<'.,.,', 'grammar.ra', 517
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 524
- def _reduce_72( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 551
+ def _reduce_76( val, _values, result )
result = AST::ASTArray.new(
:line => @lexer.line,
:file => @lexer.file,
@@ -1159,10 +1227,10 @@ module_eval <<'.,.,', 'grammar.ra', 524
end
.,.,
- # reduce 73 omitted
+ # reduce 77 omitted
-module_eval <<'.,.,', 'grammar.ra', 533
- def _reduce_74( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 560
+ def _reduce_78( val, _values, result )
result = AST::Name.new(
:value => val[1],
:file => @lexer.file,
@@ -1172,8 +1240,8 @@ module_eval <<'.,.,', 'grammar.ra', 533
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 542
- def _reduce_75( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 569
+ def _reduce_79( val, _values, result )
name = val[0].sub(/^\$/,'')
result = AST::Variable.new(
:line => @lexer.line,
@@ -1184,8 +1252,8 @@ module_eval <<'.,.,', 'grammar.ra', 542
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 551
- def _reduce_76( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 578
+ def _reduce_80( val, _values, result )
if val[1].is_a?(AST::ASTArray)
result = val[1]
else
@@ -1196,14 +1264,14 @@ module_eval <<'.,.,', 'grammar.ra', 551
end
.,.,
- # reduce 77 omitted
+ # reduce 81 omitted
- # reduce 78 omitted
+ # reduce 82 omitted
- # reduce 79 omitted
+ # reduce 83 omitted
-module_eval <<'.,.,', 'grammar.ra', 556
- def _reduce_80( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 583
+ def _reduce_84( val, _values, result )
result = nil
result
end