Module: Yoga::Parser::Helpers

Defined in:
lib/yoga/parser/helpers.rb

Overview

helpers that manage the state of the parser. This can be things like peeking, shifting, and erroring.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal ruby construct.



230
231
232
# File 'lib/yoga/parser/helpers.rb', line 230

def self.included(base)
  base.extend ClassMethods
end

Instance Method Details

#collect(ending, join = nil) ⇒ ::Array

"Collects" a set of nodes until a terminating token. It yields until the peek is the token.

Parameters:

  • ending (::Symbol)

    The terminating token.

  • join (::Symbol, nil) (defaults to: nil)

    The token that joins each of the children. This is the comma between arguments.

Returns:

  • (::Array)

    The collected nodes from the yielding process.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/yoga/parser/helpers.rb', line 160

def collect(ending, join = nil)
  children = []
  join = Utils.flatten_into_set([join]) if join
  ending = Utils.flatten_into_set([ending]) if ending

  return [] if (ending && peek?(ending)) || (!ending && !join)

  children << yield
  while (join && expect(join)) && !(ending && peek?(ending))
    children << yield
  end

  children
end

#error(tokens) ⇒ void

This method returns an undefined value.

Errors, noting the expected tokens, the given token, the location of given tokens. It does this by failing.

Parameters:

  • tokens (<::Symbol>)

    The expected tokens.



221
222
223
224
# File 'lib/yoga/parser/helpers.rb', line 221

def error(tokens)
  fail Yoga::UnexpectedTokenError, expected: tokens, got: peek.kind,
    location: peek.location
end

#expect(*tokens) ⇒ Yoga::Token

Sets up an expectation for a given token. If the next token is an expected token, it shifts, returning the token; otherwise, it #errors with the token information.

Parameters:

  • tokens (<::Symbol>)

    The expected tokens.

Returns:



202
203
204
205
206
# File 'lib/yoga/parser/helpers.rb', line 202

def expect(*tokens)
  tokens = Utils.flatten_into_set(tokens)
  return shift if peek?(*tokens)
  error(tokens.flatten)
end

#first(name) ⇒ ::Set<::Symbol>

Retrieves the first set for the given node name.

Parameters:

  • name (::Symbol)

Returns:

  • (::Set<::Symbol>)


212
213
214
# File 'lib/yoga/parser/helpers.rb', line 212

def first(name)
  self.class.first(name)
end

#next?::Boolean

Checks if the next token exists. It does this by checking for a StopIteration error. This is actually really slow, but there's not much else I can do.

Returns:

  • (::Boolean)


127
128
129
130
131
132
# File 'lib/yoga/parser/helpers.rb', line 127

def next?
  @tokens.peek
  true
rescue StopIteration
  false
end

#peekYoga::Token

Peeks to the next token. If peeking would cause a StopIteration error, it instead returns the last value that was peeked.

Returns:



114
115
116
117
118
119
120
# File 'lib/yoga/parser/helpers.rb', line 114

def peek
  if next?
    @_last = @tokens.peek
  else
    @_last
  end
end

#peek?(*tokens) ⇒ ::Boolean

Checks to see if any of the given kinds includes the next token.

Parameters:

  • tokens (<::Symbol>)

    The possible kinds.

Returns:

  • (::Boolean)


182
183
184
185
# File 'lib/yoga/parser/helpers.rb', line 182

def peek?(*tokens)
  tokens = Utils.flatten_into_set(tokens)
  tokens.include?(peek.kind)
end

#shiftYoga::Token

Shifts to the next token, and returns the old token.

Returns:



190
191
192
193
194
# File 'lib/yoga/parser/helpers.rb', line 190

def shift
  @tokens.next
rescue ::StopIteration
  fail InvalidShiftError, location: peek.location
end

#switch(name, *param) ⇒ ::Object

Switches the function executed based on the given nodes. If the peeked node matches one of the mappings, it calls the resulting block or method.

If the peeked token is not in the map, then #error is called.

Parameters:

  • name (::Symbol)

    The name of the switch to use.

Returns:

  • (::Object)

    The result of calling the block.

See Also:



143
144
145
146
147
148
# File 'lib/yoga/parser/helpers.rb', line 143

def switch(name, *param)
  switch = self.class.switch(name)
  block = switch
          .fetch(peek.kind) { switch.fetch(:$else) { error(switch.keys) } }
  instance_exec(*param, &block)
end