Sha256: da53fd00d136ba3347e254d14802d8e961f064c8eb59a531db0b304a32ad5689

Contents?: true

Size: 1.74 KB

Versions: 2

Compression:

Stored size: 1.74 KB

Contents

module SXP; class Reader
  ##
  # A basic S-expression parser.
  class Basic < Reader
    LPARENS  = [?(].freeze
    RPARENS  = [?)].freeze
    ATOM     = /^[^\s()]+/.freeze
    RATIONAL = /^([+-]?\d+)\/(\d+)$/.freeze
    DECIMAL  = /^[+-]?(\d*)?\.\d*$/.freeze
    INTEGER  = /^[+-]?\d+$/.freeze

    ##
    # @return [Object]
    def read_token
      case peek_char
        when ?(, ?) then [:list, read_char]
        when ?"     then [:atom, read_string] #"
        else super
      end
    end

    ##
    # @return [Object]
    def read_atom
      case buffer = read_literal
        when '.'      then buffer.to_sym
        when RATIONAL then Rational($1.to_i, $2.to_i)
        when DECIMAL  then Float(buffer) # FIXME?
        when INTEGER  then Integer(buffer)
        else buffer.to_sym
      end
    end

    ##
    # @return [String]
    def read_string
      buffer = String.new
      skip_char # '"'
      until peek_char == ?" #"
        buffer <<
          case char = read_char
            when ?\\ then read_character
            else char
          end
      end
      skip_char # '"'
      buffer
    end

    ##
    # @return [String]
    def read_character
      case char = read_char
        when ?b  then ?\b
        when ?f  then ?\f
        when ?n  then ?\n
        when ?r  then ?\r
        when ?t  then ?\t
        when ?u  then read_chars(4).to_i(16).chr
        when ?U  then read_chars(8).to_i(16).chr
        when ?"  then char #"
        when ?\\ then char
        else char
      end
    end

    ##
    # @return [String]
    def read_literal
      grammar = self.class.const_get(:ATOM)
      buffer = String.new
      buffer << read_char while !eof? && peek_char.chr =~ grammar
      buffer
    end
  end # class Basic
end; end # class SXP::Reader

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
sxp-0.0.7 lib/sxp/reader/basic.rb
sxp-0.0.6 lib/sxp/reader/basic.rb