def matchBracketed( prefix, ldel, qdel, quotelike, rdel )
startPos = self.pointer
debugMsg( 2, "matchBracketed starting at pos = %d: prefix = %s, "\
"ldel = %s, qdel = %s, quotelike = %s, rdel = %s",
startPos, prefix.inspect, ldel.inspect, qdel.inspect, quotelike.inspect,
rdel.inspect )
raise MatchFailure, "Did not find prefix: #{prefix.inspect}" unless
self.skip( prefix )
ldelpos = self.pointer
debugMsg( 3, "Found prefix. Left delim pointer at %d", ldelpos )
unless (( delim = self.scan(ldel) ))
raise MatchFailure, "Did not find opening bracket after prefix: '%s' (%d)" %
[ self.string[startPos..ldelpos].chomp, ldelpos ]
end
nesting = [ delim ]
debugMsg( 3, "Found opening bracket. Nesting = %s", nesting.inspect )
while self.rest?
debugMsg( 5, "Starting scan loop. Nesting = %s", nesting.inspect )
if self.skip( /\\./ )
debugMsg( 4, "Skipping backslashed literal at offset %d: '%s'",
self.pointer - 2, self.string[ self.pointer - 2, 2 ].chomp )
next
end
if self.scan(ldel)
delim = self.matched
debugMsg( 4, "Found opening delim %s at offset %d",
delim.inspect, self.pointer - 1 )
nesting.push delim
elsif self.scan(rdel)
delim = self.matched
debugMsg( 4, "Found closing delim %s at offset %d",
delim.inspect, self.pointer - 1 )
if nesting.empty?
raise MatchFailure, "Unmatched closing bracket '%s' at offset %d" %
[ delim, self.pointer - 1 ]
end
expected = nesting.pop.tr( '({[<', ')}]>' )
debugMsg( 4, "Got a '%s' bracket off nesting stack", expected )
if expected != delim
raise MatchFailure, "Mismatched closing bracket at offset %d: "\
"Expected '%s', but found '%s' instead." %
[ self.pointer - 1, expected, delim ]
end
if nesting.empty?
debugMsg( 4, "Finished with scan: nesting stack empty." )
break
end
elsif qdel && self.scan(qdel)
match = self.matched
if self. scan( /[^\\#{match}]*(?:\\.[^\\#{match}]*)*(#{Regexp::quote(match)})/ )
debugMsg( 4, "Skipping quoted chunk. Scan pointer now at offset %d", self.pointer )
next
end
raise MatchFailure, "Unmatched embedded quote (%s) at offset %d" %
[ match, self.pointer - 1 ]
elsif quotelike && self.scanQuotelike
debugMsg( 4, "Matched a quotelike. Scan pointer now at offset %d", self.pointer )
next
else
self.skip( /(?:[a-zA-Z0-9]+|.)/m )
debugMsg 5, "Skipping '%s' at offset %d." %
[ self.matched, self.pointer ]
end
end
unless nesting.empty?
raise MatchFailure, "Unmatched opening bracket(s): %s.. at offset %d" %
[ nesting.join('..'), self.pointer ]
end
rval = {
:match => self.string[ ldelpos .. (self.pointer - 1) ],
:prefix => self.string[ startPos, (ldelpos-startPos) ],
:suffix => self.string[ self.pointer..-1 ],
}
debugMsg 1, "matchBracketed succeeded: %s" % rval.inspect
return rval
end