predicator 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +3 -2
  4. data/HISTORY.md +9 -0
  5. data/README.md +7 -8
  6. data/Rakefile +14 -5
  7. data/lib/predicator.rb +18 -10
  8. data/lib/predicator/ast.rb +138 -0
  9. data/lib/predicator/context.rb +7 -63
  10. data/lib/predicator/evaluator.rb +108 -0
  11. data/lib/predicator/lexer.rex +51 -0
  12. data/lib/predicator/lexer.rex.rb +160 -0
  13. data/lib/predicator/parser.rb +291 -7
  14. data/lib/predicator/parser.y +66 -40
  15. data/lib/predicator/version.rb +1 -1
  16. data/lib/predicator/visitors.rb +5 -0
  17. data/lib/predicator/visitors/dot.rb +100 -0
  18. data/lib/predicator/visitors/each.rb +16 -0
  19. data/lib/predicator/visitors/instructions.rb +117 -0
  20. data/lib/predicator/visitors/string.rb +60 -0
  21. data/lib/predicator/visitors/visitor.rb +48 -0
  22. data/predicator.gemspec +3 -2
  23. metadata +29 -32
  24. data/lib/predicator/errors.rb +0 -5
  25. data/lib/predicator/generated_parser.rb +0 -335
  26. data/lib/predicator/lexer.rb +0 -125
  27. data/lib/predicator/nodes.rb +0 -6
  28. data/lib/predicator/nodes/base_node.rb +0 -53
  29. data/lib/predicator/nodes/date_node.rb +0 -13
  30. data/lib/predicator/nodes/fixnum_node.rb +0 -9
  31. data/lib/predicator/nodes/float_node.rb +0 -9
  32. data/lib/predicator/nodes/nil_class_node.rb +0 -25
  33. data/lib/predicator/nodes/string_node.rb +0 -13
  34. data/lib/predicator/predicates.rb +0 -14
  35. data/lib/predicator/predicates/and.rb +0 -20
  36. data/lib/predicator/predicates/between.rb +0 -31
  37. data/lib/predicator/predicates/equal.rb +0 -9
  38. data/lib/predicator/predicates/false.rb +0 -13
  39. data/lib/predicator/predicates/greater_than.rb +0 -9
  40. data/lib/predicator/predicates/greater_than_or_equal.rb +0 -9
  41. data/lib/predicator/predicates/less_than.rb +0 -9
  42. data/lib/predicator/predicates/less_than_or_equal.rb +0 -9
  43. data/lib/predicator/predicates/method.rb +0 -17
  44. data/lib/predicator/predicates/not.rb +0 -20
  45. data/lib/predicator/predicates/not_equal.rb +0 -9
  46. data/lib/predicator/predicates/or.rb +0 -20
  47. data/lib/predicator/predicates/relation.rb +0 -31
  48. data/lib/predicator/predicates/true.rb +0 -13
  49. data/lib/predicator/variable.rb +0 -26
@@ -1,125 +0,0 @@
1
- require "stringio"
2
- require "strscan"
3
-
4
- module Predicator
5
- class Lexer
6
- SPACE = /[ \t\r\n]/
7
- DOT = /\./
8
- LPAREN = /\(/
9
- RPAREN = /\)/
10
- NEQ = /!=/
11
- GEQ = />=/
12
- LEQ = /<=/
13
- GT = />/
14
- LT = /</
15
- EQ = /=/
16
- BANG = /!/
17
- DATE = /(\d{4})-(\d{2})-(\d{2})/i
18
- FLOAT = /[+-]?(?:[0-9_]+\.[0-9_]*|\.[0-9_]+|\d+(?=[eE]))(?:[eE][+-]?[0-9_]+)?\b/
19
- INTEGER = /[+-]?\d(_?\d)*\b/
20
- TRUE = /true\b/
21
- FALSE = /false\b/
22
- AND = /and/i
23
- OR = /or/i
24
- BETWEEN = /between/i
25
- BLANK = /blank\?/i
26
- PRESENT = /present\?/i
27
- STRING = /(["])(?:\\?.)*?\1/
28
- IDENTIFIER = /[a-z][A-Za-z0-9_]*/
29
-
30
- def initialize string_or_io
31
- io = string_or_io.is_a?(String) ?
32
- StringIO.new(string_or_io) :
33
- string_or_io
34
-
35
- @ss = StringScanner.new io.read
36
- @tokens = []
37
- tokenize
38
- end
39
-
40
- def next_token
41
- @tokens.shift
42
- end
43
-
44
- def tokenize
45
- until @ss.eos?
46
- case
47
- when @ss.scan(SPACE)
48
- # ignore space
49
-
50
- when text = @ss.scan(DOT)
51
- @tokens.push [:tDOT, text]
52
-
53
- when text = @ss.scan(LPAREN)
54
- @tokens.push [:tLPAREN, text]
55
-
56
- when text = @ss.scan(RPAREN)
57
- @tokens.push [:tRPAREN, text]
58
-
59
- when text = @ss.scan(NEQ)
60
- @tokens.push [:tNEQ, text]
61
-
62
- when text = @ss.scan(GEQ)
63
- @tokens.push [:tGEQ, text]
64
-
65
- when text = @ss.scan(LEQ)
66
- @tokens.push [:tLEQ, text]
67
-
68
- when text = @ss.scan(GT)
69
- @tokens.push [:tGT, text]
70
-
71
- when text = @ss.scan(LT)
72
- @tokens.push [:tLT, text]
73
-
74
- when text = @ss.scan(EQ)
75
- @tokens.push [:tEQ, text]
76
-
77
- when text = @ss.scan(BANG)
78
- @tokens.push [:tBANG, text]
79
-
80
- when text = @ss.scan(DATE)
81
- args = [ @ss[1], @ss[2], @ss[3] ].map(&:to_i)
82
- @tokens.push [:tDATE, args]
83
-
84
- when text = @ss.scan(FLOAT)
85
- @tokens.push [:tFLOAT, text]
86
-
87
- when text = @ss.scan(INTEGER)
88
- @tokens.push [:tINTEGER, text]
89
-
90
- when text = @ss.scan(TRUE)
91
- @tokens.push [:tTRUE, text]
92
-
93
- when text = @ss.scan(FALSE)
94
- @tokens.push [:tFALSE, text]
95
-
96
- when text = @ss.scan(AND)
97
- @tokens.push [:tAND, text]
98
-
99
- when text = @ss.scan(OR)
100
- @tokens.push [:tOR, text]
101
-
102
- when text = @ss.scan(BETWEEN)
103
- @tokens.push [:tBETWEEN, text]
104
-
105
- when text = @ss.scan(BLANK)
106
- @tokens.push [:tBLANK, text]
107
-
108
- when text = @ss.scan(PRESENT)
109
- @tokens.push [:tPRESENT, text]
110
-
111
- when text = @ss.scan(STRING)
112
- @tokens.push [:tSTRING, text[1..-2]]
113
-
114
- when text = @ss.scan(IDENTIFIER)
115
- @tokens.push [:tIDENTIFIER, text]
116
-
117
- else
118
- raise "Unexpected characters: #{@ss.peek(5).inspect}"
119
- end
120
- end
121
-
122
- @tokens.push [false, false]
123
- end
124
- end
125
- end
@@ -1,6 +0,0 @@
1
- require "predicator/nodes/base_node"
2
- require "predicator/nodes/date_node"
3
- require "predicator/nodes/fixnum_node"
4
- require "predicator/nodes/float_node"
5
- require "predicator/nodes/nil_class_node"
6
- require "predicator/nodes/string_node"
@@ -1,53 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class BaseNode
4
- attr_reader :value
5
-
6
- def self.class_for value
7
- class_name = "#{value.class.name}Node"
8
- if ::Predicator::Nodes.const_defined? class_name
9
- ::Predicator::Nodes.const_get class_name
10
- else
11
- raise UnknownNodeTypeError, "Unknown node type for #{value.class} (#{value.inspect})"
12
- end
13
- end
14
-
15
- def initialize value
16
- @value = value
17
- end
18
-
19
- def blank?
20
- value.respond_to?(:empty?) ?
21
- !!value.empty? :
22
- !value
23
- end
24
-
25
- def present?
26
- !blank?
27
- end
28
-
29
- def comparison_method
30
- "compare_to_#{type}"
31
- end
32
-
33
- def compare_to_nil
34
- raise NilValueError
35
- end
36
-
37
- #def compare_to_date
38
- #end
39
-
40
- def compare_to_fixnum
41
- value.to_i
42
- end
43
-
44
- def compare_to_float
45
- value.to_f
46
- end
47
-
48
- def compare_to_string
49
- value.to_s
50
- end
51
- end
52
- end
53
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class DateNode < BaseNode
4
- def type
5
- :date
6
- end
7
-
8
- def compare_to_date
9
- value
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class FixnumNode < BaseNode
4
- def type
5
- :fixnum
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class FloatNode < BaseNode
4
- def type
5
- :float
6
- end
7
- end
8
- end
9
- end
@@ -1,25 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class NilClassNode < BaseNode
4
- def type
5
- :nil
6
- end
7
-
8
- def compare_to_date
9
- raise NilValueError
10
- end
11
-
12
- def compare_to_fixnum
13
- raise NilValueError
14
- end
15
-
16
- def compare_to_float
17
- raise NilValueError
18
- end
19
-
20
- def compare_to_string
21
- raise NilValueError
22
- end
23
- end
24
- end
25
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class StringNode < BaseNode
4
- def type
5
- :string
6
- end
7
-
8
- def compare_to_date
9
- Date.parse value
10
- end
11
- end
12
- end
13
- end
@@ -1,14 +0,0 @@
1
- require "predicator/predicates/relation"
2
- require "predicator/predicates/equal"
3
- require "predicator/predicates/not_equal"
4
- require "predicator/predicates/greater_than"
5
- require "predicator/predicates/less_than"
6
- require "predicator/predicates/greater_than_or_equal"
7
- require "predicator/predicates/less_than_or_equal"
8
- require "predicator/predicates/between"
9
- require "predicator/predicates/true"
10
- require "predicator/predicates/false"
11
- require "predicator/predicates/and"
12
- require "predicator/predicates/or"
13
- require "predicator/predicates/not"
14
- require "predicator/predicates/method"
@@ -1,20 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class And
4
- attr_reader :predicates
5
-
6
- def initialize predicates
7
- @predicates = predicates
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- predicates.all?{ |pred| pred.satisfied? context }
12
- end
13
-
14
- def == other
15
- other.kind_of?(self.class) &&
16
- other.predicates == predicates
17
- end
18
- end
19
- end
20
- end
@@ -1,31 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Between
4
- attr_reader :value, :left, :right
5
-
6
- def initialize value, left, right
7
- @value, @left, @right = value, left, right
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- value_node = context.node_for value
12
- left_node = context.node_for left
13
- right_node = context.node_for right
14
- method = "compare_to_#{value_node.type}"
15
-
16
- left_value = left_node.send method
17
- right_value = right_node.send method
18
-
19
- (value_node.value >= left_value) &&
20
- (value_node.value <= right_value)
21
- end
22
-
23
- def == other
24
- other.kind_of?(self.class) &&
25
- other.value == value &&
26
- other.left == left &&
27
- other.right == right
28
- end
29
- end
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Equal < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs == rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class False
4
- def satisfied? context=Predicator::Context.new
5
- false
6
- end
7
-
8
- def == other
9
- other.kind_of?(self.class)
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class GreaterThan < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs > rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class GreaterThanOrEqual < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs >= rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class LessThan < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs < rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class LessThanOrEqual < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs <= rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Method
4
- attr_reader :value, :method
5
-
6
- def initialize value, method
7
- @value = value
8
- @method = method
9
- end
10
-
11
- def satisfied? context=Predicator::Context.new
12
- node = context.node_for value
13
- node.send method
14
- end
15
- end
16
- end
17
- end
@@ -1,20 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Not
4
- attr_reader :predicate
5
-
6
- def initialize predicate
7
- @predicate = predicate
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- !predicate.satisfied? context
12
- end
13
-
14
- def == other
15
- other.kind_of?(self.class) &&
16
- other.predicate == predicate
17
- end
18
- end
19
- end
20
- end