Class Citrus::Match

  1. lib/citrus.rb
Parent: Object

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.

Attributes

events [R] The array of events for this match.
input [R] The original Input this Match was generated on.
offset [R] The index of this match in the input.

Public class methods

new (input, events=[], offset=0)
[show source]
      # File lib/citrus.rb, line 1275
1275:     def initialize(input, events=[], offset=0)
1276:       @input = input
1277:       @offset = offset
1278:       @captures = nil
1279:       @matches = nil
1280: 
1281:       if events.length > 0
1282:         elisions = []
1283: 
1284:         while events[0].elide?
1285:           elisions.unshift(events.shift)
1286:           events.slice!(-2, events.length)
1287:         end
1288: 
1289:         events[0].extend_match(self)
1290: 
1291:         elisions.each do |rule|
1292:           rule.extend_match(self)
1293:         end
1294:       else
1295:         # Create a default stream of events for the given string.
1296:         string = input.to_str
1297:         events = [Rule.for(string), CLOSE, string.length]
1298:       end
1299: 
1300:       @events = events
1301:     end

Public instance methods

== (other)
[show source]
      # File lib/citrus.rb, line 1381
1381:     def ==(other)
1382:       case other
1383:       when String
1384:         string == other
1385:       when Match
1386:         string == other.to_s
1387:       else
1388:         super
1389:       end
1390:     end
[] (key, *args)

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.

[show source]
      # File lib/citrus.rb, line 1372
1372:     def [](key, *args)
1373:       case key
1374:       when Integer, Range
1375:         to_a[key, *args]
1376:       else
1377:         captures[key]
1378:       end
1379:     end
capture (name)

Convenient method for captures[name].first.

[show source]
      # File lib/citrus.rb, line 1335
1335:     def capture(name)
1336:       captures[name].first
1337:     end
captures (name = nil)

Returns a hash of capture names to arrays of matches with that name, in the order they appeared in the input.

[show source]
      # File lib/citrus.rb, line 1329
1329:     def captures(name = nil)
1330:       process_events! unless @captures
1331:       name ? @captures[name] : @captures
1332:     end
dump (indent=' ')

Prints the entire subtree of this match using the given indent to indicate nested match levels. Useful for debugging.

[show source]
      # File lib/citrus.rb, line 1400
1400:     def dump(indent=' ')
1401:       lines = []
1402:       stack = []
1403:       offset = 0
1404:       close = false
1405:       index = 0
1406:       last_length = nil
1407: 
1408:       while index < @events.size
1409:         event = @events[index]
1410: 
1411:         if close
1412:           os = stack.pop
1413:           start = stack.pop
1414:           rule = stack.pop
1415: 
1416:           space = indent * (stack.size / 3)
1417:           string = self.string.slice(os, event)
1418:           lines[start] = "#{space}#{string.inspect} rule=#{rule}, offset=#{os}, length=#{event}"
1419: 
1420:           last_length = event unless last_length
1421: 
1422:           close = false
1423:         elsif event == CLOSE
1424:           close = true
1425:         else
1426:           if last_length
1427:             offset += last_length
1428:             last_length = nil
1429:           end
1430: 
1431:           stack << event
1432:           stack << index
1433:           stack << offset
1434:         end
1435: 
1436:         index += 1
1437:       end
1438: 
1439:       puts lines.compact.join("\n")
1440:     end
eql? (other)

Alias for #==

first ()

A shortcut for retrieving the first immediate submatch of this match.

[show source]
      # File lib/citrus.rb, line 1346
1346:     def first
1347:       matches.first
1348:     end
inspect ()
[show source]
      # File lib/citrus.rb, line 1394
1394:     def inspect
1395:       string.inspect
1396:     end
length ()

Returns the length of this match.

[show source]
      # File lib/citrus.rb, line 1313
1313:     def length
1314:       events.last
1315:     end
matches ()

Returns an array of all immediate submatches of this match.

[show source]
      # File lib/citrus.rb, line 1340
1340:     def matches
1341:       process_events! unless @matches
1342:       @matches
1343:     end
source ()

Convenient shortcut for input.source

[show source]
      # File lib/citrus.rb, line 1318
1318:     def source
1319:       (input.respond_to?(:source) && input.source) || input
1320:     end
string ()

Returns the slice of the source text that this match captures.

[show source]
      # File lib/citrus.rb, line 1323
1323:     def string
1324:       @string ||= input.to_str[offset, length]
1325:     end
to_a ()

Returns this match plus all sub matches in an array.

[show source]
      # File lib/citrus.rb, line 1365
1365:     def to_a
1366:       [self] + matches
1367:     end
to_s ()
to_str ()

Alias for to_s

value ()

Alias for to_s