predicator 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,51 @@
1
+ class Predicator::Lexer
2
+ options
3
+ lineno
4
+ column
5
+ macro
6
+ SPACE /[ \t\r\n]/
7
+ LPAREN /\(/
8
+ RPAREN /\)/
9
+ LBRACKET /\[/
10
+ RBRACKET /\]/
11
+ TRUE /true\b/
12
+ FALSE /false\b/
13
+ BETWEEN /between\b/
14
+ IN /in\b/
15
+ BANG /!/
16
+ NOT /not\b/
17
+ DOT /\./
18
+ COMMA /,/
19
+ AND /and\b/
20
+ OR /or\b/
21
+ EQ /=/
22
+ GT />/
23
+ LT /</
24
+ INTEGER /[+-]?\d(_?\d)*\b/
25
+ STRING /(["'])(?:\\?.)*?\1/
26
+ IDENTIFIER /[a-z][A-Za-z0-9_]*\b/
27
+ rule
28
+ /#{SPACE}/ # ignore space
29
+ /#{LPAREN}/ { [:LPAREN, text] }
30
+ /#{RPAREN}/ { [:RPAREN, text] }
31
+ /#{LBRACKET}/ { [:LBRACKET, text] }
32
+ /#{RBRACKET}/ { [:RBRACKET, text] }
33
+ /#{TRUE}/ { [:TRUE, text] }
34
+ /#{FALSE}/ { [:FALSE, text] }
35
+ /#{BETWEEN}/ { [:BETWEEN, text] }
36
+ /#{IN}/ { [:IN, text] }
37
+ /#{BANG}/ { [:BANG, text] }
38
+ /#{NOT}/ { [:NOT, text] }
39
+ /#{DOT}/ { [:DOT, text] }
40
+ /#{COMMA}/ { [:COMMA, text] }
41
+ /#{AND}/ { [:AND, text] }
42
+ /#{OR}/ { [:OR, text] }
43
+ /#{EQ}/ { [:EQ, text] }
44
+ /#{GT}/ { [:GT, text] }
45
+ /#{LT}/ { [:LT, text] }
46
+ /#{INTEGER}/ { [:INTEGER, text] }
47
+ /#{STRING}/ { [:STRING, text[1...-1]] }
48
+ /#{IDENTIFIER}/ { [:IDENTIFIER, text] }
49
+ inner
50
+ def do_parse; end
51
+ end
@@ -0,0 +1,160 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # This file is automatically generated. Do not modify it.
4
+ # Generated by: oedipus_lex version 2.5.0.
5
+ # Source: lib/predicator/lexer.rex
6
+ #++
7
+
8
+ class Predicator::Lexer
9
+ require 'strscan'
10
+
11
+ SPACE = /[ \t\r\n]/
12
+ LPAREN = /\(/
13
+ RPAREN = /\)/
14
+ LBRACKET = /\[/
15
+ RBRACKET = /\]/
16
+ TRUE = /true\b/
17
+ FALSE = /false\b/
18
+ BETWEEN = /between\b/
19
+ IN = /in\b/
20
+ BANG = /!/
21
+ NOT = /not\b/
22
+ DOT = /\./
23
+ COMMA = /,/
24
+ AND = /and\b/
25
+ OR = /or\b/
26
+ EQ = /=/
27
+ GT = />/
28
+ LT = /</
29
+ INTEGER = /[+-]?\d(_?\d)*\b/
30
+ STRING = /(["'])(?:\\?.)*?\1/
31
+ IDENTIFIER = /[a-z][A-Za-z0-9_]*\b/
32
+
33
+ class LexerError < StandardError ; end
34
+ class ScanError < LexerError ; end
35
+
36
+ attr_accessor :lineno
37
+ attr_accessor :filename
38
+ attr_accessor :ss
39
+ attr_accessor :state
40
+
41
+ alias :match :ss
42
+
43
+ def matches
44
+ m = (1..9).map { |i| ss[i] }
45
+ m.pop until m[-1] or m.empty?
46
+ m
47
+ end
48
+
49
+ def action
50
+ yield
51
+ end
52
+
53
+ attr_accessor :old_pos
54
+
55
+ def column
56
+ idx = ss.string.rindex("\n", old_pos) || -1
57
+ old_pos - idx - 1
58
+ end
59
+
60
+ def scanner_class
61
+ StringScanner
62
+ end unless instance_methods(false).map(&:to_s).include?("scanner_class")
63
+
64
+ def parse str
65
+ self.ss = scanner_class.new str
66
+ self.lineno = 1
67
+ self.state ||= nil
68
+
69
+ do_parse
70
+ end
71
+
72
+ def parse_file path
73
+ self.filename = path
74
+ open path do |f|
75
+ parse f.read
76
+ end
77
+ end
78
+
79
+ def location
80
+ [
81
+ (filename || "<input>"),
82
+ lineno,
83
+ column,
84
+ ].compact.join(":")
85
+ end
86
+
87
+ def next_token
88
+
89
+ token = nil
90
+
91
+ until ss.eos? or token do
92
+ self.lineno += 1 if ss.peek(1) == "\n"
93
+ self.old_pos = ss.pos
94
+ token =
95
+ case state
96
+ when nil then
97
+ case
98
+ when ss.skip(/#{SPACE}/) then
99
+ # do nothing
100
+ when text = ss.scan(/#{LPAREN}/) then
101
+ action { [:LPAREN, text] }
102
+ when text = ss.scan(/#{RPAREN}/) then
103
+ action { [:RPAREN, text] }
104
+ when text = ss.scan(/#{LBRACKET}/) then
105
+ action { [:LBRACKET, text] }
106
+ when text = ss.scan(/#{RBRACKET}/) then
107
+ action { [:RBRACKET, text] }
108
+ when text = ss.scan(/#{TRUE}/) then
109
+ action { [:TRUE, text] }
110
+ when text = ss.scan(/#{FALSE}/) then
111
+ action { [:FALSE, text] }
112
+ when text = ss.scan(/#{BETWEEN}/) then
113
+ action { [:BETWEEN, text] }
114
+ when text = ss.scan(/#{IN}/) then
115
+ action { [:IN, text] }
116
+ when text = ss.scan(/#{BANG}/) then
117
+ action { [:BANG, text] }
118
+ when text = ss.scan(/#{NOT}/) then
119
+ action { [:NOT, text] }
120
+ when text = ss.scan(/#{DOT}/) then
121
+ action { [:DOT, text] }
122
+ when text = ss.scan(/#{COMMA}/) then
123
+ action { [:COMMA, text] }
124
+ when text = ss.scan(/#{AND}/) then
125
+ action { [:AND, text] }
126
+ when text = ss.scan(/#{OR}/) then
127
+ action { [:OR, text] }
128
+ when text = ss.scan(/#{EQ}/) then
129
+ action { [:EQ, text] }
130
+ when text = ss.scan(/#{GT}/) then
131
+ action { [:GT, text] }
132
+ when text = ss.scan(/#{LT}/) then
133
+ action { [:LT, text] }
134
+ when text = ss.scan(/#{INTEGER}/) then
135
+ action { [:INTEGER, text] }
136
+ when text = ss.scan(/#{STRING}/) then
137
+ action { [:STRING, text[1...-1]] }
138
+ when text = ss.scan(/#{IDENTIFIER}/) then
139
+ action { [:IDENTIFIER, text] }
140
+ else
141
+ text = ss.string[ss.pos .. -1]
142
+ raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
143
+ end
144
+ else
145
+ raise ScanError, "undefined state at #{location}: '#{state}'"
146
+ end # token = case state
147
+
148
+ next unless token # allow functions to trigger redo w/ nil
149
+ end # while
150
+
151
+ raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless
152
+ token.nil? || (Array === token && token.size >= 2)
153
+
154
+ # auto-switch state
155
+ self.state = token.last if token && token.first == :state
156
+
157
+ token
158
+ end # def next_token
159
+ def do_parse; end
160
+ end # class
@@ -1,22 +1,306 @@
1
- require "predicator/generated_parser"
2
- require "predicator/lexer"
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.14
4
+ # from Racc grammer file "".
5
+ #
3
6
 
7
+ require 'racc/parser.rb'
8
+
9
+ require "predicator/lexer.rex"
10
+ require "predicator/visitors"
11
+ require "predicator/ast"
4
12
  module Predicator
5
- class Parser < GeneratedParser
6
- def next_token
7
- @lexer.next_token
13
+ class Parser < Racc::Parser
14
+
15
+ def initialize
16
+ @lexer = Lexer.new
8
17
  end
9
18
 
10
19
  def parse string
11
- @lexer = Lexer.new string
20
+ @lexer.parse string
12
21
  do_parse
13
22
  end
14
23
 
24
+ def next_token
25
+ @lexer.next_token
26
+ end
27
+
15
28
  def on_error type, val, values
16
29
  super
17
30
  rescue Racc::ParseError
18
31
  trace = values.each_with_index.map{|l, i| "#{' ' * i}#{l}"}
19
32
  raise ParseError, "\nparse error on value #{val.inspect}\n#{trace.join("\n")}"
20
33
  end
21
- end
34
+
35
+ ##### State transition tables begin ###
36
+
37
+ racc_action_table = [
38
+ 6, 7, 10, 6, 7, 10, 9, 17, 18, 9,
39
+ 6, 7, 10, 46, 17, 18, 9, 47, 14, 13,
40
+ 15, 14, 13, 15, 28, 6, 7, 10, 14, 13,
41
+ 15, 9, 6, 7, 10, 16, 17, 18, 9, 14,
42
+ 13, 15, 31, 14, 13, 15, 32, 39, 17, 18,
43
+ 14, 13, 15, -7, 17, 18, 14, 13, -7, 14,
44
+ 13, 15, 27, 19, 14, 13, -7, -7, 22, 23,
45
+ 24, 25, 26, 14, 13, 15, 14, 13, 15, 14,
46
+ 13, 15, 40, 19, 41, 39 ]
47
+
48
+ racc_action_check = [
49
+ 0, 0, 0, 9, 9, 9, 0, 20, 20, 9,
50
+ 10, 10, 10, 42, 29, 29, 10, 42, 0, 0,
51
+ 0, 9, 9, 9, 16, 17, 17, 17, 10, 10,
52
+ 10, 17, 18, 18, 18, 1, 30, 30, 18, 22,
53
+ 22, 22, 19, 17, 17, 17, 21, 26, 1, 1,
54
+ 18, 18, 18, 8, 21, 21, 39, 39, 8, 23,
55
+ 23, 23, 11, 8, 47, 47, 8, 8, 11, 11,
56
+ 11, 11, 11, 24, 24, 24, 25, 25, 25, 41,
57
+ 41, 41, 27, 34, 37, 40 ]
58
+
59
+ racc_action_pointer = [
60
+ -2, 35, nil, nil, nil, nil, nil, nil, 53, 1,
61
+ 8, 53, nil, nil, nil, nil, 24, 23, 30, 20,
62
+ -6, 41, 19, 39, 53, 56, 41, 63, nil, 1,
63
+ 23, nil, nil, nil, 73, nil, nil, 71, nil, 36,
64
+ 79, 59, 6, nil, nil, nil, nil, 44, nil ]
65
+
66
+ racc_action_default = [
67
+ -27, -27, -1, -2, -3, -4, -5, -6, -22, -27,
68
+ -27, -27, -21, -23, -24, -25, -27, -27, -27, -27,
69
+ -8, -27, -27, -27, -27, -27, -27, -27, 49, -9,
70
+ -10, -26, -11, -12, -22, -13, -14, -27, -16, -27,
71
+ -27, -27, -27, -19, -17, -15, -18, -27, -20 ]
72
+
73
+ racc_goto_table = [
74
+ 34, 34, 34, 34, 33, 35, 36, 37, 1, 42,
75
+ 38, nil, 43, nil, nil, nil, nil, 20, 21, 34,
76
+ 48, nil, nil, 45, 44, 29, 30 ]
77
+
78
+ racc_goto_check = [
79
+ 6, 6, 6, 6, 7, 7, 7, 7, 1, 9,
80
+ 8, nil, 10, nil, nil, nil, nil, 1, 1, 6,
81
+ 10, nil, nil, 7, 8, 1, 1 ]
82
+
83
+ racc_goto_pointer = [
84
+ nil, 8, nil, nil, nil, nil, -22, -18, -16, -30,
85
+ -27 ]
86
+
87
+ racc_goto_default = [
88
+ nil, nil, 2, 3, 4, 5, 8, 11, nil, nil,
89
+ 12 ]
90
+
91
+ racc_reduce_table = [
92
+ 0, 0, :racc_error,
93
+ 1, 24, :_reduce_none,
94
+ 1, 24, :_reduce_none,
95
+ 1, 24, :_reduce_none,
96
+ 1, 24, :_reduce_none,
97
+ 1, 25, :_reduce_5,
98
+ 1, 25, :_reduce_6,
99
+ 1, 25, :_reduce_7,
100
+ 2, 26, :_reduce_8,
101
+ 3, 26, :_reduce_9,
102
+ 3, 26, :_reduce_10,
103
+ 3, 27, :_reduce_11,
104
+ 3, 28, :_reduce_12,
105
+ 3, 28, :_reduce_13,
106
+ 3, 28, :_reduce_14,
107
+ 5, 28, :_reduce_15,
108
+ 3, 28, :_reduce_16,
109
+ 4, 28, :_reduce_17,
110
+ 3, 31, :_reduce_18,
111
+ 1, 32, :_reduce_none,
112
+ 3, 32, :_reduce_20,
113
+ 1, 30, :_reduce_none,
114
+ 1, 30, :_reduce_none,
115
+ 1, 33, :_reduce_23,
116
+ 1, 33, :_reduce_24,
117
+ 1, 29, :_reduce_25,
118
+ 3, 29, :_reduce_26 ]
119
+
120
+ racc_reduce_n = 27
121
+
122
+ racc_shift_n = 49
123
+
124
+ racc_token_table = {
125
+ false => 0,
126
+ :error => 1,
127
+ :TRUE => 2,
128
+ :FALSE => 3,
129
+ :LPAREN => 4,
130
+ :RPAREN => 5,
131
+ :LBRACKET => 6,
132
+ :RBRACKET => 7,
133
+ :BANG => 8,
134
+ :NOT => 9,
135
+ :DOT => 10,
136
+ :COMMA => 11,
137
+ :AT => 12,
138
+ :AND => 13,
139
+ :OR => 14,
140
+ :EQ => 15,
141
+ :GT => 16,
142
+ :LT => 17,
143
+ :BETWEEN => 18,
144
+ :IN => 19,
145
+ :INTEGER => 20,
146
+ :STRING => 21,
147
+ :IDENTIFIER => 22 }
148
+
149
+ racc_nt_base = 23
150
+
151
+ racc_use_result_var = false
152
+
153
+ Racc_arg = [
154
+ racc_action_table,
155
+ racc_action_check,
156
+ racc_action_default,
157
+ racc_action_pointer,
158
+ racc_goto_table,
159
+ racc_goto_check,
160
+ racc_goto_default,
161
+ racc_goto_pointer,
162
+ racc_nt_base,
163
+ racc_reduce_table,
164
+ racc_token_table,
165
+ racc_shift_n,
166
+ racc_reduce_n,
167
+ racc_use_result_var ]
168
+
169
+ Racc_token_to_s_table = [
170
+ "$end",
171
+ "error",
172
+ "TRUE",
173
+ "FALSE",
174
+ "LPAREN",
175
+ "RPAREN",
176
+ "LBRACKET",
177
+ "RBRACKET",
178
+ "BANG",
179
+ "NOT",
180
+ "DOT",
181
+ "COMMA",
182
+ "AT",
183
+ "AND",
184
+ "OR",
185
+ "EQ",
186
+ "GT",
187
+ "LT",
188
+ "BETWEEN",
189
+ "IN",
190
+ "INTEGER",
191
+ "STRING",
192
+ "IDENTIFIER",
193
+ "$start",
194
+ "predicate",
195
+ "boolean_predicate",
196
+ "logical_predicate",
197
+ "group_predicate",
198
+ "comparison_predicate",
199
+ "variable",
200
+ "value",
201
+ "array",
202
+ "array_contents",
203
+ "literal" ]
204
+
205
+ Racc_debug_parser = false
206
+
207
+ ##### State transition tables end #####
208
+
209
+ # reduce 0 omitted
210
+
211
+ # reduce 1 omitted
212
+
213
+ # reduce 2 omitted
214
+
215
+ # reduce 3 omitted
216
+
217
+ # reduce 4 omitted
218
+
219
+ def _reduce_5(val, _values)
220
+ AST::True.new true
22
221
  end
222
+
223
+ def _reduce_6(val, _values)
224
+ AST::False.new false
225
+ end
226
+
227
+ def _reduce_7(val, _values)
228
+ AST::BooleanVariable.new val.first
229
+ end
230
+
231
+ def _reduce_8(val, _values)
232
+ AST::Not.new val.last
233
+ end
234
+
235
+ def _reduce_9(val, _values)
236
+ AST::And.new val.first, val.last
237
+ end
238
+
239
+ def _reduce_10(val, _values)
240
+ AST::Or.new val.first, val.last
241
+ end
242
+
243
+ def _reduce_11(val, _values)
244
+ AST::Group.new val[1]
245
+ end
246
+
247
+ def _reduce_12(val, _values)
248
+ AST::Equal.new val.first, val.last
249
+ end
250
+
251
+ def _reduce_13(val, _values)
252
+ AST::GreaterThan.new val.first, val.last
253
+ end
254
+
255
+ def _reduce_14(val, _values)
256
+ AST::LessThan.new val.first, val.last
257
+ end
258
+
259
+ def _reduce_15(val, _values)
260
+ AST::Between.new val.first, val[2], val.last
261
+ end
262
+
263
+ def _reduce_16(val, _values)
264
+ AST::In.new val.first, val.last
265
+ end
266
+
267
+ def _reduce_17(val, _values)
268
+ AST::NotIn.new val.first, val.last
269
+ end
270
+
271
+ def _reduce_18(val, _values)
272
+ AST::Array.new val[1]
273
+ end
274
+
275
+ # reduce 19 omitted
276
+
277
+ def _reduce_20(val, _values)
278
+ [val.first, val.last].flatten
279
+ end
280
+
281
+ # reduce 21 omitted
282
+
283
+ # reduce 22 omitted
284
+
285
+ def _reduce_23(val, _values)
286
+ AST::String.new val.first
287
+ end
288
+
289
+ def _reduce_24(val, _values)
290
+ AST::Integer.new val.first.to_i
291
+ end
292
+
293
+ def _reduce_25(val, _values)
294
+ AST::Variable.new val.first
295
+ end
296
+
297
+ def _reduce_26(val, _values)
298
+ AST::Variable.new [val.first, val.last].flatten.join(".")
299
+ end
300
+
301
+ def _reduce_none(val, _values)
302
+ val[0]
303
+ end
304
+
305
+ end # class Parser
306
+ end # module Predicator