def matchQuotelike( prefix, matchRawRegex )
startPos = self.pointer
debugMsg 2, "matchQuotelike starting at pos = %d: prefix = %s, "\
"matchRawRegex = %s",
startPos, prefix.inspect, matchRawRegex.inspect
rval = oppos = preldpos = ldpos = strpos = rdpos = modpos = nil
raise MatchFailure, "Did not find prefix: /#{prefix.inspect}/" unless
self.skip( prefix )
oppos = self.pointer
if self.check(/^["`']/) || ( matchRawRegex && self.check(%r:/:) )
initial = self.matched
pattern = "%s [^\\%s]* (\\.[^\\%s]*)* %s" %
[ Regexp.quote(initial),
initial, initial,
Regexp.quote(initial) ]
debugMsg 2, "Matching simple quote at offset %d with /%s/" %
[ self.pointer, pattern ]
unless self.scan( /#{pattern}/xism )
raise MatchFailure,
"Did not find closing delimiter to match '%s' at '%s...' (offset %d)" %
[ initial, self.string[ oppos, 20 ].chomp, self.pointer ]
end
modpos = self.pointer
rdpos = modpos - 1
if initial == '/'
pattern = if RUBY_VERSION >= "1.7.3" then /[imoxs]*/ else /[imox]*/ end
self.scan( pattern )
end
rval = {
:prefix => self.string[ startPos, (oppos-startPos) ],
:match => self.string[ oppos .. (self.pointer - 1) ],
:leftDelim => self.string[ oppos, 1 ],
:delimText => self.string[ (oppos+1) .. (rdpos-1) ],
:rightDelim => self.string[ rdpos, 1 ],
:modifiers => self.string[ modpos, (self.pointer-modpos) ],
:suffix => self.string[ self.pointer.. -1 ],
}
elsif self.scan( %r:%[rwqQx]?(?=\S): )
op = self.matched
debugMsg 2, "Matching a real quotelike ('%s') at offset %d" %
[ op, self.pointer ]
modifiers = nil
ldpos = self.pointer
strpos = ldpos + 1
ldel = self.check( /\S/ )
if ldel =~ /[\[(<{]/
rdel = ldel.tr( '[({<', '])}>' )
debugMsg 4, "Left delim is a bracket: %s; looking for compliment: %s" %
[ ldel, rdel ]
self.matchBracketed( '', Regexp::quote(ldel), nil, nil, Regexp::quote(rdel) )
else
debugMsg 4, "Left delim isn't a bracket: '#{ldel}'; looking for closing instance"
self.scan( /#{ldel}[^\\#{ldel}]*(\\.[^\\#{ldel}]*)*#{ldel}/ ) or
raise MatchFailure,
"Can't find a closing delimiter '%s' at '%s...' (offset %d)" %
[ ldel, self.rest[0,20].chomp, self.pointer ]
end
rdelpos = self.pointer - 1
if op == '%r'
pattern = if RUBY_VERSION >= "1.7.3" then /[imoxs]*/ else /[imox]*/ end
modifiers = self.scan( pattern ) || ''
end
rval = {
:prefix => self.string[ startPos, (oppos-startPos) ],
:match => self.string[ oppos .. (self.pointer - 1) ],
:quoteOp => op,
:leftDelim => self.string[ ldpos, 1 ],
:delimText => self.string[ strpos, (rdelpos-strpos) ],
:rightDelim => self.string[ rdelpos, 1 ],
:modifiers => modifiers,
:suffix => self.string[ self.pointer.. -1 ],
}
elsif self.scan( %r:<<(-)?: )
debugMsg 2, "Matching a here-document at offset %d" % self.pointer
op = self.matched
indent = self[1] ? '\s*' : ''
ldpos = self.pointer
label = ''
if self.scan( /[A-Za-z_]\w*/ )
label = self.matched
debugMsg 3, "Setting heredoc terminator to bare identifier '%s'" % label
elsif self.scan( / ' ([^'\\]* (?:\\.[^'\\]*)*) ' /sx ) ||
self.scan( / " ([^"\\]* (?:\\.[^"\\]*)*) " /sx ) ||
self.scan( / ` ([^`\\]* (?:\\.[^`\\]*)*) ` /sx )
label = self[1]
debugMsg 3, "Setting heredoc terminator to quoted identifier '%s'" % label
else
raise MatchFailure,
"Missing heredoc terminator before end of line at "\
"'%s...' (offset %d)" %
[ self.rest[0,20].chomp, self.pointer ]
end
extrapos = self.pointer
self.skip( /.*\n/ )
strpos = self.pointer
debugMsg 3, "Scanning until /\\n#{indent}#{label}\\n/m"
unless self.scan_until( /\n#{indent}#{label}\n/m )
raise MatchFailure,
"Couldn't find heredoc terminator '%s' after '%s...' (offset %d)" %
[ label, self.rest[0,20].chomp, self.pointer ]
end
rdpos = self.pointer - self.matched_size
rval = {
:prefix => self.string[ startPos, (oppos-startPos) ],
:match => self.string[ oppos .. (self.pointer - 1) ],
:quoteOp => op,
:leftDelim => self.string[ ldpos, (extrapos-ldpos) ],
:delimText => self.string[ strpos, (rdpos-strpos) ],
:rightDelim => self.string[ rdpos, (self.pointer-rdpos) ],
:suffix => self.string[ self.pointer.. -1 ],
}
else
raise MatchFailure,
"No quotelike operator found after prefix at '%s...'" %
self.rest[0,20].chomp
end
debugMsg 1, "matchQuotelike succeeded: %s" % rval.inspect
return rval
end