class Ferret::Scanner
Public Class Methods
new(expr)
click to toggle source
Calls superclass method
# File lib/sql-ferret.rb, line 772 def initialize expr raise 'type mismatch' unless expr.is_a? String super() @expr = expr @lex = Ferret::LEXICAL_RULESET @offset_ahead = 0 @token_ahead = nil @offset_atail = nil @offset_behind = nil return end
Public Instance Methods
expected!(expectation, **extra)
click to toggle source
# File lib/sql-ferret.rb, line 844 def expected! expectation, **extra # We'll call [[peek_token]] in advance so that # [[@offset_ahead]] would point exactly at the next token. tok = peek_token ugh('ferret-parse-error', expected: expectation, got: (tok || '*eof*').to_s, input: @expr, offset: @offset_ahead, **extra) end
expected_eof!()
click to toggle source
# File lib/sql-ferret.rb, line 916 def expected_eof! expected! '*eof*' unless next_token_offset >= @expr.length return end
get_id(expectation)
click to toggle source
# File lib/sql-ferret.rb, line 887 def get_id expectation return (get_optional_id or expected! expectation) end
get_optional_escaped_id(expectation)
click to toggle source
# File lib/sql-ferret.rb, line 876 def get_optional_escaped_id expectation escaped_p = pass? :'\\' if escaped_p then return true, get_id(expectation) elsif id = get_optional_id then return false, id else return nil end end
get_optional_id() { |tok| ... }
click to toggle source
# File lib/sql-ferret.rb, line 866 def get_optional_id tok = peek_token if tok.is_a? String then _consume_token_ahead return block_given? ? yield(tok) : tok else return nil end end
last_token_offset()
click to toggle source
# File lib/sql-ferret.rb, line 906 def last_token_offset return @offset_behind end
next_token_offset()
click to toggle source
# File lib/sql-ferret.rb, line 910 def next_token_offset _skip_intertoken_space \ unless @token_ahead return @offset_ahead end
pass(etalon)
click to toggle source
# File lib/sql-ferret.rb, line 901 def pass etalon pass? etalon or expected! etalon return end
pass?(etalon)
click to toggle source
# File lib/sql-ferret.rb, line 891 def pass? etalon tok = peek_token if tok == etalon then _consume_token_ahead return true else return false end end
peek_token()
click to toggle source
# File lib/sql-ferret.rb, line 795 def peek_token return @token_ahead if @token_ahead # Note that [[peek_token]] advances [[@offset_ahead]] to # skip over preceding intertoken space but no further. # Instead, it'll store the end offset of the peeked token # in [[@offset_atail]]. _skip_intertoken_space # check for eof if @offset_ahead >= @expr.length then @offset_atail = @offset_ahead return @token_ahead = nil end # check for an identifier if @lex.id_starter? @expr[@offset_ahead] then @offset_atail = @offset_ahead loop do @offset_atail += 1 break unless @lex.id_continuer? @expr[@offset_atail] end return @token_ahead = @expr[@offset_ahead ... @offset_atail] end # check for multi-char particles @lex.multichar.each do |etalon| if @expr[@offset_ahead, etalon.length] == etalon then @offset_atail = @offset_ahead + etalon.length return @token_ahead = etalon.to_sym end end # check for single-char particles if @lex.simple_particle? @expr[@offset_ahead] then @offset_atail = @offset_ahead + 1 return @token_ahead = @expr[@offset_ahead].chr.to_sym end # give up ugh 'ferret-lexical-error', input: @expr, offset: @offset_ahead, lookahead: @expr[@offset_ahead, 10], lookbehind: @expr[ [@offset_ahead - 10, 0].max ... @offset_ahead] end
Private Instance Methods
_consume_token_ahead()
click to toggle source
# File lib/sql-ferret.rb, line 856 def _consume_token_ahead raise 'assertion failed' unless @offset_atail @offset_behind = @offset_ahead @offset_ahead = @offset_atail @token_ahead = nil @offset_atail = nil return end
_skip_intertoken_space()
click to toggle source
# File lib/sql-ferret.rb, line 785 def _skip_intertoken_space loop do break if @offset_ahead >= @expr.length break unless @lex.intertoken? @expr[@offset_ahead] @offset_ahead += 1 end return end