Class: Parslet::Atoms::Context
- Inherits:
-
Object
- Object
- Parslet::Atoms::Context
- Defined in:
- lib/parslet/atoms/context.rb
Overview
Helper class that implements a transient cache that maps position and parslet object to results. This is used for memoization in the packrat style.
Also, error reporter is stored here and error reporting happens through this class. This makes the reporting pluggable.
Defined Under Namespace
Classes: LRStack
Instance Attribute Summary collapse
-
#lr_stack ⇒ Object
readonly
Returns the value of attribute lr_stack.
Instance Method Summary collapse
-
#err(*args) ⇒ Object
Report an error.
-
#err_at(*args) ⇒ Object
Report an error at a given position.
- #heads ⇒ Object
-
#initialize(reporter = Parslet::ErrorReporter::Tree.new) ⇒ Context
constructor
A new instance of Context.
-
#lookup(obj, pos) ⇒ Object
private.
- #set(obj, pos, val) ⇒ Object
-
#try_with_cache(obj, source) ⇒ Object
Caches a parse answer for obj at source.pos.
Constructor Details
#initialize(reporter = Parslet::ErrorReporter::Tree.new) ⇒ Context
Returns a new instance of Context.
29 30 31 32 33 34 |
# File 'lib/parslet/atoms/context.rb', line 29 def initialize(reporter=Parslet::ErrorReporter::Tree.new) @cache = Hash.new { |h, k| h[k] = {} } @reporter = reporter @heads = {} @lr_stack = LRStack.new([]) end |
Instance Attribute Details
#lr_stack ⇒ Object (readonly)
Returns the value of attribute lr_stack.
25 26 27 |
# File 'lib/parslet/atoms/context.rb', line 25 def lr_stack @lr_stack end |
Instance Method Details
#err(*args) ⇒ Object
Report an error.
80 81 82 83 |
# File 'lib/parslet/atoms/context.rb', line 80 def err(*args) return [false, @reporter.err(*args)] if @reporter return [false, nil] end |
#err_at(*args) ⇒ Object
Report an error at a given position.
72 73 74 75 |
# File 'lib/parslet/atoms/context.rb', line 72 def err_at(*args) return [false, @reporter.err_at(*args)] if @reporter return [false, nil] end |
#heads ⇒ Object
36 37 38 |
# File 'lib/parslet/atoms/context.rb', line 36 def heads @heads end |
#lookup(obj, pos) ⇒ Object
private
86 87 88 |
# File 'lib/parslet/atoms/context.rb', line 86 def lookup(obj, pos) @cache[pos][obj] end |
#set(obj, pos, val) ⇒ Object
90 91 92 |
# File 'lib/parslet/atoms/context.rb', line 90 def set(obj, pos, val) @cache[pos][obj] = val end |
#try_with_cache(obj, source) ⇒ Object
Caches a parse answer for obj at source.pos. Applying the same parslet at one position of input always yields the same result, unless the input has changed.
We need the entire source here so we can ask for how many characters were consumed by a successful parse. Imitation of such a parse must advance the input pos by the same amount of bytes.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/parslet/atoms/context.rb', line 48 def try_with_cache(obj, source) beg = source.pos # Not in cache yet? Return early. unless entry = lookup(obj, beg) result = obj.try(source, self) set obj, beg, [result, source.pos-beg] return result end # the condition in unless has returned true, so entry is not nil. result, advance = entry # The data we're skipping here has been read before. (since it is in # the cache) PLUS the actual contents are not interesting anymore since # we know obj matches at beg. So skip reading. source.pos = beg + advance return result end |