#!/usr/bin/ruby $Debug=true require "rubylexer" require "getoptlong" require "pp" class RubyLexer class Token def verify_offset(fd); false end def check_for_error; end end class LexerError'%x', '['=>'%w', '{'=>'%W', '"'=>/('|%[^a-pr-z0-9])/i, '/'=>'%r'} def verify_offset(fd) str=fd.read(2) @char==str[0,1] or FANCY_QUOTE_BEGINNINGS[@char]===str or return false verify_subtoken_offsets(fd) end def verify_subtoken_offsets(fd) #verify offsets of subtokens 1.step(@elems.length-1,2) { |i| @elems[i].verify_offset(fd) or raise LexerError} return true end def check_for_error 1.step(@elems.size-1,2){|idx| @elems[idx].check_for_error } super end end class RubyCode def verify_offset(fd) thistok=nexttok=endpos=nil @ident.each_index{ |tok_i| thistok,nexttok=@ident[tok_i,2] endpos=nexttok ? nexttok.offset : thistok.offset+thistok.to_s.size check_offset(thistok,fd,endpos) } assert nexttok.nil? assert thistok.object_id==@ident.last.object_id assert WToken===thistok fd.pos=endpos end def check_for_error @ident.each{|tok| tok.check_for_error } end end class NumberToken def verify_offset(fd) /^[0-9?+-]$/===fd.read(1) end end #class ZwToken # def to_s # $ShowImplicit ? explicit_form : super # end #end end public def check_offset(tok,file=nil,endpos=nil) file||=@file endpos||=(@moretokens.empty?)? file.pos : @moretokens[0].offset oldpos=file.pos assert Integer===tok.offset assert Integer===endpos endpos>=tok.offset or raise RubyLexer::LexerError, "expected >=#{tok.offset}, got #{endpos}, "\ "token #{tok}:#{tok.class}" file.pos=tok.offset tok.verify_offset(file) or raise RubyLexer::LexerError, "couldn't check offset of token #{tok.class}: #{tok}" case tok when RubyLexer::StringToken,RubyLexer::NumberToken, RubyLexer::HereBodyToken,RubyLexer::SymbolToken: #do nothing else (file.pos==endpos) or raise RubyLexer::LexerError, "positions don't line up, expected #{endpos}, got #{file.pos}, token: #{tok}" end file.pos=oldpos end def tokentest(name,lexertype,pprinter,input=File.open(name),output=$stdout) input ||= File.open(name) if output!=$stdout output=File.open(output,'w') end fd=input #File.open(name) {|fd| lxr=lexertype.new(name,fd,1) begin tok=lxr.get1token lxr.check_offset(tok) tok.check_for_error pprinter.pprint(tok,output) end until RubyLexer::EoiToken===tok #hack for SimpleTokenPrinter.... print "\n" if RubyLexer::NewlineToken===lxr.last_operative_token and RubyLexer::SimpleTokenPrinter===pprinter # unless lxr.balanced_braces? # raise "unbalanced braces at eof" # end #} output.close unless output==$stdout end #$ShowImplicit=false if __FILE__==$0 sep,line,showzw='',1,0 # lexertype= RumaLexer if defined? RumaLexer lexertype=RubyLexer insertnils=fd=name=nil pprinter=RubyLexer::SimpleTokenPrinter opts=GetoptLong.new \ ["--eval","-e", GetoptLong::REQUIRED_ARGUMENT], # ["--ruby","-r", GetoptLong::NO_ARGUMENT], ["--keepws","-k", GetoptLong::NO_ARGUMENT], ["--maxws","-m", GetoptLong::NO_ARGUMENT], ["--implicit","-i", GetoptLong::NO_ARGUMENT], ["--implicit-all", GetoptLong::NO_ARGUMENT] saweval=nil opts.each do|opt,arg| case opt when '--eval' then tokentest('-e',lexertype,pprinter.new(sep,line,showzw),arg) saweval=true # when '--ruby' then lexertype=RubyLexer when '--keepws' then pprinter= RubyLexer::KeepWsTokenPrinter when '--maxws' then pprinter= RubyLexer::KeepWsTokenPrinter;sep=' ' when '--implicit' then showzw=1 when '--implicit-all' then showzw=2 else raise :impossible end end pprinter =pprinter.new(sep,line,showzw) ARGV.empty? ? saweval || tokentest('-',lexertype,pprinter,$stdin) : ARGV.each{|fn| tokentest(fn,lexertype,pprinter) } # ARGV.first[/[_.]rb$/i] and lexertype=RubyLexer #filename with _rb are special hack end