Class: Walrus::Grammar::ParsletMerge

Inherits:
ParsletSequence show all
Defined in:
lib/walrus/grammar/parslet_merge.rb

Constant Summary

Constants inherited from ParsletSequence

Walrus::Grammar::ParsletSequence::NO_SKIP, Walrus::Grammar::ParsletSequence::SKIP_FIRST

Instance Attribute Summary

Attributes inherited from ParsletSequence

#hash

Instance Method Summary collapse

Methods inherited from ParsletSequence

#&, #initialize, #parse_common, #parse_remainder, #recurse

Methods inherited from ParsletCombination

#to_parseable

Methods included from Memoizing

#check_left_recursion, #memoizing_parse

Methods included from ParsletCombining

#&, #>>, #and?, #and_predicate, #choice, #memoizing_parse, #merge, #not!, #not_predicate, #omission, #one_or_more, #optional, #repeat, #repeat_with_default, #repetition, #repetition_with_default, #sequence, #skip, #zero_or_more, #zero_or_one, #|

Constructor Details

This class inherits a constructor from Walrus::Grammar::ParsletSequence

Instance Method Details

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
82
83
# File 'lib/walrus/grammar/parslet_merge.rb', line 75

def eql?(other)
  return false if not other.instance_of? ParsletMerge
  other_components = other.components
  return false if @components.length != other_components.length
  for i in 0..(@components.length - 1)
    return false unless @components[i].eql? other_components[i]
  end
  true
end

#parse(string, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/walrus/grammar/parslet_merge.rb', line 22

def parse(string, options = {})
  raise ArgumentError if string.nil?
  state                         = ParserState.new(string, options)
  last_caught                   = nil # keep track of the last kind of throw to be caught
  @components.each do |parseable|
    catch :ProcessNextComponent do
      catch :NotPredicateSuccess do
        catch :AndPredicateSuccess do
          catch :ZeroWidthParseSuccess do
            begin
              parsed = parseable.memoizing_parse(state.remainder, state.options)
              if parsed.respond_to? :each
                parsed.each { |element| state.parsed(element) }
              else
                state.parsed(parsed)
              end
            rescue SkippedSubstringException => e
              state.skipped(e)
            # rescue ParseError => e # failed, will try to skip; save original error in case skipping fails                                        
            #   if options.has_key?(:skipping_override) : skipping_parslet = options[:skipping_override]
            #   elsif options.has_key?(:skipping)       : skipping_parslet = options[:skipping]
            #   else                                      skipping_parslet = nil
            #   end
            #   raise e if skipping_parslet.nil?        # no skipper defined, raise original error
            #   begin
            #     parsed = skipping_parslet.memoizing_parse(state.remainder, state.options) # guard against self references (possible infinite recursion) here?
            #     state.skipped(parsed)
            #     redo              # skipping succeeded, try to redo
            #   rescue ParseError
            #     raise e           # skipping didn't help either, raise original error
            #   end
            end
            last_caught = nil
            throw :ProcessNextComponent # can't use "next" here because it will only break out of innermost "do"
          end
          last_caught = :ZeroWidthParseSuccess
          throw :ProcessNextComponent
        end
        last_caught = :AndPredicateSuccess
        throw :ProcessNextComponent
      end
      last_caught = :NotPredicateSuccess
    end
  end
  
  if state.results.respond_to? :empty? and state.results.empty? and
   throw last_caught
  else
    state.results
  end
  
end