Class: Ferret::Scanner
- Inherits:
-
Object
- Object
- Ferret::Scanner
- Defined in:
- lib/sql-ferret.rb
Instance Method Summary collapse
- #expected!(expectation, **extra) ⇒ Object
- #expected_eof! ⇒ Object
- #get_id(expectation) ⇒ Object
- #get_optional_escaped_id(expectation) ⇒ Object
- #get_optional_id ⇒ Object
-
#initialize(expr) ⇒ Scanner
constructor
A new instance of Scanner.
- #last_token_offset ⇒ Object
- #next_token_offset ⇒ Object
- #pass(etalon) ⇒ Object
- #pass?(etalon) ⇒ Boolean
- #peek_token ⇒ Object
Constructor Details
#initialize(expr) ⇒ Scanner
Returns a new instance of Scanner.
772 773 774 775 776 777 778 779 780 781 782 783 |
# 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 |
Instance Method Details
#expected!(expectation, **extra) ⇒ Object
844 845 846 847 848 849 850 851 852 853 854 |
# 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! ⇒ Object
916 917 918 919 |
# File 'lib/sql-ferret.rb', line 916 def expected_eof! expected! '*eof*' unless next_token_offset >= @expr.length return end |
#get_id(expectation) ⇒ Object
887 888 889 |
# File 'lib/sql-ferret.rb', line 887 def get_id expectation return (get_optional_id or expected! expectation) end |
#get_optional_escaped_id(expectation) ⇒ Object
876 877 878 879 880 881 882 883 884 885 |
# 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 ⇒ Object
866 867 868 869 870 871 872 873 874 |
# 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 ⇒ Object
906 907 908 |
# File 'lib/sql-ferret.rb', line 906 def last_token_offset return @offset_behind end |
#next_token_offset ⇒ Object
910 911 912 913 914 |
# File 'lib/sql-ferret.rb', line 910 def next_token_offset _skip_intertoken_space \ unless @token_ahead return @offset_ahead end |
#pass(etalon) ⇒ Object
901 902 903 904 |
# File 'lib/sql-ferret.rb', line 901 def pass etalon pass? etalon or expected! etalon return end |
#pass?(etalon) ⇒ Boolean
891 892 893 894 895 896 897 898 899 |
# 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 ⇒ Object
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
# 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 |