Class: Parslet::Atoms::Repetition
- 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
-
#max ⇒ Object
readonly
Returns the value of attribute max.
-
#min ⇒ Object
readonly
Returns the value of attribute min.
-
#parslet ⇒ Object
readonly
Returns the value of attribute parslet.
Attributes inherited from Base
Instance Method Summary collapse
-
#accept(visitor) ⇒ Object
Call back visitors #visit_repetition method.
- #error_msgs ⇒ Object
-
#initialize(parslet, min, max, tag = :repetition) ⇒ Repetition
constructor
A new instance of Repetition.
- #to_s_inner(prec) ⇒ Object
- #try(source, context, consume_all) ⇒ Object
Methods inherited from Base
#apply, #cached?, #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, #capture, #ignore, #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 21 22 23 |
# File 'lib/parslet/atoms/repetition.rb', line 11 def initialize(parslet, min, max, tag=:repetition) super() raise ArgumentError, "Asking for zero repetitions of a parslet. (#{parslet.inspect} repeating #{min},#{max})" \ if max == 0 @parslet = parslet @min = min @max = max @tag = tag end |
Instance Attribute Details
#max ⇒ Object (readonly)
Returns the value of attribute max.
10 11 12 |
# File 'lib/parslet/atoms/repetition.rb', line 10 def max @max end |
#min ⇒ Object (readonly)
Returns the value of attribute min.
10 11 12 |
# File 'lib/parslet/atoms/repetition.rb', line 10 def min @min end |
#parslet ⇒ Object (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 |
#error_msgs ⇒ Object
25 26 27 28 29 30 |
# File 'lib/parslet/atoms/repetition.rb', line 25 def error_msgs @error_msgs ||= { minrep: "Expected at least #{min} of #{parslet.inspect}", unconsumed: 'Extra input after last repetition' } end |
#to_s_inner(prec) ⇒ Object
80 81 82 83 84 85 |
# File 'lib/parslet/atoms/repetition.rb', line 80 def to_s_inner(prec) minmax = "{#{min}, #{max}}" minmax = '?' if min == 0 && max == 1 parslet.to_s(prec) + minmax end |
#try(source, context, consume_all) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/parslet/atoms/repetition.rb', line 32 def try(source, context, consume_all) 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, false) 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 successes) is >= min. return context.err_at( self, source, error_msgs[:minrep], start_pos, [break_on]) if occ < min # consume_all is true, that means that we're inside the part of the parser # that should consume the input completely. Repetition failing here means # probably that we didn't. # # We have a special clause to create an error here because otherwise # break_on would get thrown away. It turns out, that contains very # interesting information in a lot of cases. # return context.err( self, source, error_msgs[:unconsumed], [break_on]) if consume_all && source.chars_left>0 return succ(accum) end |