predicator 0.3.0 → 1.2.1
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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +46 -0
- data/.travis.yml +3 -2
- data/HISTORY.md +31 -0
- data/README.md +33 -12
- data/Rakefile +14 -5
- data/lib/predicator.rb +18 -4
- data/lib/predicator/ast.rb +190 -0
- data/lib/predicator/context.rb +7 -12
- data/lib/predicator/evaluator.rb +153 -0
- data/lib/predicator/lexer.rex +69 -0
- data/lib/predicator/lexer.rex.rb +187 -0
- data/lib/predicator/parser.rb +427 -26
- data/lib/predicator/parser.y +103 -35
- data/lib/predicator/version.rb +1 -1
- data/lib/predicator/visitors.rb +5 -0
- data/lib/predicator/visitors/dot.rb +113 -0
- data/lib/predicator/visitors/each.rb +16 -0
- data/lib/predicator/visitors/instructions.rb +183 -0
- data/lib/predicator/visitors/string.rb +76 -0
- data/lib/predicator/visitors/visitor.rb +100 -0
- data/predicator.gemspec +10 -2
- metadata +67 -28
- data/lib/predicator/generated_parser.rb +0 -307
- data/lib/predicator/lexer.rb +0 -117
- data/lib/predicator/predicates/and.rb +0 -20
- data/lib/predicator/predicates/between.rb +0 -23
- data/lib/predicator/predicates/equal.rb +0 -9
- data/lib/predicator/predicates/false.rb +0 -13
- data/lib/predicator/predicates/greater_than.rb +0 -9
- data/lib/predicator/predicates/greater_than_or_equal.rb +0 -9
- data/lib/predicator/predicates/less_than.rb +0 -9
- data/lib/predicator/predicates/less_than_or_equal.rb +0 -9
- data/lib/predicator/predicates/not.rb +0 -20
- data/lib/predicator/predicates/not_equal.rb +0 -9
- data/lib/predicator/predicates/or.rb +0 -20
- data/lib/predicator/predicates/relation.rb +0 -17
- data/lib/predicator/predicates/true.rb +0 -13
- data/lib/predicator/variable.rb +0 -26
@@ -0,0 +1,153 @@
|
|
1
|
+
require "date"
|
2
|
+
|
3
|
+
module Predicator
|
4
|
+
class Evaluator
|
5
|
+
attr_reader :instructions, :stack, :context
|
6
|
+
|
7
|
+
def initialize instructions, context_data={}
|
8
|
+
@instructions = instructions
|
9
|
+
@context = context_for context_data
|
10
|
+
@stack = []
|
11
|
+
@ip = 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def context_for context_data
|
15
|
+
return context_data unless context_data.kind_of? Hash
|
16
|
+
Context.new context_data
|
17
|
+
end
|
18
|
+
|
19
|
+
def result
|
20
|
+
while @ip < instructions.length
|
21
|
+
process @instructions[@ip]
|
22
|
+
@ip += 1
|
23
|
+
end
|
24
|
+
stack.pop
|
25
|
+
end
|
26
|
+
|
27
|
+
def process instruction
|
28
|
+
case instruction.first
|
29
|
+
when "not" then stack.push !stack.pop
|
30
|
+
when "jfalse" then jump_if_false instruction.last
|
31
|
+
when "jtrue" then jump_if_true instruction.last
|
32
|
+
when "lit", "array" then stack.push instruction.last
|
33
|
+
when "load" then stack.push context[instruction.last]
|
34
|
+
when "to_bool" then stack.push !!stack.pop
|
35
|
+
when "to_int" then stack.push to_int(stack.pop)
|
36
|
+
when "to_str" then stack.push to_str(stack.pop)
|
37
|
+
when "to_date" then stack.push to_date(stack.pop)
|
38
|
+
when "date_ago" then stack.push date_ago(stack.pop)
|
39
|
+
when "date_from_now" then stack.push date_from_now(stack.pop)
|
40
|
+
when "blank" then stack.push blank?(stack.pop)
|
41
|
+
when "present" then stack.push !blank?(stack.pop)
|
42
|
+
when "compare"
|
43
|
+
if instruction.last == "BETWEEN"
|
44
|
+
compare_BETWEEN
|
45
|
+
else
|
46
|
+
compare instruction.last
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_int val
|
52
|
+
if val.nil? || (val.is_a?(String) && val.empty?)
|
53
|
+
nil
|
54
|
+
else
|
55
|
+
val.to_i
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_str val
|
60
|
+
val.nil? ? nil : val.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_date val
|
64
|
+
val.nil? ? nil : Date.parse(val)
|
65
|
+
end
|
66
|
+
|
67
|
+
def date_ago seconds
|
68
|
+
past_time = Time.now - seconds
|
69
|
+
to_date past_time.strftime "%Y-%m-%d"
|
70
|
+
end
|
71
|
+
|
72
|
+
def date_from_now seconds
|
73
|
+
future_time = Time.now + seconds
|
74
|
+
to_date future_time.strftime "%Y-%m-%d"
|
75
|
+
end
|
76
|
+
|
77
|
+
def blank? val
|
78
|
+
val.respond_to?(:empty?) ? !!val.empty? : !val
|
79
|
+
end
|
80
|
+
|
81
|
+
def jump_if_false offset
|
82
|
+
if stack[-1] == false
|
83
|
+
adjusted_offset = offset - 1
|
84
|
+
@ip += adjusted_offset
|
85
|
+
else
|
86
|
+
stack.pop
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def jump_if_true offset
|
91
|
+
if stack[-1] == true
|
92
|
+
adjusted_offset = offset - 1
|
93
|
+
@ip += adjusted_offset
|
94
|
+
else
|
95
|
+
stack.pop
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def compare comparison
|
100
|
+
right = stack.pop
|
101
|
+
left = stack.pop
|
102
|
+
if left.nil? || right.nil?
|
103
|
+
stack.push false
|
104
|
+
else
|
105
|
+
stack.push send("compare_#{comparison}", left, right)
|
106
|
+
end
|
107
|
+
rescue StandardError
|
108
|
+
stack.push false
|
109
|
+
end
|
110
|
+
|
111
|
+
def compare_EQ left, right
|
112
|
+
left == right
|
113
|
+
end
|
114
|
+
|
115
|
+
def compare_GT left, right
|
116
|
+
left > right
|
117
|
+
end
|
118
|
+
|
119
|
+
def compare_LT left, right
|
120
|
+
left < right
|
121
|
+
end
|
122
|
+
|
123
|
+
def compare_IN left, right
|
124
|
+
right.include? left
|
125
|
+
end
|
126
|
+
|
127
|
+
def compare_NOTIN left, right
|
128
|
+
!right.include? left
|
129
|
+
end
|
130
|
+
|
131
|
+
def compare_STARTSWITH left, right
|
132
|
+
left.start_with? right
|
133
|
+
end
|
134
|
+
|
135
|
+
def compare_ENDSWITH left, right
|
136
|
+
left.end_with? right
|
137
|
+
end
|
138
|
+
|
139
|
+
def compare_BETWEEN
|
140
|
+
max = stack.pop
|
141
|
+
min = stack.pop
|
142
|
+
val = stack.pop
|
143
|
+
if max.nil? || min.nil? || val.nil?
|
144
|
+
stack.push false
|
145
|
+
else
|
146
|
+
result = val.between? min, max
|
147
|
+
stack.push result
|
148
|
+
end
|
149
|
+
rescue StandardError
|
150
|
+
stack.push false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,69 @@
|
|
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
|
+
ENDSWITH /ends with/
|
25
|
+
STARTSWITH /starts with/
|
26
|
+
BEGINSWITH /begins with/
|
27
|
+
BLANK /is blank/
|
28
|
+
PRESENT /is present/
|
29
|
+
AGO /ago/
|
30
|
+
FROMNOW /from now/
|
31
|
+
DATE /\d{4}[-|\/]\d{2}[-|\/]\d{2}/i
|
32
|
+
DURATION /\d+d/
|
33
|
+
INTEGER /[+-]?\d(_?\d)*\b/
|
34
|
+
STRING /(["'])(?:\\?.)*?\1/
|
35
|
+
IDENTIFIER /[a-z][A-Za-z0-9_]*\b/
|
36
|
+
rule
|
37
|
+
/#{SPACE}/ # ignore space
|
38
|
+
/#{LPAREN}/ { [:LPAREN, text] }
|
39
|
+
/#{RPAREN}/ { [:RPAREN, text] }
|
40
|
+
/#{LBRACKET}/ { [:LBRACKET, text] }
|
41
|
+
/#{RBRACKET}/ { [:RBRACKET, text] }
|
42
|
+
/#{TRUE}/ { [:TRUE, text] }
|
43
|
+
/#{FALSE}/ { [:FALSE, text] }
|
44
|
+
/#{BETWEEN}/ { [:BETWEEN, text] }
|
45
|
+
/#{IN}/ { [:IN, text] }
|
46
|
+
/#{BANG}/ { [:BANG, text] }
|
47
|
+
/#{NOT}/ { [:NOT, text] }
|
48
|
+
/#{DOT}/ { [:DOT, text] }
|
49
|
+
/#{COMMA}/ { [:COMMA, text] }
|
50
|
+
/#{AND}/ { [:AND, text] }
|
51
|
+
/#{OR}/ { [:OR, text] }
|
52
|
+
/#{EQ}/ { [:EQ, text] }
|
53
|
+
/#{GT}/ { [:GT, text] }
|
54
|
+
/#{LT}/ { [:LT, text] }
|
55
|
+
/#{AGO}/ { [:AGO, text] }
|
56
|
+
/#{FROMNOW}/ { [:FROMNOW, text] }
|
57
|
+
/#{ENDSWITH}/ { [:ENDSWITH, text] }
|
58
|
+
/#{STARTSWITH}/ { [:STARTSWITH, text] }
|
59
|
+
/#{BEGINSWITH}/ { [:STARTSWITH, text] }
|
60
|
+
/#{BLANK}/ { [:BLANK, text] }
|
61
|
+
/#{PRESENT}/ { [:PRESENT, text] }
|
62
|
+
/#{DATE}/ { [:DATE, text] }
|
63
|
+
/#{DURATION}/ { [:DURATION, text] }
|
64
|
+
/#{INTEGER}/ { [:INTEGER, text] }
|
65
|
+
/#{STRING}/ { [:STRING, text[1...-1]] }
|
66
|
+
/#{IDENTIFIER}/ { [:IDENTIFIER, text] }
|
67
|
+
inner
|
68
|
+
def do_parse; end
|
69
|
+
end
|
@@ -0,0 +1,187 @@
|
|
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
|
+
ENDSWITH = /ends with/
|
30
|
+
STARTSWITH = /starts with/
|
31
|
+
BEGINSWITH = /begins with/
|
32
|
+
BLANK = /is blank/
|
33
|
+
PRESENT = /is present/
|
34
|
+
AGO = /ago/
|
35
|
+
FROMNOW = /from now/
|
36
|
+
DATE = /\d{4}[-|\/]\d{2}[-|\/]\d{2}/i
|
37
|
+
DURATION = /\d+d/
|
38
|
+
INTEGER = /[+-]?\d(_?\d)*\b/
|
39
|
+
STRING = /(["'])(?:\\?.)*?\1/
|
40
|
+
IDENTIFIER = /[a-z][A-Za-z0-9_]*\b/
|
41
|
+
|
42
|
+
class LexerError < StandardError ; end
|
43
|
+
class ScanError < LexerError ; end
|
44
|
+
|
45
|
+
attr_accessor :lineno
|
46
|
+
attr_accessor :filename
|
47
|
+
attr_accessor :ss
|
48
|
+
attr_accessor :state
|
49
|
+
|
50
|
+
alias :match :ss
|
51
|
+
|
52
|
+
def matches
|
53
|
+
m = (1..9).map { |i| ss[i] }
|
54
|
+
m.pop until m[-1] or m.empty?
|
55
|
+
m
|
56
|
+
end
|
57
|
+
|
58
|
+
def action
|
59
|
+
yield
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_accessor :old_pos
|
63
|
+
|
64
|
+
def column
|
65
|
+
idx = ss.string.rindex("\n", old_pos) || -1
|
66
|
+
old_pos - idx - 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def scanner_class
|
70
|
+
StringScanner
|
71
|
+
end unless instance_methods(false).map(&:to_s).include?("scanner_class")
|
72
|
+
|
73
|
+
def parse str
|
74
|
+
self.ss = scanner_class.new str
|
75
|
+
self.lineno = 1
|
76
|
+
self.state ||= nil
|
77
|
+
|
78
|
+
do_parse
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse_file path
|
82
|
+
self.filename = path
|
83
|
+
open path do |f|
|
84
|
+
parse f.read
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def location
|
89
|
+
[
|
90
|
+
(filename || "<input>"),
|
91
|
+
lineno,
|
92
|
+
column,
|
93
|
+
].compact.join(":")
|
94
|
+
end
|
95
|
+
|
96
|
+
def next_token
|
97
|
+
|
98
|
+
token = nil
|
99
|
+
|
100
|
+
until ss.eos? or token do
|
101
|
+
self.lineno += 1 if ss.peek(1) == "\n"
|
102
|
+
self.old_pos = ss.pos
|
103
|
+
token =
|
104
|
+
case state
|
105
|
+
when nil then
|
106
|
+
case
|
107
|
+
when ss.skip(/#{SPACE}/) then
|
108
|
+
# do nothing
|
109
|
+
when text = ss.scan(/#{LPAREN}/) then
|
110
|
+
action { [:LPAREN, text] }
|
111
|
+
when text = ss.scan(/#{RPAREN}/) then
|
112
|
+
action { [:RPAREN, text] }
|
113
|
+
when text = ss.scan(/#{LBRACKET}/) then
|
114
|
+
action { [:LBRACKET, text] }
|
115
|
+
when text = ss.scan(/#{RBRACKET}/) then
|
116
|
+
action { [:RBRACKET, text] }
|
117
|
+
when text = ss.scan(/#{TRUE}/) then
|
118
|
+
action { [:TRUE, text] }
|
119
|
+
when text = ss.scan(/#{FALSE}/) then
|
120
|
+
action { [:FALSE, text] }
|
121
|
+
when text = ss.scan(/#{BETWEEN}/) then
|
122
|
+
action { [:BETWEEN, text] }
|
123
|
+
when text = ss.scan(/#{IN}/) then
|
124
|
+
action { [:IN, text] }
|
125
|
+
when text = ss.scan(/#{BANG}/) then
|
126
|
+
action { [:BANG, text] }
|
127
|
+
when text = ss.scan(/#{NOT}/) then
|
128
|
+
action { [:NOT, text] }
|
129
|
+
when text = ss.scan(/#{DOT}/) then
|
130
|
+
action { [:DOT, text] }
|
131
|
+
when text = ss.scan(/#{COMMA}/) then
|
132
|
+
action { [:COMMA, text] }
|
133
|
+
when text = ss.scan(/#{AND}/) then
|
134
|
+
action { [:AND, text] }
|
135
|
+
when text = ss.scan(/#{OR}/) then
|
136
|
+
action { [:OR, text] }
|
137
|
+
when text = ss.scan(/#{EQ}/) then
|
138
|
+
action { [:EQ, text] }
|
139
|
+
when text = ss.scan(/#{GT}/) then
|
140
|
+
action { [:GT, text] }
|
141
|
+
when text = ss.scan(/#{LT}/) then
|
142
|
+
action { [:LT, text] }
|
143
|
+
when text = ss.scan(/#{AGO}/) then
|
144
|
+
action { [:AGO, text] }
|
145
|
+
when text = ss.scan(/#{FROMNOW}/) then
|
146
|
+
action { [:FROMNOW, text] }
|
147
|
+
when text = ss.scan(/#{ENDSWITH}/) then
|
148
|
+
action { [:ENDSWITH, text] }
|
149
|
+
when text = ss.scan(/#{STARTSWITH}/) then
|
150
|
+
action { [:STARTSWITH, text] }
|
151
|
+
when text = ss.scan(/#{BEGINSWITH}/) then
|
152
|
+
action { [:STARTSWITH, text] }
|
153
|
+
when text = ss.scan(/#{BLANK}/) then
|
154
|
+
action { [:BLANK, text] }
|
155
|
+
when text = ss.scan(/#{PRESENT}/) then
|
156
|
+
action { [:PRESENT, text] }
|
157
|
+
when text = ss.scan(/#{DATE}/) then
|
158
|
+
action { [:DATE, text] }
|
159
|
+
when text = ss.scan(/#{DURATION}/) then
|
160
|
+
action { [:DURATION, text] }
|
161
|
+
when text = ss.scan(/#{INTEGER}/) then
|
162
|
+
action { [:INTEGER, text] }
|
163
|
+
when text = ss.scan(/#{STRING}/) then
|
164
|
+
action { [:STRING, text[1...-1]] }
|
165
|
+
when text = ss.scan(/#{IDENTIFIER}/) then
|
166
|
+
action { [:IDENTIFIER, text] }
|
167
|
+
else
|
168
|
+
text = ss.string[ss.pos .. -1]
|
169
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
170
|
+
end
|
171
|
+
else
|
172
|
+
raise ScanError, "undefined state at #{location}: '#{state}'"
|
173
|
+
end # token = case state
|
174
|
+
|
175
|
+
next unless token # allow functions to trigger redo w/ nil
|
176
|
+
end # while
|
177
|
+
|
178
|
+
raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless
|
179
|
+
token.nil? || (Array === token && token.size >= 2)
|
180
|
+
|
181
|
+
# auto-switch state
|
182
|
+
self.state = token.last if token && token.first == :state
|
183
|
+
|
184
|
+
token
|
185
|
+
end # def next_token
|
186
|
+
def do_parse; end
|
187
|
+
end # class
|
data/lib/predicator/parser.rb
CHANGED
@@ -1,41 +1,442 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require "predicator/predicates/relation"
|
8
|
-
require "predicator/predicates/equal"
|
9
|
-
require "predicator/predicates/not_equal"
|
10
|
-
require "predicator/predicates/greater_than"
|
11
|
-
require "predicator/predicates/less_than"
|
12
|
-
require "predicator/predicates/greater_than_or_equal"
|
13
|
-
require "predicator/predicates/less_than_or_equal"
|
14
|
-
require "predicator/predicates/between"
|
15
|
-
require "predicator/predicates/true"
|
16
|
-
require "predicator/predicates/false"
|
17
|
-
require "predicator/predicates/and"
|
18
|
-
require "predicator/predicates/or"
|
19
|
-
require "predicator/predicates/not"
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.4.14
|
4
|
+
# from Racc grammer file "".
|
5
|
+
#
|
20
6
|
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
|
9
|
+
require "predicator/lexer.rex"
|
10
|
+
require "predicator/visitors"
|
11
|
+
require "predicator/ast"
|
21
12
|
module Predicator
|
22
|
-
class
|
13
|
+
class Parser < Racc::Parser
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
@lexer.next_token
|
15
|
+
def initialize
|
16
|
+
@lexer = Lexer.new
|
27
17
|
end
|
28
18
|
|
29
19
|
def parse string
|
30
|
-
@lexer
|
20
|
+
@lexer.parse string
|
31
21
|
do_parse
|
32
22
|
end
|
33
23
|
|
24
|
+
def next_token
|
25
|
+
@lexer.next_token
|
26
|
+
end
|
27
|
+
|
34
28
|
def on_error type, val, values
|
35
29
|
super
|
36
|
-
rescue Racc::ParseError
|
30
|
+
rescue Racc::ParseError
|
37
31
|
trace = values.each_with_index.map{|l, i| "#{' ' * i}#{l}"}
|
38
32
|
raise ParseError, "\nparse error on value #{val.inspect}\n#{trace.join("\n")}"
|
39
33
|
end
|
40
|
-
|
34
|
+
|
35
|
+
##### State transition tables begin ###
|
36
|
+
|
37
|
+
racc_action_table = [
|
38
|
+
6, 7, 10, 6, 7, 10, 9, 15, 31, 9,
|
39
|
+
6, 7, 10, 6, 7, 10, 9, 16, 17, 9,
|
40
|
+
16, 17, 14, 16, 17, 14, 52, 6, 7, 10,
|
41
|
+
25, 28, 14, 9, 53, 14, 20, 21, 22, 23,
|
42
|
+
24, 18, 19, 37, 57, 38, 39, 41, 38, 14,
|
43
|
+
26, 27, 16, 17, 37, 38, 56, 39, 41, 37,
|
44
|
+
38, 60, 39, 41, 37, 38, 70, 39, 41, 72,
|
45
|
+
71, 16, 17, 73, 58, 59, 37, 38, 39, 41,
|
46
|
+
61, 52, 37, 37, 38 ]
|
47
|
+
|
48
|
+
racc_action_check = [
|
49
|
+
0, 0, 0, 9, 9, 9, 0, 1, 15, 9,
|
50
|
+
10, 10, 10, 16, 16, 16, 10, 29, 29, 16,
|
51
|
+
1, 1, 0, 32, 32, 9, 24, 17, 17, 17,
|
52
|
+
8, 8, 10, 17, 25, 16, 8, 8, 8, 8,
|
53
|
+
8, 8, 8, 23, 30, 26, 23, 23, 27, 17,
|
54
|
+
8, 8, 30, 30, 20, 20, 28, 20, 20, 21,
|
55
|
+
21, 48, 21, 21, 22, 22, 62, 22, 22, 64,
|
56
|
+
62, 33, 33, 64, 40, 40, 52, 52, 61, 61,
|
57
|
+
49, 53, 60, 71, 73 ]
|
58
|
+
|
59
|
+
racc_action_pointer = [
|
60
|
+
-2, 7, nil, nil, nil, nil, nil, nil, 21, 1,
|
61
|
+
8, nil, nil, nil, nil, 8, 11, 25, nil, nil,
|
62
|
+
32, 37, 42, 21, 20, 15, 22, 25, 32, 4,
|
63
|
+
39, nil, 10, 58, nil, nil, nil, nil, nil, nil,
|
64
|
+
47, nil, nil, nil, nil, nil, nil, nil, 48, 67,
|
65
|
+
nil, nil, 54, 75, nil, nil, nil, nil, nil, nil,
|
66
|
+
60, 53, 59, nil, 62, nil, nil, nil, nil, nil,
|
67
|
+
nil, 61, nil, 61, nil, nil ]
|
68
|
+
|
69
|
+
racc_action_default = [
|
70
|
+
-48, -48, -1, -2, -3, -4, -5, -6, -7, -48,
|
71
|
+
-48, -14, -15, -16, -46, -48, -48, -48, -11, -12,
|
72
|
+
-48, -48, -48, -48, -48, -48, -48, -48, -48, -8,
|
73
|
+
-48, 76, -9, -10, -17, -23, -30, -40, -41, -42,
|
74
|
+
-48, -45, -18, -24, -31, -19, -25, -32, -48, -48,
|
75
|
+
-21, -26, -48, -48, -28, -29, -47, -13, -43, -44,
|
76
|
+
-48, -48, -48, -35, -48, -38, -22, -27, -20, -33,
|
77
|
+
-34, -48, -37, -48, -36, -39 ]
|
78
|
+
|
79
|
+
racc_goto_table = [
|
80
|
+
35, 43, 46, 62, 50, 51, 54, 55, 34, 42,
|
81
|
+
45, 48, 1, 36, 44, 47, 49, 64, nil, nil,
|
82
|
+
nil, 29, 30, nil, nil, nil, nil, nil, 32, 33,
|
83
|
+
nil, nil, 65, 66, 67, nil, nil, nil, nil, nil,
|
84
|
+
63, nil, nil, nil, nil, nil, nil, nil, 68, nil,
|
85
|
+
nil, nil, nil, 75, 69, nil, nil, nil, nil, 74 ]
|
86
|
+
|
87
|
+
racc_goto_check = [
|
88
|
+
12, 12, 12, 15, 11, 13, 12, 12, 10, 10,
|
89
|
+
10, 10, 1, 14, 14, 14, 14, 16, nil, nil,
|
90
|
+
nil, 1, 1, nil, nil, nil, nil, nil, 1, 1,
|
91
|
+
nil, nil, 12, 11, 13, nil, nil, nil, nil, nil,
|
92
|
+
10, nil, nil, nil, nil, nil, nil, nil, 10, nil,
|
93
|
+
nil, nil, nil, 12, 14, nil, nil, nil, nil, 10 ]
|
94
|
+
|
95
|
+
racc_goto_pointer = [
|
96
|
+
nil, 12, nil, nil, nil, nil, nil, nil, nil, nil,
|
97
|
+
-12, -20, -20, -19, -7, -49, -35, nil ]
|
98
|
+
|
99
|
+
racc_goto_default = [
|
100
|
+
nil, nil, 2, 3, 4, 5, 8, 11, 12, 13,
|
101
|
+
nil, nil, nil, nil, nil, nil, nil, 40 ]
|
102
|
+
|
103
|
+
racc_reduce_table = [
|
104
|
+
0, 0, :racc_error,
|
105
|
+
1, 32, :_reduce_none,
|
106
|
+
1, 32, :_reduce_none,
|
107
|
+
1, 32, :_reduce_none,
|
108
|
+
1, 32, :_reduce_none,
|
109
|
+
1, 33, :_reduce_5,
|
110
|
+
1, 33, :_reduce_6,
|
111
|
+
1, 33, :_reduce_7,
|
112
|
+
2, 34, :_reduce_8,
|
113
|
+
3, 34, :_reduce_9,
|
114
|
+
3, 34, :_reduce_10,
|
115
|
+
2, 34, :_reduce_11,
|
116
|
+
2, 34, :_reduce_12,
|
117
|
+
3, 35, :_reduce_13,
|
118
|
+
1, 36, :_reduce_none,
|
119
|
+
1, 36, :_reduce_none,
|
120
|
+
1, 36, :_reduce_none,
|
121
|
+
3, 38, :_reduce_17,
|
122
|
+
3, 38, :_reduce_18,
|
123
|
+
3, 38, :_reduce_19,
|
124
|
+
5, 38, :_reduce_20,
|
125
|
+
3, 38, :_reduce_21,
|
126
|
+
4, 38, :_reduce_22,
|
127
|
+
3, 39, :_reduce_23,
|
128
|
+
3, 39, :_reduce_24,
|
129
|
+
3, 39, :_reduce_25,
|
130
|
+
3, 39, :_reduce_26,
|
131
|
+
4, 39, :_reduce_27,
|
132
|
+
3, 39, :_reduce_28,
|
133
|
+
3, 39, :_reduce_29,
|
134
|
+
3, 40, :_reduce_30,
|
135
|
+
3, 40, :_reduce_31,
|
136
|
+
3, 40, :_reduce_32,
|
137
|
+
5, 40, :_reduce_33,
|
138
|
+
3, 42, :_reduce_34,
|
139
|
+
1, 46, :_reduce_none,
|
140
|
+
3, 46, :_reduce_36,
|
141
|
+
3, 44, :_reduce_37,
|
142
|
+
1, 47, :_reduce_none,
|
143
|
+
3, 47, :_reduce_39,
|
144
|
+
1, 41, :_reduce_40,
|
145
|
+
1, 43, :_reduce_41,
|
146
|
+
1, 45, :_reduce_42,
|
147
|
+
2, 45, :_reduce_43,
|
148
|
+
2, 45, :_reduce_44,
|
149
|
+
1, 48, :_reduce_45,
|
150
|
+
1, 37, :_reduce_46,
|
151
|
+
3, 37, :_reduce_47 ]
|
152
|
+
|
153
|
+
racc_reduce_n = 48
|
154
|
+
|
155
|
+
racc_shift_n = 76
|
156
|
+
|
157
|
+
racc_token_table = {
|
158
|
+
false => 0,
|
159
|
+
:error => 1,
|
160
|
+
:TRUE => 2,
|
161
|
+
:FALSE => 3,
|
162
|
+
:LPAREN => 4,
|
163
|
+
:RPAREN => 5,
|
164
|
+
:LBRACKET => 6,
|
165
|
+
:RBRACKET => 7,
|
166
|
+
:BANG => 8,
|
167
|
+
:NOT => 9,
|
168
|
+
:DOT => 10,
|
169
|
+
:COMMA => 11,
|
170
|
+
:AT => 12,
|
171
|
+
:AND => 13,
|
172
|
+
:OR => 14,
|
173
|
+
:EQ => 15,
|
174
|
+
:GT => 16,
|
175
|
+
:LT => 17,
|
176
|
+
:BETWEEN => 18,
|
177
|
+
:IN => 19,
|
178
|
+
:PRESENT => 20,
|
179
|
+
:BLANK => 21,
|
180
|
+
:INTEGER => 22,
|
181
|
+
:STRING => 23,
|
182
|
+
:IDENTIFIER => 24,
|
183
|
+
:DATE => 25,
|
184
|
+
:DURATION => 26,
|
185
|
+
:AGO => 27,
|
186
|
+
:FROMNOW => 28,
|
187
|
+
:STARTSWITH => 29,
|
188
|
+
:ENDSWITH => 30 }
|
189
|
+
|
190
|
+
racc_nt_base = 31
|
191
|
+
|
192
|
+
racc_use_result_var = false
|
193
|
+
|
194
|
+
Racc_arg = [
|
195
|
+
racc_action_table,
|
196
|
+
racc_action_check,
|
197
|
+
racc_action_default,
|
198
|
+
racc_action_pointer,
|
199
|
+
racc_goto_table,
|
200
|
+
racc_goto_check,
|
201
|
+
racc_goto_default,
|
202
|
+
racc_goto_pointer,
|
203
|
+
racc_nt_base,
|
204
|
+
racc_reduce_table,
|
205
|
+
racc_token_table,
|
206
|
+
racc_shift_n,
|
207
|
+
racc_reduce_n,
|
208
|
+
racc_use_result_var ]
|
209
|
+
|
210
|
+
Racc_token_to_s_table = [
|
211
|
+
"$end",
|
212
|
+
"error",
|
213
|
+
"TRUE",
|
214
|
+
"FALSE",
|
215
|
+
"LPAREN",
|
216
|
+
"RPAREN",
|
217
|
+
"LBRACKET",
|
218
|
+
"RBRACKET",
|
219
|
+
"BANG",
|
220
|
+
"NOT",
|
221
|
+
"DOT",
|
222
|
+
"COMMA",
|
223
|
+
"AT",
|
224
|
+
"AND",
|
225
|
+
"OR",
|
226
|
+
"EQ",
|
227
|
+
"GT",
|
228
|
+
"LT",
|
229
|
+
"BETWEEN",
|
230
|
+
"IN",
|
231
|
+
"PRESENT",
|
232
|
+
"BLANK",
|
233
|
+
"INTEGER",
|
234
|
+
"STRING",
|
235
|
+
"IDENTIFIER",
|
236
|
+
"DATE",
|
237
|
+
"DURATION",
|
238
|
+
"AGO",
|
239
|
+
"FROMNOW",
|
240
|
+
"STARTSWITH",
|
241
|
+
"ENDSWITH",
|
242
|
+
"$start",
|
243
|
+
"predicate",
|
244
|
+
"boolean_predicate",
|
245
|
+
"logical_predicate",
|
246
|
+
"group_predicate",
|
247
|
+
"comparison_predicate",
|
248
|
+
"variable",
|
249
|
+
"integer_comparison_predicate",
|
250
|
+
"string_comparison_predicate",
|
251
|
+
"date_comparison_predicate",
|
252
|
+
"integer",
|
253
|
+
"integer_array",
|
254
|
+
"string",
|
255
|
+
"string_array",
|
256
|
+
"date",
|
257
|
+
"integer_array_contents",
|
258
|
+
"string_array_contents",
|
259
|
+
"duration" ]
|
260
|
+
|
261
|
+
Racc_debug_parser = false
|
262
|
+
|
263
|
+
##### State transition tables end #####
|
264
|
+
|
265
|
+
# reduce 0 omitted
|
266
|
+
|
267
|
+
# reduce 1 omitted
|
268
|
+
|
269
|
+
# reduce 2 omitted
|
270
|
+
|
271
|
+
# reduce 3 omitted
|
272
|
+
|
273
|
+
# reduce 4 omitted
|
274
|
+
|
275
|
+
def _reduce_5(val, _values)
|
276
|
+
AST::True.new true
|
277
|
+
end
|
278
|
+
|
279
|
+
def _reduce_6(val, _values)
|
280
|
+
AST::False.new false
|
281
|
+
end
|
282
|
+
|
283
|
+
def _reduce_7(val, _values)
|
284
|
+
AST::BooleanVariable.new val.first
|
285
|
+
end
|
286
|
+
|
287
|
+
def _reduce_8(val, _values)
|
288
|
+
AST::Not.new val.last
|
289
|
+
end
|
290
|
+
|
291
|
+
def _reduce_9(val, _values)
|
292
|
+
AST::And.new val.first, val.last
|
293
|
+
end
|
294
|
+
|
295
|
+
def _reduce_10(val, _values)
|
296
|
+
AST::Or.new val.first, val.last
|
297
|
+
end
|
298
|
+
|
299
|
+
def _reduce_11(val, _values)
|
300
|
+
AST::Present.new val.first
|
301
|
+
end
|
302
|
+
|
303
|
+
def _reduce_12(val, _values)
|
304
|
+
AST::Blank.new val.first
|
305
|
+
end
|
306
|
+
|
307
|
+
def _reduce_13(val, _values)
|
308
|
+
AST::Group.new val[1]
|
309
|
+
end
|
310
|
+
|
311
|
+
# reduce 14 omitted
|
312
|
+
|
313
|
+
# reduce 15 omitted
|
314
|
+
|
315
|
+
# reduce 16 omitted
|
316
|
+
|
317
|
+
def _reduce_17(val, _values)
|
318
|
+
AST::IntegerEqual.new val.first, val.last
|
319
|
+
end
|
320
|
+
|
321
|
+
def _reduce_18(val, _values)
|
322
|
+
AST::IntegerGreaterThan.new val.first, val.last
|
323
|
+
end
|
324
|
+
|
325
|
+
def _reduce_19(val, _values)
|
326
|
+
AST::IntegerLessThan.new val.first, val.last
|
41
327
|
end
|
328
|
+
|
329
|
+
def _reduce_20(val, _values)
|
330
|
+
AST::IntegerBetween.new val.first, val[2], val.last
|
331
|
+
end
|
332
|
+
|
333
|
+
def _reduce_21(val, _values)
|
334
|
+
AST::IntegerIn.new val.first, val.last
|
335
|
+
end
|
336
|
+
|
337
|
+
def _reduce_22(val, _values)
|
338
|
+
AST::IntegerNotIn.new val.first, val.last
|
339
|
+
end
|
340
|
+
|
341
|
+
def _reduce_23(val, _values)
|
342
|
+
AST::StringEqual.new val.first, val.last
|
343
|
+
end
|
344
|
+
|
345
|
+
def _reduce_24(val, _values)
|
346
|
+
AST::StringGreaterThan.new val.first, val.last
|
347
|
+
end
|
348
|
+
|
349
|
+
def _reduce_25(val, _values)
|
350
|
+
AST::StringLessThan.new val.first, val.last
|
351
|
+
end
|
352
|
+
|
353
|
+
def _reduce_26(val, _values)
|
354
|
+
AST::StringIn.new val.first, val.last
|
355
|
+
end
|
356
|
+
|
357
|
+
def _reduce_27(val, _values)
|
358
|
+
AST::StringNotIn.new val.first, val.last
|
359
|
+
end
|
360
|
+
|
361
|
+
def _reduce_28(val, _values)
|
362
|
+
AST::StringStartsWith.new val.first, val.last
|
363
|
+
end
|
364
|
+
|
365
|
+
def _reduce_29(val, _values)
|
366
|
+
AST::StringEndsWith.new val.first, val.last
|
367
|
+
end
|
368
|
+
|
369
|
+
def _reduce_30(val, _values)
|
370
|
+
AST::DateEqual.new val.first, val.last
|
371
|
+
end
|
372
|
+
|
373
|
+
def _reduce_31(val, _values)
|
374
|
+
AST::DateGreaterThan.new val.first, val.last
|
375
|
+
end
|
376
|
+
|
377
|
+
def _reduce_32(val, _values)
|
378
|
+
AST::DateLessThan.new val.first, val.last
|
379
|
+
end
|
380
|
+
|
381
|
+
def _reduce_33(val, _values)
|
382
|
+
AST::DateBetween.new val.first, val[2], val.last
|
383
|
+
end
|
384
|
+
|
385
|
+
def _reduce_34(val, _values)
|
386
|
+
AST::IntegerArray.new val[1]
|
387
|
+
end
|
388
|
+
|
389
|
+
# reduce 35 omitted
|
390
|
+
|
391
|
+
def _reduce_36(val, _values)
|
392
|
+
[val.first, val.last].flatten
|
393
|
+
end
|
394
|
+
|
395
|
+
def _reduce_37(val, _values)
|
396
|
+
AST::StringArray.new val[1]
|
397
|
+
end
|
398
|
+
|
399
|
+
# reduce 38 omitted
|
400
|
+
|
401
|
+
def _reduce_39(val, _values)
|
402
|
+
[val.first, val.last].flatten
|
403
|
+
end
|
404
|
+
|
405
|
+
def _reduce_40(val, _values)
|
406
|
+
AST::Integer.new val.first.to_i
|
407
|
+
end
|
408
|
+
|
409
|
+
def _reduce_41(val, _values)
|
410
|
+
AST::String.new val.first
|
411
|
+
end
|
412
|
+
|
413
|
+
def _reduce_42(val, _values)
|
414
|
+
AST::Date.new val.first
|
415
|
+
end
|
416
|
+
|
417
|
+
def _reduce_43(val, _values)
|
418
|
+
AST::DateAgo.new val.first
|
419
|
+
end
|
420
|
+
|
421
|
+
def _reduce_44(val, _values)
|
422
|
+
AST::DateFromNow.new val.first
|
423
|
+
end
|
424
|
+
|
425
|
+
def _reduce_45(val, _values)
|
426
|
+
AST::Duration.new val.first
|
427
|
+
end
|
428
|
+
|
429
|
+
def _reduce_46(val, _values)
|
430
|
+
AST::Variable.new val.first
|
431
|
+
end
|
432
|
+
|
433
|
+
def _reduce_47(val, _values)
|
434
|
+
AST::Variable.new [val.first, val.last].flatten.join(".")
|
435
|
+
end
|
436
|
+
|
437
|
+
def _reduce_none(val, _values)
|
438
|
+
val[0]
|
439
|
+
end
|
440
|
+
|
441
|
+
end # class Parser
|
442
|
+
end # module Predicator
|