Class: Parslet::Atoms::Lookahead

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

Overview

Either positive or negative lookahead, doesn’t consume its input.

Example:

str('foo').present? # matches when the input contains 'foo', but leaves it

Constant Summary

Constants included from Precedence

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

Instance Attribute Summary collapse

Attributes inherited from Base

#label

Instance Method Summary collapse

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(bound_parslet, positive = true) ⇒ Lookahead

Returns a new instance of Lookahead.



11
12
13
14
15
16
17
# File 'lib/parslet/atoms/lookahead.rb', line 11

def initialize(bound_parslet, positive=true)
  super()
  
  # Model positive and negative lookahead by testing this flag.
  @positive = positive
  @bound_parslet = bound_parslet
end

Instance Attribute Details

#bound_parsletObject (readonly)

Returns the value of attribute bound_parslet.



9
10
11
# File 'lib/parslet/atoms/lookahead.rb', line 9

def bound_parslet
  @bound_parslet
end

#positiveObject (readonly)

Returns the value of attribute positive.



8
9
10
# File 'lib/parslet/atoms/lookahead.rb', line 8

def positive
  @positive
end

Instance Method Details

#accept(visitor) ⇒ Object

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



69
70
71
# File 'lib/parslet/atoms/visitor.rb', line 69

def accept(visitor)
  visitor.visit_lookahead(positive, bound_parslet)
end

#error_msgsObject



19
20
21
22
23
24
# File 'lib/parslet/atoms/lookahead.rb', line 19

def error_msgs
  @error_msgs ||= {
    :positive => ["Input should start with ", bound_parslet],
    :negative => ["Input should not start with ", bound_parslet]
  }
end

#to_s_inner(prec) ⇒ Object



47
48
49
50
51
# File 'lib/parslet/atoms/lookahead.rb', line 47

def to_s_inner(prec)
  @char = positive ? '&' : '!'

  "#{@char}#{bound_parslet.to_s(prec)}"
end

#try(source, context, consume_all) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/parslet/atoms/lookahead.rb', line 26

def try(source, context, consume_all)
  rewind_pos  = source.bytepos
  error_pos   = source.pos

  success, _ = bound_parslet.apply(source, context, consume_all)
  
  if positive
    return succ(nil) if success
    return context.err_at(self, source, error_msgs[:positive], error_pos)
  else
    return succ(nil) unless success
    return context.err_at(self, source, error_msgs[:negative], error_pos)
  end
  
# This is probably the only parslet that rewinds its input in #try.
# Lookaheads NEVER consume their input, even on success, that's why. 
ensure 
  source.bytepos = rewind_pos
end