Class: Dentaku::TokenScanner

Inherits:
Object
  • Object
show all
Defined in:
lib/dentaku/token_scanner.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(category, regexp, converter = nil) ⇒ TokenScanner

Returns a new instance of TokenScanner.



5
6
7
8
9
# File 'lib/dentaku/token_scanner.rb', line 5

def initialize(category, regexp, converter=nil)
  @category  = category
  @regexp    = %r{\A(#{ regexp })}i
  @converter = converter
end

Class Method Details

.combinatorObject



72
73
74
# File 'lib/dentaku/token_scanner.rb', line 72

def combinator
  new(:combinator, '(and|or)\b', lambda { |raw| raw.strip.downcase.to_sym })
end

.comparatorObject



66
67
68
69
70
# File 'lib/dentaku/token_scanner.rb', line 66

def comparator
  names = { le: '<=', ge: '>=', ne: '!=', lt: '<', gt: '>', eq: '=' }.invert
  alternate = { ne: '<>', eq: '==' }.invert
  new(:comparator, '<=|>=|!=|<>|<|>|==|=', lambda { |raw| names[raw] || alternate[raw] })
end

.double_quoted_stringObject



48
49
50
# File 'lib/dentaku/token_scanner.rb', line 48

def double_quoted_string
  new(:string, '"[^"]*"', lambda { |raw| raw.gsub(/^"|"$/, '') })
end

.functionObject



76
77
78
79
80
81
# File 'lib/dentaku/token_scanner.rb', line 76

def function
  new(:function, '\w+\s*\(', lambda do |raw|
    function_name = raw.gsub('(', '')
    [Token.new(:function, function_name.strip.downcase.to_sym, function_name), Token.new(:grouping, :fopen, '(')]
  end)
end

.groupingObject



61
62
63
64
# File 'lib/dentaku/token_scanner.rb', line 61

def grouping
  names = { open: '(', close: ')', comma: ',' }.invert
  new(:grouping, '\(|\)|,', lambda { |raw| names[raw] })
end

.identifierObject



83
84
85
# File 'lib/dentaku/token_scanner.rb', line 83

def identifier
  new(:identifier, '\w+\b', lambda { |raw| raw.strip.downcase.to_s })
end

.numericObject



44
45
46
# File 'lib/dentaku/token_scanner.rb', line 44

def numeric
  new(:numeric, '(\d+(\.\d+)?|\.\d+)\b', lambda { |raw| raw =~ /\./ ? BigDecimal.new(raw) : raw.to_i })
end

.operatorObject



56
57
58
59
# File 'lib/dentaku/token_scanner.rb', line 56

def operator
  names = { pow: '^', add: '+', subtract: '-', multiply: '*', divide: '/', mod: '%' }.invert
  new(:operator, '\^|\+|-|\*|\/|%', lambda { |raw| names[raw] })
end

.scannersObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/dentaku/token_scanner.rb', line 25

def scanners
  @scanners ||= [
    whitespace,
    numeric,
    double_quoted_string,
    single_quoted_string,
    operator,
    grouping,
    comparator,
    combinator,
    function,
    identifier
  ]
end

.single_quoted_stringObject



52
53
54
# File 'lib/dentaku/token_scanner.rb', line 52

def single_quoted_string
  new(:string, "'[^']*'", lambda { |raw| raw.gsub(/^'|'$/, '') })
end

.whitespaceObject



40
41
42
# File 'lib/dentaku/token_scanner.rb', line 40

def whitespace
  new(:whitespace, '\s+')
end

Instance Method Details

#scan(string) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/dentaku/token_scanner.rb', line 11

def scan(string)
  if m = @regexp.match(string)
    value = raw = m.to_s
    value = @converter.call(raw) if @converter

    return Array(value).map do |v|
      Token === v ? v : Token.new(@category, v, raw)
    end
  end

  false
end