Class: Parslet::Pattern

### Home Classes Methods

### In Files

- lib/parslet/pattern.rb

### Parent

Object

### Namespace

- CLASS Parslet::Pattern::SequenceBind
- CLASS Parslet::Pattern::SimpleBind
- CLASS Parslet::Pattern::SubtreeBind

### Methods

- ::new
- #element_match
- #element_match_ary_single
- #element_match_binding
- #element_match_hash
- #match

### Files

- README

### Class/Module Index

Quicksearch

- Parslet
- Parslet::Atoms
- Parslet::Atoms::Alternative
- Parslet::Atoms::Base
- Parslet::Atoms::CanFlatten
- Parslet::Atoms::Capture
- Parslet::Atoms::Context
- Parslet::Atoms::DSL
- Parslet::Atoms::Dynamic
- Parslet::Atoms::Entity
- Parslet::Atoms::Lookahead
- Parslet::Atoms::Named
- Parslet::Atoms::Precedence
- Parslet::Atoms::Re
- Parslet::Atoms::Repetition
- Parslet::Atoms::Scope
- Parslet::Atoms::Sequence
- Parslet::Atoms::Str
- Parslet::Cause
- Parslet::ClassMethods
- Parslet::DelayedMatchConstructor
- Parslet::ErrorReporter
- Parslet::ErrorReporter::Deepest
- Parslet::ErrorReporter::Tree
- Parslet::Expression
- Parslet::Expression::Treetop
- Parslet::Expression::Treetop::Parser
- Parslet::Expression::Treetop::Transform
- Parslet::ParseFailed
- Parslet::Parser
- Parslet::Parser::PrettyPrinter
- Parslet::Parser::Visitors
- Parslet::Parser::Visitors::Citrus
- Parslet::Parser::Visitors::Treetop
- Parslet::Pattern
- Parslet::Pattern::SequenceBind
- Parslet::Pattern::SimpleBind
- Parslet::Pattern::SubtreeBind
- Parslet::Scope
- Parslet::Scope::Binding
- Parslet::Scope::NotFound
- Parslet::Slice
- Parslet::Source
- Parslet::Source::LineCache
- Parslet::Source::RangeSearch
- Parslet::Transform
- Parslet::Transform::Context

No matching classes.

# Parslet::Pattern

Matches trees against expressions. Trees are formed by arrays and hashes for expressing membership and sequence. The leafs of the tree are other classes.

A tree issued by the parslet library might look like this:

    {
      :function_call => {
        :name => 'foobar',
        :args => [1, 2, 3]
      }
    }

A pattern that would match against this tree would be:

    { :function_call => { :name => simple(:name), :args => sequence(:args) }}

Note that Parslet::Pattern only matches at a given subtree; it wont try to match recursively. To do that, please use Parslet::Transform.

### Public Class Methods

new(pattern) click to toggle source

    # File lib/parslet/pattern.rb, line 22
    def initialize(pattern)
      @pattern = pattern
    end

### Public Instance Methods

element_match(tree, exp, bindings) click to toggle source

Returns true if the tree element given by `tree` matches the expression given by `exp`. This match must respect bindings already made in `bindings`. Note that bindings is carried along and modified.

@api private

    # File lib/parslet/pattern.rb, line 49
    def element_match(tree, exp, bindings)
      # p [:elm, tree, exp]
      case [tree, exp].map { |e| e.class }
        when [Hash,Hash]
          return element_match_hash(tree, exp, bindings)
        when [Array,Array]
          return element_match_ary_single(tree, exp, bindings)
      else
        # If elements match exactly, then that is good enough in all cases
        return true if tree == exp

        # If exp is a bind variable: Check if the binding matches
        if exp.respond_to?(:can_bind?) && exp.can_bind?(tree)
          return element_match_binding(tree, exp, bindings)
        end

        # Otherwise: No match (we don't know anything about the element
        # combination)
        return false
      end
    end

element_match_ary_single(sequence, exp, bindings) click to toggle source

@api private

    # File lib/parslet/pattern.rb, line 89
    def element_match_ary_single(sequence, exp, bindings)
      return false if sequence.size != exp.size

      return sequence.zip(exp).all? { |elt, subexp|
        element_match(elt, subexp, bindings) }
    end

element_match_binding(tree, exp, bindings) click to toggle source

@api private

    # File lib/parslet/pattern.rb, line 73
    def element_match_binding(tree, exp, bindings)
      var_name = exp.variable_name

      # TODO test for the hidden :_ feature.
      if var_name && bound_value = bindings[var_name]
        return bound_value == tree
      end

      # New binding:
      bindings.store var_name, tree

      return true
    end

element_match_hash(tree, exp, bindings) click to toggle source

@api private

    # File lib/parslet/pattern.rb, line 98
    def element_match_hash(tree, exp, bindings)
      # Early failure when one hash is bigger than the other
      return false unless exp.size == tree.size

      # We iterate over expected pattern, since we demand that the keys that
      # are there should be in tree as well.
      exp.each do |expected_key, expected_value|
        return false unless tree.has_key? expected_key

        # Recurse into the value and stop early on failure
        value = tree[expected_key]
        return false unless element_match(value, expected_value, bindings)
      end

      return true
    end

match(subtree, bindings=nil) click to toggle source

Decides if the given subtree matches this pattern. Returns the bindings made on a successful match or nil if the match fails. If you specify bindings to be a hash, the mappings in it will be treated like bindings made during an attempted match.

    Pattern.new('a').match('a', :foo => 'bar') # => { :foo => 'bar' }

@param subtree [String, Hash, Array] poro subtree returned by a parse @param bindings [Hash] variable bindings to be verified @return [Hash, nil] On success: variable bindings that allow a match. On

    failure: nil

    # File lib/parslet/pattern.rb, line 38
    def match(subtree, bindings=nil)
      bindings = bindings && bindings.dup || Hash.new
      return bindings if element_match(subtree, @pattern, bindings)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.