Source

par / lib / par / source.rb

require 'strscan'

module Par
  # Source consumes a string bit by bit. It defines methods to consume a
  # string conditionally or unconditionally, never touching the original
  # string,  instead slicing it up into small results.
  #
  # String access methods are relative to the current position, unless
  # mentioned otherwise:
  #
  # * #n reads n characters
  #
  class Source
    attr_reader :str 
    attr_reader :pos

    def initialize str
      @scanner = StringScanner.new(str)
    end

    def match pattern
      pattern = Regexp.new(
        Regexp.escape(pattern)) if pattern.respond_to? :to_str

      if match = @scanner.scan(pattern) 
        return Par.result(match)
      end

      Par.bottom
    end
    
    def n n
      match = @scanner.scan(/.{#{n}}/)
      match && Par.result(match) || Par.bottom
    end

    def conditional_rewind
      old_pos = pos
      r = yield
      old_pos = pos if r != Par.bottom

      return r
    ensure
      @scanner.pos = old_pos
    end
    alias :cr :conditional_rewind

    def either &block
      Lazy.new self, &block
    end

    def rest
      @scanner.rest
    end
    def pos
      @scanner.pos
    end
  end
end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.