Class: Gullah::Node
- Inherits:
-
Object
- Object
- Gullah::Node
- Defined in:
- lib/gullah/node.rb
Overview
a node in an AST
Instance Attribute Summary collapse
-
#attributes ⇒ Object
(also: #atts)
readonly
A hash of attributes, including indicators of tests that passed or failed.
-
#children ⇒ Object
readonly
The children of this node, if any, as an array.
-
#parent ⇒ Object
readonly
The parent node of this node, if any.
-
#summary ⇒ Object
readonly
A concise stringification of the structure of this node’s subtree.
Instance Method Summary collapse
-
#ancestors ⇒ Object
Returns an Enumerable enumerating the nodes immediately above this node in the tree: its parent, its parent’s parent, etc.
-
#boundary? ⇒ Boolean
Is this node one that cannot be the child of another node?.
-
#contains?(offset) ⇒ Boolean
Does this node contain the given text offset?.
-
#dbg(so: false) ⇒ Object
Produces a simplified representation of the node to facilitate debugging.
-
#depth ⇒ Object
Distance of the node from the root node of the parse tree.
-
#descendants ⇒ Object
Returns an Enumerable over the descendants of this node: its children, its children’s children, etc.
-
#end ⇒ Object
The node’s end text offset.
-
#error? ⇒ Boolean
Does this node have some failed test?.
-
#failed? ⇒ Boolean
Does this node have some failed test or does it represent characters no leaf rule mached?.
-
#find(pos) ⇒ Object
Finds the node at the given position within this node’s subtree.
-
#first_child? ⇒ Boolean
Is this node the first of its parent’s children?.
-
#full_text ⇒ Object
A reference to the full text the node’s text is embedded in.
-
#height ⇒ Object
The distance of a node from the first leaf node in its subtree.
-
#ignorable? ⇒ Boolean
Was this node created by an
ignorerule?. -
#last_child? ⇒ Boolean
Is this node the last of its parent’s children?.
-
#later ⇒ Object
The collection of nodes in the subtree containing this node whose start offset is at or after its end offset.
-
#later_sibling ⇒ Object
The immediately following sibling to this node.
-
#later_siblings ⇒ Object
Returns the children of this node’s parent that follow it.
-
#leaf? ⇒ Boolean
Is this a leaf node?.
-
#leaves ⇒ Object
The leaves of this node’s subtree.
-
#name ⇒ Object
The name of the rule that created this node.
-
#nonterminal? ⇒ Boolean
Is this a node that has other nodes as children?.
-
#pending_tests? ⇒ Boolean
Does this node’s subtree contain unsatisfied syntactic requirements? These are tests that depend on nodes not in the node’s own subtree.
-
#position ⇒ Object
A pair consisting of the nodes start and height.
-
#prior ⇒ Object
The collection of nodes in the subtree containing this node that do not
containthe node and whose start offset precedes its start offset. -
#prior_sibling ⇒ Object
The immediately prior sibling to this node.
-
#prior_siblings ⇒ Object
Returns the children of this node’s parent that precede it.
-
#root ⇒ Object
The root of this node’s current parse tree.
-
#root? ⇒ Boolean
Does this node have any parent? If not, it is a root.
-
#sibling_index ⇒ Object
The index of this node among its parent’s children.
-
#siblings ⇒ Object
Returns the children of this node’s parent’s children minus this node itself.
-
#significant? ⇒ Boolean
Was this node created by something other than an
ignorerule?. -
#size ⇒ Object
The number of nodes in this node’s subtree.
-
#start ⇒ Object
The node’s start text offset.
-
#subtree ⇒ Object
Returns an Enumerable over this node and its descendants.
-
#text ⇒ Object
The portion of the original text covered by this node.
-
#text_after ⇒ Object
The text following this node’s text.
-
#text_before ⇒ Object
The text preceding this node’s text.
-
#trash? ⇒ Boolean
Does this node represent a character sequence no leaf rule matched?.
Instance Attribute Details
#attributes ⇒ Object (readonly) Also known as: atts
A hash of attributes, including indicators of tests that passed or failed. The atts alias of attributes exists for when a more telegraphic coding style is useful.
16 17 18 |
# File 'lib/gullah/node.rb', line 16 def attributes @attributes end |
#children ⇒ Object (readonly)
The children of this node, if any, as an array.
20 21 22 |
# File 'lib/gullah/node.rb', line 20 def children @children end |
#parent ⇒ Object (readonly)
The parent node of this node, if any.
8 9 10 |
# File 'lib/gullah/node.rb', line 8 def parent @parent end |
#summary ⇒ Object (readonly)
A concise stringification of the structure of this node’s subtree.
24 25 26 |
# File 'lib/gullah/node.rb', line 24 def summary @summary end |
Instance Method Details
#ancestors ⇒ Object
Returns an Enumerable enumerating the nodes immediately above this node in the tree: its parent, its parent’s parent, etc.
254 255 256 |
# File 'lib/gullah/node.rb', line 254 def ancestors _ancestors self end |
#boundary? ⇒ Boolean
Is this node one that cannot be the child of another node?
88 89 90 |
# File 'lib/gullah/node.rb', line 88 def boundary? false end |
#contains?(offset) ⇒ Boolean
Does this node contain the given text offset?
208 209 210 |
# File 'lib/gullah/node.rb', line 208 def contains?(offset) start <= offset && offset < self.end end |
#dbg(so: false) ⇒ Object
Produces a simplified representation of the node to facilitate debugging. The so named parameter, if true, will cause the representation to drop ignored nodes. The name “so” stands for “significant only”.
> pp root.dbg
{:name=>:S,
:pos=>{:start=>0, :end=>11, :depth=>0},
:children=>
[{:name=>:NP,
:pos=>{:start=>0, :end=>7, :depth=>1},
:children=>
[{:name=>:D, :pos=>{:start=>0, :end=>3, :depth=>2}, :text=>"the"},
{:name=>:_ws,
:pos=>{:start=>3, :end=>4, :depth=>2},
:ignorable=>true,
:text=>" "},
{:name=>:N, :pos=>{:start=>4, :end=>7, :depth=>2}, :text=>"cat"}]},
{:name=>:_ws,
:pos=>{:start=>7, :end=>8, :depth=>1},
:ignorable=>true,
:text=>" "},
{:name=>:VP,
:pos=>{:start=>8, :end=>11, :depth=>1},
:children=>
[{:name=>:V, :pos=>{:start=>8, :end=>11, :depth=>2}, :text=>"sat"}]}]}
> pp root.dbg so: true
{:name=>:S,
:pos=>{:start=>0, :end=>11, :depth=>0},
:children=>
[{:name=>:NP,
:pos=>{:start=>0, :end=>7, :depth=>1},
:children=>
[{:name=>:D, :pos=>{:start=>0, :end=>3, :depth=>2}, :text=>"the"},
{:name=>:_ws, :pos=>{:start=>3, :end=>4, :depth=>2}, :text=>" "},
{:name=>:N, :pos=>{:start=>4, :end=>7, :depth=>2}, :text=>"cat"}]},
{:name=>:_ws, :pos=>{:start=>7, :end=>8, :depth=>1}, :text=>" "},
{:name=>:VP,
:pos=>{:start=>8, :end=>11, :depth=>1},
:children=>
[{:name=>:V, :pos=>{:start=>8, :end=>11, :depth=>2}, :text=>"sat"}]}]}
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/gullah/node.rb', line 399 def dbg(so: false) { name: name, pos: { start: start, end: self.end, depth: depth } }.tap do |simpleton| simpleton[:failed] = true if @failed_test simpleton[:attributes] = deep_clone attributes if attributes.any? if leaf? simpleton[:trash] = true if trash? simpleton[:ignorable] = true unless so || significant? simpleton[:text] = text else simpleton[:children] = children.map { |c| c.dbg so: so } end end end |
#depth ⇒ Object
Distance of the node from the root node of the parse tree. During parsing, while nodes are being added, this distance may change, unlike the height.
The root node has a depth of 0. It’s children have a depth of 1. Their children have a depth of 2. And so forth.
187 188 189 |
# File 'lib/gullah/node.rb', line 187 def depth parent ? 1 + parent.depth : 0 end |
#descendants ⇒ Object
Returns an Enumerable over the descendants of this node: its children, its children’s children, etc. This enumeration is depth-first.
261 262 263 |
# File 'lib/gullah/node.rb', line 261 def descendants _descendants self end |
#end ⇒ Object
The node’s end text offset. For a non-terminal node, this will be the same as the end of the last leaf node of its subtree.
176 177 178 |
# File 'lib/gullah/node.rb', line 176 def end @end ||= @children[-1].end end |
#error? ⇒ Boolean
Does this node have some failed test?
112 113 114 |
# File 'lib/gullah/node.rb', line 112 def error? @failed_test end |
#failed? ⇒ Boolean
Does this node have some failed test or does it represent characters no leaf rule mached?
100 101 102 |
# File 'lib/gullah/node.rb', line 100 def failed? trash? || error? end |
#find(pos) ⇒ Object
Finds the node at the given position within this node’s subtree.
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/gullah/node.rb', line 214 def find(pos) offset = pos.first return nil unless contains?(offset) return self if pos == position if (child = children&.find { |c| c.contains? offset }) child.find(pos) end end |
#first_child? ⇒ Boolean
Is this node the first of its parent’s children?
304 305 306 |
# File 'lib/gullah/node.rb', line 304 def first_child? sibling_index.zero? end |
#full_text ⇒ Object
A reference to the full text the node’s text is embedded in.
150 151 152 |
# File 'lib/gullah/node.rb', line 150 def full_text @text end |
#height ⇒ Object
The distance of a node from the first leaf node in its subtree. If the node is the immediate parent of this leaf, its distance will be one. Leaves have a height of zero.
195 196 197 |
# File 'lib/gullah/node.rb', line 195 def height @height ||= @leaf ? 0 : 1 + children[0].height end |
#ignorable? ⇒ Boolean
Was this node created by an ignore rule?
125 126 127 |
# File 'lib/gullah/node.rb', line 125 def ignorable? @leaf && rule.ignorable end |
#last_child? ⇒ Boolean
Is this node the last of its parent’s children?
298 299 300 |
# File 'lib/gullah/node.rb', line 298 def last_child? parent && sibling_index == parent.children.length - 1 end |
#later ⇒ Object
The collection of nodes in the subtree containing this node whose start offset is at or after its end offset.
339 340 341 |
# File 'lib/gullah/node.rb', line 339 def later root.descendants.select { |n| n.start >= self.end } end |
#later_sibling ⇒ Object
The immediately following sibling to this node.
318 319 320 |
# File 'lib/gullah/node.rb', line 318 def later_sibling parent && parent.children[sibling_index + 1] end |
#later_siblings ⇒ Object
Returns the children of this node’s parent that follow it.
292 293 294 |
# File 'lib/gullah/node.rb', line 292 def later_siblings parent && siblings[(sibling_index + 1)..] end |
#leaf? ⇒ Boolean
Is this a leaf node?
94 95 96 |
# File 'lib/gullah/node.rb', line 94 def leaf? @leaf end |
#leaves ⇒ Object
The leaves of this node’s subtree. If the node is a leaf, this returns a single-member array containing the node itself.
325 326 327 |
# File 'lib/gullah/node.rb', line 325 def leaves @leaf ? [self] : descendants.select(&:leaf?) end |
#name ⇒ Object
The name of the rule that created this node.
76 77 78 |
# File 'lib/gullah/node.rb', line 76 def name rule.name end |
#nonterminal? ⇒ Boolean
Is this a node that has other nodes as children?
137 138 139 |
# File 'lib/gullah/node.rb', line 137 def nonterminal? !@leaf end |
#pending_tests? ⇒ Boolean
Does this node’s subtree contain unsatisfied syntactic requirements? These are tests that depend on nodes not in the node’s own subtree.
119 120 121 |
# File 'lib/gullah/node.rb', line 119 def pending_tests? !!attributes[:pending] end |
#position ⇒ Object
A pair consisting of the nodes start and height. This will be a unique identifier for the node in its parse and is constant at all stages of parsing.
202 203 204 |
# File 'lib/gullah/node.rb', line 202 def position @position ||= [start, height] end |
#prior ⇒ Object
The collection of nodes in the subtree containing this node that do not contain the node and whose start offset precedes its start offset.
332 333 334 |
# File 'lib/gullah/node.rb', line 332 def prior root.descendants.reject { |n| n.contains? start }.select { |n| n.start < start } end |
#prior_sibling ⇒ Object
The immediately prior sibling to this node.
310 311 312 313 314 |
# File 'lib/gullah/node.rb', line 310 def prior_sibling if parent first_child? ? nil : parent.children[sibling_index - 1] end end |
#prior_siblings ⇒ Object
Returns the children of this node’s parent that precede it.
286 287 288 |
# File 'lib/gullah/node.rb', line 286 def prior_siblings parent && siblings[0...sibling_index] end |
#root ⇒ Object
The root of this node’s current parse tree.
Note, if you use this in a node test the root will always be the same as the node itself because these tests are run when the node is being added to the tree. If you use it in structure tests, it will be some ancestor of the node but not necessarily the final root. The current root is always the first argument to structure tests. Using this argument is more efficient than using the root method. Really, the root method is only useful in completed parses.
241 242 243 |
# File 'lib/gullah/node.rb', line 241 def root parent ? parent.root : self end |
#root? ⇒ Boolean
Does this node have any parent? If not, it is a root.
247 248 249 |
# File 'lib/gullah/node.rb', line 247 def root? parent.nil? end |
#sibling_index ⇒ Object
The index of this node among its parent’s children.
280 281 282 |
# File 'lib/gullah/node.rb', line 280 def sibling_index @sibling_index ||= parent.children.index self if parent end |
#siblings ⇒ Object
Returns the children of this node’s parent’s children minus this node itself.
274 275 276 |
# File 'lib/gullah/node.rb', line 274 def siblings parent&.children&.reject { |n| n == self } end |
#significant? ⇒ Boolean
Was this node created by something other than an ignore rule?
131 132 133 |
# File 'lib/gullah/node.rb', line 131 def significant? !ignorable? end |
#size ⇒ Object
The number of nodes in this node’s subtree. Leaves always have a size of 1.
227 228 229 |
# File 'lib/gullah/node.rb', line 227 def size @size ||= @leaf ? 1 : @children.map(&:size).sum + 1 end |
#start ⇒ Object
The node’s start text offset. For a non-terminal node, this will be the same as the start of the first leaf node of its subtree.
169 170 171 |
# File 'lib/gullah/node.rb', line 169 def start @start ||= @children[0].start end |
#subtree ⇒ Object
Returns an Enumerable over this node and its descendants. The node itself is the first node returned.
268 269 270 |
# File 'lib/gullah/node.rb', line 268 def subtree _descendants nil end |
#text ⇒ Object
The portion of the original text covered by this node. This is in effect the text of the leaves of its subtree.
144 145 146 |
# File 'lib/gullah/node.rb', line 144 def text @text[start...self.end] end |
#text_after ⇒ Object
The text following this node’s text. Useful for lookaround tests and preconditions.
162 163 164 |
# File 'lib/gullah/node.rb', line 162 def text_after @text[self.end..] end |
#text_before ⇒ Object
The text preceding this node’s text. Useful for lookaround tests and preconditions.
156 157 158 |
# File 'lib/gullah/node.rb', line 156 def text_before @text[0...start] end |
#trash? ⇒ Boolean
Does this node represent a character sequence no leaf rule matched?
82 83 84 |
# File 'lib/gullah/node.rb', line 82 def trash? false end |