XPR_FNAME, EXPR_DOT
	  @lex_state = EXPR_ARG
	else
	  @lex_state = EXPR_BEG
	end
      end
      tk
    end

    @OP.def_rules("'", '"') do
      |op, io|
      identify_string(op)
    end

    @OP.def_rules("`") do
      |op, io|
      if @lex_state == EXPR_FNAME
	Token(op)
      else
	identify_string(op)
      end
    end

    @OP.def_rules('?') do
      |op, io|
      if @lex_state == EXPR_END
	@lex_state = EXPR_BEG
	Token(TkQUESTION)
      else
	ch = getc
	if @lex_state == EXPR_ARG && ch =~ /\s/
	  ungetc
	  @lex_state = EXPR_BEG;
	  Token(TkQUESTION)
	else
	  if (ch == '\\') 
	    read_escape
	  end
	  @lex_state = EXPR_END
	  Token(TkINTEGER)
	end
      end
    end

    @OP.def_rules("&", "&&", "|", "||") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op)
    end
    
    @OP.def_rules("+=", "-=", "*=", "**=", 
		  "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
      |op, io|
      @lex_state = EXPR_BEG
      op =~ /^(.*)=$/
      Token(TkOPASGN, $1)
    end

    @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do
      |op, io|
      Token(op)
    end

    @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do
      |op, io|
      Token(op)
    end

    @OP.def_rules("+", "-") do
      |op, io|
      catch(:RET) do
	if @lex_state == EXPR_ARG
	  if @space_seen and peek(0) =~ /[0-9]/
	    throw :RET, identify_number
	  else
	    @lex_state = EXPR_BEG
	  end
	elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
	  throw :RET, identify_number
	else
	  @lex_state = EXPR_BEG
	end
	Token(op)
      end
    end

    @OP.def_rule(".") do
      @lex_state = EXPR_BEG
      if peek(0) =~ /[0-9]/
	ungetc
	identify_number
      else
	# for "obj.if" etc.
	# (JP: obj.if 