class Dentaku::TokenMatcher

Attributes

categories[R]
children[R]
values[R]

Public Class Methods

addsub() click to toggle source
# File lib/dentaku/token_matcher.rb, line 104
def self.addsub;         new(:operator, [:add, :subtract]);    end
anchored_minus() click to toggle source
# File lib/dentaku/token_matcher.rb, line 106
def self.anchored_minus; new(:operator, :subtract).caret;      end
arguments() click to toggle source
# File lib/dentaku/token_matcher.rb, line 122
def self.arguments;      (value | comma).plus;                 end
close() click to toggle source
# File lib/dentaku/token_matcher.rb, line 117
def self.close;          new(:grouping, :close);               end
combinator() click to toggle source
# File lib/dentaku/token_matcher.rb, line 110
def self.combinator;     new(:combinator);                     end
comma() click to toggle source
# File lib/dentaku/token_matcher.rb, line 118
def self.comma;          new(:grouping, :comma);               end
comp_gt() click to toggle source
# File lib/dentaku/token_matcher.rb, line 113
def self.comp_gt;        new(:comparator, [:gt, :ge]);         end
comp_lt() click to toggle source
# File lib/dentaku/token_matcher.rb, line 114
def self.comp_lt;        new(:comparator, [:lt, :le]);         end
comparator() click to toggle source
# File lib/dentaku/token_matcher.rb, line 112
def self.comparator;     new(:comparator);                     end
datetime() click to toggle source
# File lib/dentaku/token_matcher.rb, line 96
def self.datetime;       new(:datetime);                       end
if() click to toggle source
# File lib/dentaku/token_matcher.rb, line 124
def self.if;             new(:function, :if);                  end
logical() click to toggle source
# File lib/dentaku/token_matcher.rb, line 99
def self.logical;        new(:logical);                        end
method_missing(name, *args, &block) click to toggle source
# File lib/dentaku/token_matcher.rb, line 130
def self.method_missing(name, *args, &block)
  new(:function, name)
end
mod() click to toggle source
# File lib/dentaku/token_matcher.rb, line 109
def self.mod;            new(:operator, :mod);                 end
muldiv() click to toggle source
# File lib/dentaku/token_matcher.rb, line 107
def self.muldiv;         new(:operator, [:multiply, :divide]); end
new(categories = nil, values = nil, children = []) click to toggle source
# File lib/dentaku/token_matcher.rb, line 7
def initialize(categories = nil, values = nil, children = [])
  # store categories and values as hash to optimize key lookup, h/t @jan-mangs
  @categories = [categories].compact.flatten.each_with_object({}) { |c, h| h[c] = 1 }
  @values     = [values].compact.flatten.each_with_object({}) { |v, h| h[v] = 1 }
  @children   = children.compact
  @invert     = false

  @min = 1
  @max = 1
  @range = (@min..@max)
end
non_close_plus() click to toggle source
# File lib/dentaku/token_matcher.rb, line 121
def self.non_close_plus; new(:grouping, :close).invert.plus;   end
non_group() click to toggle source
# File lib/dentaku/token_matcher.rb, line 119
def self.non_group;      new(:grouping).invert;                end
non_group_star() click to toggle source
# File lib/dentaku/token_matcher.rb, line 120
def self.non_group_star; new(:grouping).invert.star;           end
not() click to toggle source
# File lib/dentaku/token_matcher.rb, line 128
def self.not;            new(:function, :not);                 end
numeric() click to toggle source
# File lib/dentaku/token_matcher.rb, line 97
def self.numeric;        new(:numeric);                        end
open() click to toggle source
# File lib/dentaku/token_matcher.rb, line 116
def self.open;           new(:grouping, :open);                end
pow() click to toggle source
# File lib/dentaku/token_matcher.rb, line 108
def self.pow;            new(:operator, :pow);                 end
respond_to_missing?(name, include_priv) click to toggle source
# File lib/dentaku/token_matcher.rb, line 134
def self.respond_to_missing?(name, include_priv)
  true
end
round() click to toggle source
# File lib/dentaku/token_matcher.rb, line 125
def self.round;          new(:function, :round);               end
rounddown() click to toggle source
# File lib/dentaku/token_matcher.rb, line 127
def self.rounddown;      new(:function, :rounddown);           end
roundup() click to toggle source
# File lib/dentaku/token_matcher.rb, line 126
def self.roundup;        new(:function, :roundup);             end
string() click to toggle source
# File lib/dentaku/token_matcher.rb, line 98
def self.string;         new(:string);                         end
subtract() click to toggle source
# File lib/dentaku/token_matcher.rb, line 105
def self.subtract;       new(:operator, :subtract);            end
value() click to toggle source
# File lib/dentaku/token_matcher.rb, line 100
def self.value
  new(:datetime) | new(:numeric) | new(:string) | new(:logical)
end

Public Instance Methods

==(token) click to toggle source
# File lib/dentaku/token_matcher.rb, line 28
def ==(token)
  leaf_matcher? ? matches_token?(token) : any_child_matches_token?(token)
end
caret() click to toggle source
# File lib/dentaku/token_matcher.rb, line 47
def caret
  @caret = true
  self
end
caret?() click to toggle source
# File lib/dentaku/token_matcher.rb, line 52
def caret?
  @caret
end
invert() click to toggle source
# File lib/dentaku/token_matcher.rb, line 23
def invert
  @invert = ! @invert
  self
end
leaf_matcher?() click to toggle source
# File lib/dentaku/token_matcher.rb, line 69
def leaf_matcher?
  children.empty?
end
leaf_matchers() click to toggle source
# File lib/dentaku/token_matcher.rb, line 73
def leaf_matchers
  leaf_matcher? ? [self] : children
end
match(token_stream, offset = 0) click to toggle source
# File lib/dentaku/token_matcher.rb, line 32
def match(token_stream, offset = 0)
  matched_tokens = []
  matched = false

  while self == token_stream[matched_tokens.length + offset] && matched_tokens.length < @max
    matched_tokens << token_stream[matched_tokens.length + offset]
  end

  if @range.cover?(matched_tokens.length)
    matched = true
  end

  [matched, matched_tokens]
end
plus() click to toggle source
# File lib/dentaku/token_matcher.rb, line 63
def plus
  @max = Float::INFINITY
  @range = (@min..@max)
  self
end
star() click to toggle source
# File lib/dentaku/token_matcher.rb, line 56
def star
  @min = 0
  @max = Float::INFINITY
  @range = (@min..@max)
  self
end
|(other_matcher) click to toggle source
# File lib/dentaku/token_matcher.rb, line 19
def |(other_matcher)
  self.class.new(:nomatch, :nomatch, leaf_matchers + other_matcher.leaf_matchers)
end

Private Instance Methods

any_child_matches_token?(token) click to toggle source
# File lib/dentaku/token_matcher.rb, line 79
def any_child_matches_token?(token)
  children.any? { |child| child == token }
end
category_match(category) click to toggle source
# File lib/dentaku/token_matcher.rb, line 88
def category_match(category)
  @categories.empty? || @categories.key?(category)
end
matches_token?(token) click to toggle source
# File lib/dentaku/token_matcher.rb, line 83
def matches_token?(token)
  return false if token.nil?
  (category_match(token.category) && value_match(token.value)) ^ @invert
end
value_match(value) click to toggle source
# File lib/dentaku/token_matcher.rb, line 92
def value_match(value)
  @values.empty? || @values.key?(value)
end