Class: Parslet::Atoms::Repetition

Inherits:
Base
  • Object
show all
Defined in:
lib/parslet/atoms/repetition.rb,
lib/parslet/atoms/visitor.rb

Overview

Matches a parslet repeatedly.

Example:

str('a').repeat(1,3)  # matches 'a' at least once, but at most three times
str('a').maybe        # matches 'a' if it is present in the input (repeat(0,1))

Constant Summary

Constants included from Precedence

Precedence::ALTERNATE, Precedence::BASE, Precedence::LOOKAHEAD, Precedence::OUTER, Precedence::REPETITION, Precedence::SEQUENCE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#apply, #inspect, #parse, #parse_with_debug, precedence, #setup_and_apply, #to_s

Methods included from CanFlatten

#flatten, #flatten_repetition, #flatten_sequence, #foldl, #merge_fold, #warn_about_duplicate_keys

Methods included from DSL

#>>, #absent?, #as, #maybe, #present?, #repeat, #|

Constructor Details

#initialize(parslet, min, max, tag = :repetition) ⇒ Repetition

Returns a new instance of Repetition.



11
12
13
14
15
16
17
18
19
20
# File 'lib/parslet/atoms/repetition.rb', line 11

def initialize(parslet, min, max, tag=:repetition)
  super()

  @parslet = parslet
  @min, @max = min, max
  @tag = tag
  @error_msgs = {
    :minrep  => "Expected at least #{min} of #{parslet.inspect}"
  }
end

Instance Attribute Details

#maxObject (readonly)

Returns the value of attribute max.



10
11
12
# File 'lib/parslet/atoms/repetition.rb', line 10

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



10
11
12
# File 'lib/parslet/atoms/repetition.rb', line 10

def min
  @min
end

#parsletObject (readonly)

Returns the value of attribute parslet.



10
11
12
# File 'lib/parslet/atoms/repetition.rb', line 10

def parslet
  @parslet
end

Instance Method Details

#accept(visitor) ⇒ Object

Call back visitors #visit_repetition method. See parslet/export for an example.



51
52
53
# File 'lib/parslet/atoms/visitor.rb', line 51

def accept(visitor)
  visitor.visit_repetition(@tag, min, max, parslet)
end

#to_s_inner(prec) ⇒ Object



56
57
58
59
60
61
# File 'lib/parslet/atoms/repetition.rb', line 56

def to_s_inner(prec)
  minmax = "{#{min}, #{max}}"
  minmax = '?' if min == 0 && max == 1

  parslet.to_s(prec) + minmax
end

#try(source, context) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/parslet/atoms/repetition.rb', line 22

def try(source, context)
  occ = 0
  accum = [@tag]   # initialize the result array with the tag (for flattening)
  start_pos = source.pos
  
  break_on = nil
  loop do
    success, value = parslet.apply(source, context)

    break_on = value
    break unless success

    occ += 1
    accum << value
    
    # If we're not greedy (max is defined), check if that has been reached. 
    return succ(accum) if max && occ>=max
  end
  
  # Last attempt to match parslet was a failure, failure reason in break_on.
  
  # Greedy matcher has produced a failure. Check if occ (which will
  # contain the number of sucesses) is >= min.
  return context.err_at(
    self, 
    source, 
    @error_msgs[:minrep], 
    start_pos, 
    [break_on]) if occ < min
    
  return succ(accum)
end