#!/usr/bin/ruby # encoding: utf-8 module ANTLR3 =begin rdoc ANTLR3::Main::InteractiveStringStream A special stream used in the interactive mode of the Main scripts. It uses Readline (if available) or standard IO#gets to fetch data on demand. =end class InteractiveStringStream < StringStream if RUBY_VERSION =~ /^1\.9/ # creates a new StringStream object where +data+ is the string data to stream. # accepts the following options in a symbol-to-value hash: # # [:file or :name] the (file) name to associate with the stream; default: '(string)' # [:line] the initial line number; default: +1+ # [:column] the initial column number; default: +0+ # def initialize( options = {}, &block ) # for 1.9 @string = '' @data = [] @position = options.fetch :position, 0 @line = options.fetch :line, 1 @column = options.fetch :column, 0 @markers = [] mark @initialized = @eof = false @readline = block or raise( ArgumentError, "no line-reading block was provided" ) @name ||= options[ :file ] || options[ :name ] || '(interactive)' end def readline @initialized = true unless @eof if line = @readline.call line = line.to_s.encode( Encoding::UTF_8 ) @string << line @data.concat( line.codepoints.to_a ) return true else @eof = true return false end end end else # creates a new StringStream object where +data+ is the string data to stream. # accepts the following options in a symbol-to-value hash: # # [:file or :name] the (file) name to associate with the stream; default: '(string)' # [:line] the initial line number; default: +1+ # [:column] the initial column number; default: +0+ # def initialize( options = {}, &block ) @string = @data = '' @position = options.fetch :position, 0 @line = options.fetch :line, 1 @column = options.fetch :column, 0 @markers = [] mark @initialized = @eof = false @readline = block or raise( ArgumentError, "no line-reading block was provided" ) @name ||= options[ :file ] || options[ :name ] || '(interactive)' end def readline @initialized = true unless @eof if line = @readline.call @data << line.to_s return true else @eof = true return false end end end end private :readline def consume @position < @data.size and return( super ) unless @eof readline consume end end def peek( i = 1 ) i.zero? and return 0 i += 1 if i < 0 index = @position + i - 1 index < 0 and return 0 if index < @data.size char = @data[ index ] elsif readline peek( i ) else EOF end end def look( i = 1 ) peek( i ).chr rescue EOF end def substring( start, stop ) fill_through( stop ) @string[ start .. stop ] end private def fill_through( position ) @eof and return if @position < 0 then fill_out else readline until ( @data.size > @position or @eof ) end end def fill_out @eof and return readline until @eof end end end