Class: Inversion::Parser::State
- Inherits:
-
Object
- Object
- Inversion::Parser::State
- Extended by:
- Loggability
- Defined in:
- lib/inversion/parser.rb
Overview
Parse state object class. State objects keep track of where in the parse tree new nodes should be appended, and manages inclusion.
Instance Attribute Summary collapse
-
#include_stack ⇒ Object
readonly
The stack of templates that have been loaded for this state; for loop detection.
-
#node_stack ⇒ Object
readonly
The stack of containers.
-
#options ⇒ Object
readonly
The parse options in effect for this parse state.
-
#template ⇒ Object
The template object for this parser state.
Instance Method Summary collapse
-
#<<(node) ⇒ Object
Append operator: add nodes to the correct part of the parse tree.
-
#append_tree(newtree) ⇒ Object
Append another Array of nodes onto this state’s node tree.
-
#clear_nodes ⇒ Object
Clear any parsed nodes from the state, leaving the options and include_stack intact.
-
#current_node ⇒ Object
Return the node that is currently being appended to, or
nil
if there aren’t any opened container nodes. -
#initialize(template, options = {}) ⇒ State
constructor
Create a new State object.
-
#initialize_copy(original) ⇒ Object
Copy constructor – duplicate inner structures.
-
#is_well_formed? ⇒ Boolean
(also: #well_formed?)
Check to see if all open tags have been closed.
-
#load_subtemplate(path) ⇒ Object
Load a subtemplate from the specified
path
, checking for recursive-dependency. -
#pop ⇒ Object
Pop one level off of the node stack and return it.
-
#tree ⇒ Object
Returns the tree if it’s well formed.
Constructor Details
#initialize(template, options = {}) ⇒ State
Create a new State object
174 175 176 177 178 179 180 |
# File 'lib/inversion/parser.rb', line 174 def initialize( template, ={} ) @template = template @options = .dup @tree = [] @node_stack = [ @tree ] @include_stack = [] end |
Instance Attribute Details
#include_stack ⇒ Object (readonly)
The stack of templates that have been loaded for this state; for loop detection.
204 205 206 |
# File 'lib/inversion/parser.rb', line 204 def include_stack @include_stack end |
#node_stack ⇒ Object (readonly)
The stack of containers
207 208 209 |
# File 'lib/inversion/parser.rb', line 207 def node_stack @node_stack end |
#options ⇒ Object (readonly)
The parse options in effect for this parse state
198 199 200 |
# File 'lib/inversion/parser.rb', line 198 def @options end |
#template ⇒ Object
The template object for this parser state
201 202 203 |
# File 'lib/inversion/parser.rb', line 201 def template @template end |
Instance Method Details
#<<(node) ⇒ Object
Append operator: add nodes to the correct part of the parse tree.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/inversion/parser.rb', line 211 def <<( node ) # self.log.debug "Appending %p" % [ node ] node.before_appending( self ) self.node_stack.last << node if node.is_container? # Containers get pushed onto the stack so they get appended to self.node_stack.push( node ) else # Container nodes' #after_appending gets called in #pop node.after_appending( self ) end return self rescue Inversion::ParseError => err raise err, "%s at %s" % [ err., node.location ] end |
#append_tree(newtree) ⇒ Object
Append another Array of nodes onto this state’s node tree.
232 233 234 235 236 |
# File 'lib/inversion/parser.rb', line 232 def append_tree( newtree ) newtree.each do |node| self.node_stack.last << node end end |
#clear_nodes ⇒ Object
Clear any parsed nodes from the state, leaving the options and include_stack intact.
279 280 281 282 |
# File 'lib/inversion/parser.rb', line 279 def clear_nodes @tree = [] @node_stack = [ @tree ] end |
#current_node ⇒ Object
Return the node that is currently being appended to, or nil
if there aren’t any opened container nodes.
273 274 275 |
# File 'lib/inversion/parser.rb', line 273 def current_node return self.node_stack.last end |
#initialize_copy(original) ⇒ Object
Copy constructor – duplicate inner structures.
184 185 186 187 188 189 190 |
# File 'lib/inversion/parser.rb', line 184 def initialize_copy( original ) @template = original.template @options = original..dup @tree = @tree.map( &:dup ) @node_stack = [ @tree ] @include_stack = original.include_stack.dup end |
#is_well_formed? ⇒ Boolean Also known as: well_formed?
Check to see if all open tags have been closed.
250 251 252 |
# File 'lib/inversion/parser.rb', line 250 def is_well_formed? return self.node_stack.length == 1 end |
#load_subtemplate(path) ⇒ Object
Load a subtemplate from the specified path
, checking for recursive-dependency.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/inversion/parser.rb', line 286 def load_subtemplate( path ) if self.include_stack.include?( path ) stack_desc = ( self.include_stack + [path] ).join( ' --> ' ) msg = "Recursive load of %p detected: from %s" % [ path, stack_desc ] self.log.error( msg ) raise Inversion::StackError, msg end # self.log.debug "Include stack is: %p" % [ self.include_stack ] substate = self.dup substate.clear_nodes substate.include_stack.push( path ) return Inversion::Template.load( path, substate, self. ) end |
#pop ⇒ Object
Pop one level off of the node stack and return it.
257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/inversion/parser.rb', line 257 def pop closed_node = self.node_stack.pop # If there's nothing on the node stack, we've popped the top-level # Array, which means there wasn't an opening container. raise Inversion::ParseError, "unbalanced end: no open tag" if self.node_stack.empty? closed_node.after_appending( self ) return closed_node end |
#tree ⇒ Object
Returns the tree if it’s well formed.
240 241 242 243 244 245 246 |
# File 'lib/inversion/parser.rb', line 240 def tree unless self.is_well_formed? raise Inversion::ParseError, "Unclosed container tag: %s, from %s" % [ self.node_stack.last.tagname, self.node_stack.last.location ] end return @tree end |