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.
Methods
public class
public instance
Attributes
Public class methods
# 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
# 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
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.
# 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
Convenient method for captures[name].first.
# File lib/citrus.rb, line 1335 1335: def capture(name) 1336: captures[name].first 1337: end
Returns a hash of capture names to arrays of matches with that name, in the order they appeared in the input.
# File lib/citrus.rb, line 1329 1329: def captures(name = nil) 1330: process_events! unless @captures 1331: name ? @captures[name] : @captures 1332: end
Prints the entire subtree of this match using the given indent to indicate nested match levels. Useful for debugging.
# 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
A shortcut for retrieving the first immediate submatch of this match.
# File lib/citrus.rb, line 1346 1346: def first 1347: matches.first 1348: end
# File lib/citrus.rb, line 1394 1394: def inspect 1395: string.inspect 1396: end
Returns the length of this match.
# File lib/citrus.rb, line 1313 1313: def length 1314: events.last 1315: end
Returns an array of all immediate submatches of this match.
# File lib/citrus.rb, line 1340 1340: def matches 1341: process_events! unless @matches 1342: @matches 1343: end
Convenient shortcut for input.source
# File lib/citrus.rb, line 1318 1318: def source 1319: (input.respond_to?(:source) && input.source) || input 1320: end
Returns the slice of the source text that this match captures.
# File lib/citrus.rb, line 1323 1323: def string 1324: @string ||= input.to_str[offset, length] 1325: end
Returns this match plus all sub matches in an array.
# File lib/citrus.rb, line 1365 1365: def to_a 1366: [self] + matches 1367: end