def write_scanner f = scanner_io
flag = ""
flag += "i" if @opt['--ignorecase']
f.printf REX_HEADER, Rexical::VERSION, grammar_file
unless @opt['--independent']
f.printf "require 'racc/parser'\n"
end
@scanner_header.each_line do |s|
f.print s
end
if @module_name
f.puts "module #{@module_name}"
end
if @opt['--independent']
f.puts "class #{@class_name}"
else
f.puts "class #{@class_name} < Racc::Parser"
end
f.print REX_UTIL
f.print "\ndef next_token\nreturn if @ss.eos?\n\ntext = @ss.peek(1)\n@lineno += 1 if text == \"\\\\n\"\ntoken = case @state\n"
exclusive_states.each do |es|
f.printf "when \#{es ? es.to_s : \"nil\"}\ncase\n"
rules.each do |rule|
exclusive_state, start_state, rule_expr, rule_action = *rule
if es == exclusive_state
if rule_action
if start_state
f.print "when (state == \#{start_state}) and (text = @ss.scan(/\#{rule_expr}/\#{flag}))\naction \#{rule_action}\n\n"
else
f.print "when (text = @ss.scan(/\#{rule_expr}/\#{flag}))\naction \#{rule_action}\n\n"
end
else
if start_state
f.print "when (state == \#{start_state}) and (text = @ss.scan(/\#{rule_expr}/\#{flag}))\n;\n\n"
else
f.print "when (text = @ss.scan(/\#{rule_expr}/\#{flag}))\n;\n\n"
end
end
end
end
f.print "else\ntext = @ss.string[@ss.pos .. -1]\nraise ScanError, \"can not match: '\" + text + \"'\"\nend # if\n\n"
end
f.print "else\nraise ScanError, \"undefined state: '\" + state.to_s + \"'\"\nend # case state\n"
if @opt['--debug']
f.print "p token\n"
end
f.print "token\nend # def next_token\n\n"
@scanner_inner.each_line do |s|
f.print s
end
f.puts "end # class"
f.puts "end # module" if @module_name
@scanner_footer.each_line do |s|
f.print s
end
f.printf REX_STUB, @class_name, '"%s:%d:%s\n"' if @opt['--stub']
f.close
end