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
-
.included(base) ⇒ Object
private
Internal ruby construct.
Instance Method Summary collapse
-
#collect(ending, join = nil) ⇒ ::Array
"Collects" a set of nodes until a terminating token.
-
#error(tokens) ⇒ void
Errors, noting the expected tokens, the given token, the location of given tokens.
-
#expect(*tokens) ⇒ Yoga::Token
Sets up an expectation for a given token.
-
#first(name) ⇒ ::Set<::Symbol>
Retrieves the first set for the given node name.
-
#next? ⇒ ::Boolean
Checks if the next token exists.
-
#peek ⇒ Yoga::Token
Peeks to the next token.
-
#peek?(*tokens) ⇒ ::Boolean
Checks to see if any of the given kinds includes the next token.
-
#shift ⇒ Yoga::Token
Shifts to the next token, and returns the old token.
-
#switch(name, *param) ⇒ ::Object
Switches the function executed based on the given nodes.
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.
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.
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.
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.
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.
127 128 129 130 131 132 |
# File 'lib/yoga/parser/helpers.rb', line 127 def next? @tokens.peek true rescue StopIteration false end |
#peek ⇒ Yoga::Token
Peeks to the next token. If peeking would cause a StopIteration
error, it instead returns the last value that was peeked.
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.
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 |
#shift ⇒ Yoga::Token
Shifts to the next token, and returns the old token.
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.
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 |