Module: Yoga::Parser::Helpers::ClassMethods

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

Overview

The class methods for helpers for the parser. These are defined on the class of the parser.

Constant Summary collapse

DEFAULT_SWITCH =

The default value for a switch. This matches no tokens and performs no actions. This cannot be modified.

Returns:

  • ({::Symbol => ::Proc})
{}.freeze

Instance Method Summary collapse

Instance Method Details

#first(name) ⇒ ::Set<::Symbol> #first(name, tokens) ⇒ void

Overloads:

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

    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.

    Retrieves the first set for the given node name. If none exists, a KeyError is raised.

    Parameters:

    • name (::Symbol)

      The name of the node to look up the first set for.

    Returns:

    • (::Set<::Symbol>)

      The first set

    Raises:

    • (::KeyError)

      If the node has no defined first set.

  • #first(name, tokens) ⇒ void

    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.

    This method returns an undefined value.

    Merges the given tokens into the first set of the name of the node given.

    Parameters:

    • name (::Symbol)

      The name of the node that the first set is for.

    • tokens (<::Symbol>)

      The tokens that act as the first set for the node.



101
102
103
104
105
106
107
# File 'lib/yoga/parser/helpers.rb', line 101

def first(name, tokens = nil)
  if tokens
    firsts[name] = Set.new(Array(tokens))
  else
    firsts.fetch(name)
  end
end

#firsts{::Symbol => ::Set<::Symbol>}

The first sets. The key is the name of a node, and the value is a set of all tokens that can be at the start of that node.

Returns:

  • ({::Symbol => ::Set<::Symbol>})


78
79
80
# File 'lib/yoga/parser/helpers.rb', line 78

def firsts
  @firsts ||= Hash.new { |h, k| h[k] = Set.new }
end

#switch(name) ⇒ {::Symbol => ::Proc} #switch(name, mapping) ⇒ {::Symbol => {::Symbol => ::Proc}}

Predefines a switch logic. This is used to do set checking for the keys instead of array checking. This reduces the time it takes for a switch statement to be performed.

Examples:

Parser.switch(:Definition,
  :":" => proc { parse_directive },
  :enum => proc { parse_enum },
  :def => proc { parse_function },
  :class => proc { parse_class },
  :struct => proc { parse_struct })

@param name [::Symbol] The name of the switch map.  A first set
  with the same name is created as well.
@param mapping [{::Symbol, ::Enumerable<::Symbol> =>
  ::Proc, ::Symbol}] The mapping.
@return [void]

Overloads:

  • #switch(name) ⇒ {::Symbol => ::Proc}

    Retrieves the switch map for the given name. This is basically a lookup table for the peek token. The keys represent the peek token kind, and the values are the actions that should be taken for the given token kind.

    Parameters:

    • name (::Symbol)

      The name of the switch map. This is typically the same as the first set name and the node name for the rule.

    Returns:

    • ({::Symbol => ::Proc})

      The switch map.

  • #switch(name, mapping) ⇒ {::Symbol => {::Symbol => ::Proc}}

    Sets the switch map for the given name. This does some internal mapping before finalizing the mapping. First, it converts all values into a proc; then, it expands all array (or enumerable) keys into seperate entries. It then sets the first set using the name of the switch as the name of the first set, and the keys of the switch map as the first set.

Parameters:

  • name (::Symbol)

    The name of the switch. This is used in the method to look up the switch.

  • mapping ({::Symbol, <::Symbol> => ::Proc}, nil) (defaults to: nil)

    A mapping of symbol(s) to callables. If no value is given, then it returns the current switch for the given name.

Returns:

  • ({::Symbol => {::Symbol => ::Proc}})


60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/yoga/parser/helpers.rb', line 60

def switch(name, mapping = nil)
  @_switches ||= {}
  name = name.intern
  return @_switches[name] || DEFAULT_SWITCH unless mapping
  switch = {}
  mapping.each do |k, v|
    v = v.is_a?(::Proc) ? v : proc { |*a| send(v, *a) }
    Array(k).each { |n| switch[n] = v }
  end

  first(name, switch.keys)
  @_switches[name] = switch
end