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
173 174 175 176 177 178 179 |
# File 'lib/inversion/parser.rb', line 173 def initialize( template, ={} ) @template = template = .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.
203 204 205 |
# File 'lib/inversion/parser.rb', line 203 def include_stack @include_stack end |
#node_stack ⇒ Object (readonly)
The stack of containers
206 207 208 |
# File 'lib/inversion/parser.rb', line 206 def node_stack @node_stack end |
#options ⇒ Object (readonly)
The parse options in effect for this parse state
197 198 199 |
# File 'lib/inversion/parser.rb', line 197 def end |
#template ⇒ Object
The template object for this parser state
200 201 202 |
# File 'lib/inversion/parser.rb', line 200 def template @template end |
Instance Method Details
#<<(node) ⇒ Object
Append operator: add nodes to the correct part of the parse tree.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/inversion/parser.rb', line 210 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.
231 232 233 234 235 |
# File 'lib/inversion/parser.rb', line 231 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.
278 279 280 281 |
# File 'lib/inversion/parser.rb', line 278 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.
272 273 274 |
# File 'lib/inversion/parser.rb', line 272 def current_node return self.node_stack.last end |
#initialize_copy(original) ⇒ Object
Copy constructor – duplicate inner structures.
183 184 185 186 187 188 189 |
# File 'lib/inversion/parser.rb', line 183 def initialize_copy( original ) @template = original.template = 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.
249 250 251 |
# File 'lib/inversion/parser.rb', line 249 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.
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/inversion/parser.rb', line 285 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.
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/inversion/parser.rb', line 256 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.
239 240 241 242 243 244 245 |
# File 'lib/inversion/parser.rb', line 239 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 |