Class: Walrus::Grammar::ParserState

Inherits:
Object
  • Object
show all
Defined in:
lib/walrus/grammar/parser_state.rb

Overview

Simple class for maintaining state during a parse operation.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string, options = {}) ⇒ ParserState

Raises an ArgumentError if string is nil.

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/walrus/grammar/parser_state.rb', line 29

def initialize(string, options = {})
  raise ArgumentError if string.nil?
  self.base_string        = string
  @results                = ArrayResult.new                     # for accumulating results
  @remainder              = @base_string.clone
  @scanned                = ''
  @options                = options.clone
  
  # start wherever we last finished (doesn't seem to behave different to the alternative)
  @options[:line_start]   = (@options[:line_end] or @options[:line_start] or 0)
  @options[:column_start] = (@options[:column_end] or @options[:column_start] or 0)
#        @options[:line_start]   = 0 if @options[:line_start].nil?
#        @options[:column_start] = 0 if @options[:column_start].nil?

  @options[:line_end]     = @options[:line_start]               # before parsing begins, end point is equal to start point
  @options[:column_end]   = @options[:column_start]
  @original_line_start    = @options[:line_start]
  @original_column_start  = @options[:column_start]
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



23
24
25
# File 'lib/walrus/grammar/parser_state.rb', line 23

def options
  @options
end

#remainderObject (readonly)

Returns the remainder (the unparsed portion) of the string. Will return an empty string if already at the end of the string.



26
27
28
# File 'lib/walrus/grammar/parser_state.rb', line 26

def remainder
  @remainder
end

Instance Method Details

#auto_skipped(substring) ⇒ Object

The skipped method is used to inform the receiver of a successful parsing event where the parsed substring should be consumed but not included in the accumulated results and furthermore the parse event should not effect the overall bounds of the parse result. In reality this means that the method is only ever called upon the successful use of a automatic intertoken “skipping” parslet. By definition this method should only be called for intertoken skipping otherwise incorrect results will be produced.

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
# File 'lib/walrus/grammar/parser_state.rb', line 68

def auto_skipped(substring)
  raise ArgumentError if substring.nil?
  a, b, c, d = @options[:line_start], @options[:column_start], @options[:line_end], @options[:column_end] # save
  remainder = update_and_return_remainder_for_string(substring)
  @options[:line_start], @options[:column_start], @options[:line_end], @options[:column_end] = a, b, c, d # restore
  remainder
end

#lengthObject

Returns the number of results accumulated so far.



117
118
119
# File 'lib/walrus/grammar/parser_state.rb', line 117

def length
  @results.length
end

#parsed(substring) ⇒ Object

The parsed method is used to inform the receiver of a successful parsing event. Note that substring need not actually be a String but it must respond to the following messages:

- "line_end" and "column_end" so that the end position of the receiver can be updated

As a convenience returns the remainder. Raises an ArgumentError if substring is nil.

Raises:

  • (ArgumentError)


54
55
56
57
# File 'lib/walrus/grammar/parser_state.rb', line 54

def parsed(substring)
  raise ArgumentError if substring.nil?
  update_and_return_remainder_for_string(substring, true)
end

#resultsObject

Returns the results accumulated so far. Returns an empty array if no results have been accumulated. Returns a single object if only one result has been accumulated. Returns an array of objects if multiple results have been accumulated.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/walrus/grammar/parser_state.rb', line 80

def results
  
  updated_start       = [@original_line_start, @original_column_start]
  updated_end         = [@options[:line_end], @options[:column_end]]
  updated_source_text = @scanned.clone
  
  if @results.length == 1
    
    # he we ask the single result to exhibit container-like properties
    # use the "outer" variants so as to not overwrite any data internal to the result itself
    # this can happen where a lone result is surrounded only by skipped elements
    # the result has to convey data about its own limits, plus those of the context just around it
    results = @results[0]
    results.outer_start       = updated_start if results.start != updated_start
    results.outer_end         = updated_end if results.end != updated_end
    results.outer_source_text = updated_source_text if results.source_text != updated_source_text
    
    # the above trick fixes some of the location tracking issues but opens up another can of worms
    # uncomment this line to see
    #return results
    
    # need some way of handling unwrapped results (raw results, not AST nodes) as well
    results.start             = updated_start
    results.end               = updated_end
    results.source_text       = updated_source_text
    
  else
    results = @results
    results.start             = updated_start
    results.end               = updated_end
    results.source_text       = updated_source_text
  end        
  
  results
end

#skipped(substring) ⇒ Object

The skipped method is used to inform the receiver of a successful parsing event where the parsed substring should be consumed but not included in the accumulated results. The substring should respond to “line_end” and “column_end”. In all other respects this method behaves exactly like the parsed method.

Raises:

  • (ArgumentError)


62
63
64
65
# File 'lib/walrus/grammar/parser_state.rb', line 62

def skipped(substring)
  raise ArgumentError if substring.nil?
  update_and_return_remainder_for_string(substring)
end