lib/literal_parser.rb
# Scans the string for a single value and advances the parsers position
#
# @return [Object] the scanned value
#
# @raise [LiteralParser::SyntaxError]
#   When no valid ruby object could be scanned at the given position, a
#   LiteralParser::SyntaxError is raised.
Scans the string for a single value and advances the parsers position
Scans the string for a single value and advances the parsers position
def scan_value
    case
      when @scanner.scan(RArrayBegin)    then
        value = []
        @scanner.scan(RArrayVoid)
        if @scanner.scan(RArrayEnd)
          value
        else
          value << scan_value
          while @scanner.scan(RArraySeparator)
            value << scan_value
          end
          raise SyntaxError, "Expected ]" unless @scanner.scan(RArrayVoid) && @scanner.scan(RArrayEnd)
          value
        end
      when @scanner.scan(RHashBegin)    then
        value = {}
        @scanner.scan(RHashVoid)
        if @scanner.scan(RHashEnd)
          value
        else
          if @scanner.scan(RHashKeySymbol)
            key = @scanner[1].to_sym
            @scanner.scan(RHashVoid)
          else
            key = scan_value
            raise SyntaxError, "Expected =>" unless @scanner.scan(RHashArrow)
          end
          val = scan_value
          value[key] = val
          while @scanner.scan(RHashSeparator)
            if @scanner.scan(RHashKeySymbol)
              key = @scanner[1].to_sym
              @scanner.scan(RHashVoid)
            else
              key = scan_value
              raise SyntaxError, "Expected =>" unless @scanner.scan(RHashArrow)
            end
            val = scan_value
            value[key] = val
          end
          raise SyntaxError, "Expected }" unless @scanner.scan(RHashVoid) && @scanner.scan(RHashEnd)
          value
        end
      when @scanner.scan(RConstant)      then eval("#{@constant_base}::#{@scanner[0]}") 
      when @scanner.scan(RNil)           then nil
      when @scanner.scan(RTrue)          then true
      when @scanner.scan(RFalse)         then false
      when @scanner.scan(RDateTime)      then
        Time.mktime(@scanner[1], @scanner[2], @scanner[3], @scanner[4], @scanner[5], @scanner[6])
      when @scanner.scan(RDate)          then
        date = @scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i
        Date.civil(*date)
      when @scanner.scan(RTime)          then
        now = Time.now
        Time.mktime(now.year, now.month, now.day, @scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i)
      when @scanner.scan(RFloat)         then Float(@scanner.matched.delete('^0-9.e-'))
      when @scanner.scan(RBigDecimal)    then
        data = @scanner.matched.delete('^0-9.-')
        @use_big_decimal ? BigDecimal(data) : Float(data)
      when @scanner.scan(ROctalInteger)  then Integer(@scanner.matched.delete('^0-9-'))
      when @scanner.scan(RHexInteger)    then Integer(@scanner.matched.delete('^xX0-9A-Fa-f-'))
      when @scanner.scan(RBinaryInteger) then Integer(@scanner.matched.delete('^bB01-'))
      when @scanner.scan(RInteger)       then @scanner.matched.delete('^0-9-').to_i
      when @scanner.scan(RRegexp)        then
        source = @scanner[1]
        flags  = 0
        lang   = nil
        if @scanner[2] then
          flags |= Regexp::IGNORECASE if @scanner[2].include?('i')
          flags |= Regexp::EXTENDED if @scanner[2].include?('m')
          flags |= Regexp::MULTILINE if @scanner[2].include?('x')
          lang   = @scanner[2].delete('^nNeEsSuU')[-1,1]
        end
        Regexp.new(source, flags, lang)
      when @scanner.scan(RSymbol)        then
        case @scanner.matched[1,1]
          when '"'
            @scanner.matched[2..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m|
              DStringEscapes[m]
            }.to_sym
          when "'"
            @scanner.matched[2..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\").to_sym
          else
            @scanner.matched[1..-1].to_sym
        end
      when @scanner.scan(RSString)       then
        @scanner.matched[1..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\")
      when @scanner.scan(RDString)       then
        @scanner.matched[1..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m| DStringEscapes[m] }
      else raise SyntaxError, "Unrecognized pattern: #{@scanner.rest.inspect}"
    end
  end
def scan_value case when @scanner . scan ( RArrayBegin ) then value = [ ] @scanner . scan ( RArrayVoid ) if @scanner . scan ( RArrayEnd ) value else value << scan_value while @scanner . scan ( RArraySeparator ) value << scan_value end raise SyntaxError , "Expected ]" unless @scanner . scan ( RArrayVoid ) && @scanner . scan ( RArrayEnd ) value end when @scanner . scan ( RHashBegin ) then value = { } @scanner . scan ( RHashVoid ) if @scanner . scan ( RHashEnd ) value else if @scanner . scan ( RHashKeySymbol ) key = @scanner [ 1 ] . to_sym @scanner . scan ( RHashVoid ) else key = scan_value raise SyntaxError , "Expected =>" unless @scanner . scan ( RHashArrow ) end val = scan_value value [ key ] = val while @scanner . scan ( RHashSeparator ) if @scanner . scan ( RHashKeySymbol ) key = @scanner [ 1 ] . to_sym @scanner . scan ( RHashVoid ) else key = scan_value raise SyntaxError , "Expected =>" unless @scanner . scan ( RHashArrow ) end val = scan_value value [ key ] = val end raise SyntaxError , "Expected }" unless @scanner . scan ( RHashVoid ) && @scanner . scan ( RHashEnd ) value end when @scanner . scan ( RConstant ) then eval ( "#{@constant_base}::#{@scanner[0]}" ) when @scanner . scan ( RNil ) then nil when @scanner . scan ( RTrue ) then true when @scanner . scan ( RFalse ) then false when @scanner . scan ( RDateTime ) then Time . mktime ( @scanner [ 1 ] , @scanner [ 2 ] , @scanner [ 3 ] , @scanner [ 4 ] , @scanner [ 5 ] , @scanner [ 6 ] ) when @scanner . scan ( RDate ) then date = @scanner [ 1 ] . to_i , @scanner [ 2 ] . to_i , @scanner [ 3 ] . to_i Date . civil ( * date ) when @scanner . scan ( RTime ) then now = Time . now Time . mktime ( now . year , now . month , now . day , @scanner [ 1 ] . to_i , @scanner [ 2 ] . to_i , @scanner [ 3 ] . to_i ) when @scanner . scan ( RFloat ) then Float ( @scanner . matched . delete ( '^0-9.e-' ) ) when @scanner . scan ( RBigDecimal ) then data = @scanner . matched . delete ( '^0-9.-' ) @use_big_decimal ? BigDecimal ( data ) : Float ( data ) when @scanner . scan ( ROctalInteger ) then Integer ( @scanner . matched . delete ( '^0-9-' ) ) when @scanner . scan ( RHexInteger ) then Integer ( @scanner . matched . delete ( '^xX0-9A-Fa-f-' ) ) when @scanner . scan ( RBinaryInteger ) then Integer ( @scanner . matched . delete ( '^bB01-' ) ) when @scanner . scan ( RInteger ) then @scanner . matched . delete ( '^0-9-' ) . to_i when @scanner . scan ( RRegexp ) then source = @scanner [ 1 ] flags = 0 lang = nil if @scanner [ 2 ] then flags |= Regexp :: IGNORECASE if @scanner [ 2 ] . include? ( 'i' ) flags |= Regexp :: EXTENDED if @scanner [ 2 ] . include? ( 'm' ) flags |= Regexp :: MULTILINE if @scanner [ 2 ] . include? ( 'x' ) lang = @scanner [ 2 ] . delete ( '^nNeEsSuU' ) [ - 1 , 1 ] end Regexp . new ( source , flags , lang ) when @scanner . scan ( RSymbol ) then case @scanner . matched [ 1 , 1 ] when '"' @scanner . matched [ 2 .. - 2 ] . gsub ( / \\ (?:[0-3]? \d \d ?|x[A-Fa-f \d ]{2}|.) / ) { | m | DStringEscapes [ m ] } . to_sym when "'" @scanner . matched [ 2 .. - 2 ] . gsub ( / \\ ' / , "'" ) . gsub ( / \\ \\ / , "\\" ) . to_sym else @scanner . matched [ 1 .. - 1 ] . to_sym end when @scanner . scan ( RSString ) then @scanner . matched [ 1 .. - 2 ] . gsub ( / \\ ' / , "'" ) . gsub ( / \\ \\ / , "\\" ) when @scanner . scan ( RDString ) then @scanner . matched [ 1 .. - 2 ] . gsub ( / \\ (?:[0-3]? \d \d ?|x[A-Fa-f \d ]{2}|.) / ) { | m | DStringEscapes [ m ] } else raise SyntaxError , "Unrecognized pattern: #{@scanner.rest.inspect}" end end
Scans the string for a single value and advances the parsers position
Scans the string for a single value and advances the parsers position
# yes, I know it's evil, but it's sane due to the regex, also it's less annoying than deep_const_get
the scanned value
the scanned value
Object
[LiteralParser::SyntaxError] When no valid ruby object could be scanned at the given position, a LiteralParser::SyntaxError is raised.
[ LiteralParser :: SyntaxError ] When no valid ruby object could be scanned at the given position a LiteralParser :: SyntaxError is raised .