Class: YABFI::Consumer
- Inherits:
-
Object
- Object
- YABFI::Consumer
- Defined in:
- lib/yabfi/consumer.rb
Overview
This class provides generic methods to declaratively consume an Array of input.
Direct Known Subclasses
Constant Summary collapse
- Unsatisfied =
Raised when the expected input does not match the given input.
Class.new(BaseError)
- EndOfInput =
Raised when the end of input is reached.
Class.new(BaseError)
Instance Attribute Summary collapse
- #tokens ⇒ Object readonly
Instance Method Summary collapse
-
#advance ⇒ Object
Look at the next character of input and advance the parse by one element.
-
#attempt ⇒ Object?
Try a block of code, resetting the parse state on failure.
-
#consume_index ⇒ Integer
Lazily evaluated _conumer_idx instnace variable.
-
#end_of_input? ⇒ true, false
Test if the parse has completed.
-
#eq(expected) ⇒ Object
Declare that the next token in the stream should be the given token.
-
#initialize(tokens) ⇒ Consumer
constructor
Create a new Consumer.
-
#many ⇒ Object?
Consume 0 or more occurrences of the given block.
-
#many_one(&block) ⇒ Object?
Consume 1 or more occurrences of the given block.
-
#one_of(*toks) ⇒ Object
Declare that the next token in the stream should match the given token.
-
#peek ⇒ Object
Look at the next character of input without advancing the consumption.
-
#satisfy(message = nil) {|token| ... } ⇒ Object
Given an optional error message and predicate, test if the next token in the parse satisfies the predicate.
-
#seek(n) ⇒ Object
Seek to the given posision.
Constructor Details
#initialize(tokens) ⇒ Consumer
Create a new Consumer.
17 18 19 |
# File 'lib/yabfi/consumer.rb', line 17 def initialize(tokens) @tokens = tokens end |
Instance Attribute Details
#tokens ⇒ Object (readonly)
12 13 14 |
# File 'lib/yabfi/consumer.rb', line 12 def tokens @tokens end |
Instance Method Details
#advance ⇒ Object
Look at the next character of input and advance the parse by one element.
55 56 57 |
# File 'lib/yabfi/consumer.rb', line 55 def advance peek.tap { seek(consume_index.succ) } end |
#attempt ⇒ Object?
Try a block of code, resetting the parse state on failure.
99 100 101 102 103 104 105 |
# File 'lib/yabfi/consumer.rb', line 99 def attempt idx = consume_index yield rescue seek(idx) nil end |
#consume_index ⇒ Integer
Lazily evaluated _conumer_idx instnace variable.
24 25 26 |
# File 'lib/yabfi/consumer.rb', line 24 def consume_index @consume_index ||= 0 end |
#end_of_input? ⇒ true, false
Test if the parse has completed.
38 39 40 |
# File 'lib/yabfi/consumer.rb', line 38 def end_of_input? consume_index >= tokens.length end |
#eq(expected) ⇒ Object
Declare that the next token in the stream should be the given token.
82 83 84 |
# File 'lib/yabfi/consumer.rb', line 82 def eq(expected) satisfy("Expected #{expected}, got:") { |tok| tok == expected } end |
#many ⇒ Object?
Consume 0 or more occurrences of the given block.
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/yabfi/consumer.rb', line 110 def many idx = consume_index results = [] loop do idx = consume_index results << yield end rescue seek(idx) results end |
#many_one(&block) ⇒ Object?
Consume 1 or more occurrences of the given block.
125 126 127 128 129 |
# File 'lib/yabfi/consumer.rb', line 125 def many_one(&block) many(&block).tap do |results| fail Unsatisfied, '#many_one: got no results' if results.empty? end end |
#one_of(*toks) ⇒ Object
Declare that the next token in the stream should match the given token.
92 93 94 |
# File 'lib/yabfi/consumer.rb', line 92 def one_of(*toks) satisfy("Expected one of #{toks}, got:") { |tok| toks.include?(tok) } end |
#peek ⇒ Object
Look at the next character of input without advancing the consumption.
46 47 48 49 |
# File 'lib/yabfi/consumer.rb', line 46 def peek fail EndOfInput, '#peek: end of input' if end_of_input? tokens[consume_index] end |
#satisfy(message = nil) {|token| ... } ⇒ Object
Given an optional error message and predicate, test if the next token in the parse satisfies the predicate.
68 69 70 71 72 73 74 |
# File 'lib/yabfi/consumer.rb', line 68 def satisfy( = nil) ||= '#satisfy:' tok = peek fail Unsatisfied, "#{} '#{tok}'" unless yield(tok) seek(consume_index.succ) tok end |
#seek(n) ⇒ Object
Seek to the given posision.
31 32 33 |
# File 'lib/yabfi/consumer.rb', line 31 def seek(n) @consume_index = n end |