1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#
# scanner.rb
#
# Copyright (c) 1999,2000 Minero Aoki <aamine@loveruby.net>
#
# This program is free software.
# You can distribute/modify this program under the terms of
# the GNU Lesser General Public License version 2 or later.
#
require 'strscan'
class Scanner
EOL = /\A(?:\n|\r\n|\r)/
SPACE = /\A[ \t]+/
LINE = /\A[^\r\n]*(?:\n|\r\n|\r|\z)/
QPAIR = /\A\\./
CHAR = /\A./
def initialize( str, fname = nil )
@avoid_gc = str # no need but
@scan = StringScanner.new( str, false )
@filename = fname
@lineno = 1
@debug = false
end
attr :lineno
attr :filename, true
attr :debug, true
def scanner
@scan
end
def scan
end
private
def do_scan_string( contexp, termexp, preserve )
ret = ''
tmp = nil
qpair = QPAIR
while true do
if tmp = @scan.scan( contexp ) then
ret << tmp
end
if tmp = @scan.scan( qpair ) then
ret << (preserve ? tmp : tmp[1..-1])
elsif @scan.skip( termexp )
break
else
scan_error! 'found unterminated string'
end
end
ret
end
def scan_string( right, preserve = true )
do_scan_string( /\A[^\\#{right}]+/, /\A#{right}/, preserve )
end
def scan_Q_string( preserve = true )
do_scan_string( /\A[^\\"]+/, /\A"/, preserve )
end
def scan_error!( mes )
raise ScanError, "#{@filename}:#{@lineno}: #{mes}"
end
def scan_bug!( mes = 'must not happen' )
raise "[Script Bug] #{msg}"
end
def debug_report( arr )
s = arr[0]
printf "%7d %-10s %s\n",
@scan.restsize,
s.respond_to?(:id2name) ? s.id2name : s.inspect,
arr[1].inspect
end
end
|