lib/import/shake_grammar/lexer.rb in tracksperanto-3.2.1 vs lib/import/shake_grammar/lexer.rb in tracksperanto-3.2.2

- old
+ new

@@ -1,6 +1,8 @@ # -*- encoding : utf-8 -*- +require 'bychar' + module Tracksperanto::ShakeGrammar class WrongInputError < RuntimeError; end # Since Shake uses a C-like language for it's scripts we rig up a very sloppy # but concise C-like lexer to cope @@ -23,13 +25,20 @@ def initialize(with_io, sentinel = nil, limit_to_one_stmt = false, stack_depth = 0) # We parse byte by byte, but reading byte by byte is very slow. We therefore use a buffering reader # that will cache in chunks, and then read from there byte by byte. This yields a substantial speedup (4.9 seconds for the test # as opposed to 7.9 without this). We do check for the proper class only once so that when we use nested lexers # we only wrap the passed IO once, and only if necessary. - with_io = Tracksperanto::BufferingReader.new(with_io) unless with_io.respond_to?(:read_one_byte) + with_io = Bychar::Reader.new(with_io) unless with_io.respond_to?(:read_one_byte) @io, @stack, @buf, @sentinel, @limit_to_one_stmt, @stack_depth = with_io, [], '', sentinel, limit_to_one_stmt, stack_depth - catch(STOP_TOKEN) { parse until @io.data_exhausted? } + + catch(STOP_TOKEN) do + begin + loop { parse } + rescue Bychar::EOFError + end + end + @in_comment ? consume_comment! : consume_atom! end private @@ -42,10 +51,10 @@ erase_buffer end def parse - c = @io.read_one_byte + c = @io.read_one_byte! if @buf.length > MAX_BUFFER_SIZE # Wrong format and the buffer is filled up, bail raise WrongInputError, "Atom buffer overflow at #{MAX_BUFFER_SIZE} bytes, this is definitely not a Shake script" end