Class: Rattler::Parsers::Sequence

Inherits:
Parser show all
Includes:
Combining
Defined in:
lib/rattler/parsers/sequence.rb

Overview

Sequence combines two or more parsers and matches by trying each one in sequence and failing unless they all succeed.

Author:

  • Jason Arhart

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Combining

#capturing?, #with_ws

Methods inherited from Parser

#capturing?, #labeled?, #one_or_more, #optional, #skip, #variable_capture_count?, #with_ws, #zero_or_more, #|

Methods inherited from Util::Node

#==, [], #[], #attrs, #can_equal?, #child, #children, #each, #empty?, #eql?, #initialize, #inspect, #method_missing, #name, #respond_to?, #same_contents?, #to_graphviz, #with_attrs, #with_attrs!, #with_children

Constructor Details

This class inherits a constructor from Rattler::Util::Node

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Rattler::Util::Node

Class Method Details

.parsed(results, *_) ⇒ Object



21
22
23
# File 'lib/rattler/parsers/sequence.rb', line 21

def self.parsed(results, *_) #:nodoc:
  results.reduce(:&)
end

Instance Method Details

#&(other) ⇒ Object

Return a new parser that tries both this parser and other and fails unless both parse in sequence.

Parameters:

  • other (Parser)

    the next parser to try if this parser succeeds.

Returns:

  • a new parser that tries both this parser and other and fails unless both parse in sequence



60
61
62
# File 'lib/rattler/parsers/sequence.rb', line 60

def &(other)
  Sequence[(children + [other])]
end

#capture_countObject

The number of child parsers that are capturing

Returns:

  • the number of child parsers that are capturing



67
68
69
# File 'lib/rattler/parsers/sequence.rb', line 67

def capture_count
  @capture_count ||= count {|_| _.capturing? }
end

#parse(scanner, rules, scope = {}) ⇒ Object

Try each parser in sequence, and if they all succeed return an array of captured results, or return false if any parser fails.

Returns:

  • an array of captured results of each parser in sequence, or false



32
33
34
# File 'lib/rattler/parsers/sequence.rb', line 32

def parse(scanner, rules, scope = {})
  parse_and_yield_scope scanner, rules, scope
end

#parse_and_yield_scope(scanner, rules, scope = {}) {|scope| ... } ⇒ Object

Yields:

  • (scope)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rattler/parsers/sequence.rb', line 36

def parse_and_yield_scope(scanner, rules, scope = {})
  pos = scanner.pos
  results = []
  for child in children
    if r = child.parse(scanner, rules, scope) {|_| scope = _ }
      results << r unless r == true
    else
      scanner.pos = pos
      return false
    end
  end
  yield scope if block_given?
  case capture_count
  when 0 then true
  when 1 then results[0]
  else results
  end
end