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
@@ -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