Class: Walrat::ParserState

Inherits:
Object
  • Object
show all
Defined in:
lib/walrat/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)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/walrat/parser_state.rb', line 35

def initialize string, options = {}
  raise ArgumentError, 'nil string' 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?

  # before parsing begins, end point is equal to start point
  @options[:line_end]     = @options[:line_start]
  @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.



28
29
30
# File 'lib/walrat/parser_state.rb', line 28

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.



32
33
34
# File 'lib/walrat/parser_state.rb', line 32

def remainder
  @remainder
end

Instance Method Details

#auto_skipped(substring) ⇒ Object

The auto_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 affect 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)


89
90
91
92
93
94
95
96
97
# File 'lib/walrat/parser_state.rb', line 89

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.



141
142
143
# File 'lib/walrat/parser_state.rb', line 141

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)


66
67
68
69
# File 'lib/walrat/parser_state.rb', line 66

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.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/walrat/parser_state.rb', line 103

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
    # here 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)


76
77
78
79
# File 'lib/walrat/parser_state.rb', line 76

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