diff options
Diffstat (limited to 'runtime/Ruby/lib/antlr3/streams/interactive.rb')
-rwxr-xr-x | runtime/Ruby/lib/antlr3/streams/interactive.rb | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/runtime/Ruby/lib/antlr3/streams/interactive.rb b/runtime/Ruby/lib/antlr3/streams/interactive.rb new file mode 100755 index 0000000..3606050 --- /dev/null +++ b/runtime/Ruby/lib/antlr3/streams/interactive.rb @@ -0,0 +1,136 @@ +#!/usr/bin/ruby +# encoding: utf-8 + +module ANTLR3 + +=begin rdoc ANTLR3::Main::InteractiveStringStream + +A special stream used in the <b>interactive mode</b> 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: <tt>'(string)'</tt> + # [: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: <tt>'(string)'</tt> + # [: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 |