Class: Citrus::Match
Overview
The base class for all matches. Matches are organized into a tree where any match may contain any number of other matches. Nodes of the tree are lazily instantiated as needed. This class provides several convenient tree traversal methods that help when examining and interpreting parse results.
Instance Attribute Summary collapse
-
#events ⇒ Object
readonly
The array of events for this match.
-
#input ⇒ Object
readonly
The original Input this Match was generated on.
-
#offset ⇒ Object
readonly
The index of this match in the #input.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#[](key, *args) ⇒ Object
Returns the capture at the given
key. -
#capture(name) ⇒ Object
Convenient method for captures.first.
-
#captures(name = nil) ⇒ Object
Returns a hash of capture names to arrays of matches with that name, in the order they appeared in the input.
-
#dump(indent = ' ') ⇒ Object
Prints the entire subtree of this match using the given
indentto indicate nested match levels. -
#first ⇒ Object
A shortcut for retrieving the first immediate submatch of this match.
-
#initialize(input, events = [], offset = 0) ⇒ Match
constructor
A new instance of Match.
- #inspect ⇒ Object
-
#length ⇒ Object
Returns the length of this match.
-
#matches ⇒ Object
Returns an array of all immediate submatches of this match.
-
#source ⇒ Object
Convenient shortcut for
input.source. -
#string ⇒ Object
(also: #to_s)
Returns the slice of the source text that this match captures.
-
#to_a ⇒ Object
Returns this match plus all sub #matches in an array.
Constructor Details
#initialize(input, events = [], offset = 0) ⇒ Match
Returns a new instance of Match.
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 |
# File 'lib/citrus.rb', line 1275 def initialize(input, events=[], offset=0) @input = input @offset = offset @captures = nil @matches = nil if events.length > 0 elisions = [] while events[0].elide? elisions.unshift(events.shift) events.slice!(-2, events.length) end events[0].extend_match(self) elisions.each do |rule| rule.extend_match(self) end else # Create a default stream of events for the given string. string = input.to_str events = [Rule.for(string), CLOSE, string.length] end @events = events end |
Instance Attribute Details
#events ⇒ Object (readonly)
The array of events for this match.
1310 1311 1312 |
# File 'lib/citrus.rb', line 1310 def events @events end |
#input ⇒ Object (readonly)
The original Input this Match was generated on.
1304 1305 1306 |
# File 'lib/citrus.rb', line 1304 def input @input end |
#offset ⇒ Object (readonly)
The index of this match in the #input.
1307 1308 1309 |
# File 'lib/citrus.rb', line 1307 def offset @offset end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 |
# File 'lib/citrus.rb', line 1381 def ==(other) case other when String string == other when Match string == other.to_s else super end end |
#[](key, *args) ⇒ Object
Returns the capture at the given key. If it is an Integer (and an
optional length) or a Range, the result of #to_a with the same arguments
is returned. Otherwise, the value at key in #captures is returned.
1372 1373 1374 1375 1376 1377 1378 1379 |
# File 'lib/citrus.rb', line 1372 def [](key, *args) case key when Integer, Range to_a[key, *args] else captures[key] end end |
#capture(name) ⇒ Object
Convenient method for captures.first.
1335 1336 1337 |
# File 'lib/citrus.rb', line 1335 def capture(name) captures[name].first end |
#captures(name = nil) ⇒ Object
Returns a hash of capture names to arrays of matches with that name, in the order they appeared in the input.
1329 1330 1331 1332 |
# File 'lib/citrus.rb', line 1329 def captures(name = nil) process_events! unless @captures name ? @captures[name] : @captures end |
#dump(indent = ' ') ⇒ Object
Prints the entire subtree of this match using the given indent to
indicate nested match levels. Useful for debugging.
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 |
# File 'lib/citrus.rb', line 1400 def dump(indent=' ') lines = [] stack = [] offset = 0 close = false index = 0 last_length = nil while index < @events.size event = @events[index] if close os = stack.pop start = stack.pop rule = stack.pop space = indent * (stack.size / 3) string = self.string.slice(os, event) lines[start] = "#{space}#{string.inspect} rule=#{rule}, offset=#{os}, length=#{event}" last_length = event unless last_length close = false elsif event == CLOSE close = true else if last_length offset += last_length last_length = nil end stack << event stack << index stack << offset end index += 1 end puts lines.compact.join("\n") end |
#first ⇒ Object
A shortcut for retrieving the first immediate submatch of this match.
1346 1347 1348 |
# File 'lib/citrus.rb', line 1346 def first matches.first end |
#inspect ⇒ Object
1394 1395 1396 |
# File 'lib/citrus.rb', line 1394 def inspect string.inspect end |
#length ⇒ Object
Returns the length of this match.
1313 1314 1315 |
# File 'lib/citrus.rb', line 1313 def length events.last end |
#matches ⇒ Object
Returns an array of all immediate submatches of this match.
1340 1341 1342 1343 |
# File 'lib/citrus.rb', line 1340 def matches process_events! unless @matches @matches end |
#source ⇒ Object
Convenient shortcut for input.source
1318 1319 1320 |
# File 'lib/citrus.rb', line 1318 def source (input.respond_to?(:source) && input.source) || input end |
#string ⇒ Object Also known as: to_s
Returns the slice of the source text that this match captures.
1323 1324 1325 |
# File 'lib/citrus.rb', line 1323 def string @string ||= input.to_str[offset, length] end |
#to_a ⇒ Object
Returns this match plus all sub #matches in an array.
1365 1366 1367 |
# File 'lib/citrus.rb', line 1365 def to_a [self] + matches end |