dentaku 0.2.3 → 0.2.4
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.
- data/lib/dentaku/evaluator.rb +11 -1
- data/lib/dentaku/tokenizer.rb +6 -6
- data/lib/dentaku/version.rb +1 -1
- data/spec/evaluator_spec.rb +11 -0
- metadata +7 -13
data/lib/dentaku/evaluator.rb
CHANGED
|
@@ -9,6 +9,8 @@ module Dentaku
|
|
|
9
9
|
T_ADDSUB = TokenMatcher.new(:operator, [:add, :subtract])
|
|
10
10
|
T_MULDIV = TokenMatcher.new(:operator, [:multiply, :divide])
|
|
11
11
|
T_COMPARATOR = TokenMatcher.new(:comparator)
|
|
12
|
+
T_COMP_GT = TokenMatcher.new(:comparator, [:gt, :ge])
|
|
13
|
+
T_COMP_LT = TokenMatcher.new(:comparator, [:lt, :le])
|
|
12
14
|
T_OPEN = TokenMatcher.new(:grouping, :open)
|
|
13
15
|
T_CLOSE = TokenMatcher.new(:grouping, :close)
|
|
14
16
|
T_COMMA = TokenMatcher.new(:grouping, :comma)
|
|
@@ -24,6 +26,8 @@ module Dentaku
|
|
|
24
26
|
P_GROUP = [T_OPEN, T_NON_GROUP_STAR, T_CLOSE]
|
|
25
27
|
P_MATH_ADD = [T_NUMERIC, T_ADDSUB, T_NUMERIC]
|
|
26
28
|
P_MATH_MUL = [T_NUMERIC, T_MULDIV, T_NUMERIC]
|
|
29
|
+
P_RANGE_ASC = [T_NUMERIC, T_COMP_LT, T_NUMERIC, T_COMP_LT, T_NUMERIC]
|
|
30
|
+
P_RANGE_DESC = [T_NUMERIC, T_COMP_GT, T_NUMERIC, T_COMP_GT, T_NUMERIC]
|
|
27
31
|
P_NUM_COMP = [T_NUMERIC, T_COMPARATOR, T_NUMERIC]
|
|
28
32
|
P_STR_COMP = [T_STRING, T_COMPARATOR, T_STRING]
|
|
29
33
|
P_COMBINE = [T_LOGICAL, T_COMBINATOR, T_LOGICAL]
|
|
@@ -40,6 +44,8 @@ module Dentaku
|
|
|
40
44
|
[P_GROUP, :evaluate_group],
|
|
41
45
|
[P_MATH_MUL, :apply],
|
|
42
46
|
[P_MATH_ADD, :apply],
|
|
47
|
+
[P_RANGE_ASC, :expand_range],
|
|
48
|
+
[P_RANGE_DESC, :expand_range],
|
|
43
49
|
[P_NUM_COMP, :apply],
|
|
44
50
|
[P_STR_COMP, :apply],
|
|
45
51
|
[P_COMBINE, :apply]
|
|
@@ -72,7 +78,7 @@ module Dentaku
|
|
|
72
78
|
|
|
73
79
|
def evaluate_step(token_stream, start, length, evaluator)
|
|
74
80
|
expr = token_stream.slice!(start, length)
|
|
75
|
-
token_stream.insert start, self.send(evaluator, *expr)
|
|
81
|
+
token_stream.insert start, *self.send(evaluator, *expr)
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
def find_rule_match(pattern, token_stream)
|
|
@@ -124,6 +130,10 @@ module Dentaku
|
|
|
124
130
|
end
|
|
125
131
|
end
|
|
126
132
|
|
|
133
|
+
def expand_range(left, oper1, middle, oper2, right)
|
|
134
|
+
[left, oper1, middle, Token.new(:combinator, :and), middle, oper2, right]
|
|
135
|
+
end
|
|
136
|
+
|
|
127
137
|
def if(*args)
|
|
128
138
|
_, open, condition, _, true_value, _, false_value, close = args
|
|
129
139
|
|
data/lib/dentaku/tokenizer.rb
CHANGED
|
@@ -6,9 +6,9 @@ module Dentaku
|
|
|
6
6
|
class Tokenizer
|
|
7
7
|
SCANNERS = [
|
|
8
8
|
TokenScanner.new(:whitespace, '\s+'),
|
|
9
|
-
TokenScanner.new(:numeric, '(\d+(\.\d+)?|\.\d+)', lambda{|raw| raw =~ /\./ ? raw.to_f : raw.to_i }),
|
|
10
|
-
TokenScanner.new(:string, '"[^"]*"', lambda{|raw| raw.gsub(/^"|"$/, '') }),
|
|
11
|
-
TokenScanner.new(:string, "'[^']*'", lambda{|raw| raw.gsub(/^'|'$/, '') }),
|
|
9
|
+
TokenScanner.new(:numeric, '(\d+(\.\d+)?|\.\d+)', lambda { |raw| raw =~ /\./ ? raw.to_f : raw.to_i }),
|
|
10
|
+
TokenScanner.new(:string, '"[^"]*"', lambda { |raw| raw.gsub(/^"|"$/, '') }),
|
|
11
|
+
TokenScanner.new(:string, "'[^']*'", lambda { |raw| raw.gsub(/^'|'$/, '') }),
|
|
12
12
|
TokenScanner.new(:operator, '\+|-|\*|\/', lambda do |raw|
|
|
13
13
|
case raw
|
|
14
14
|
when '+' then :add
|
|
@@ -35,9 +35,9 @@ module Dentaku
|
|
|
35
35
|
when '=' then :eq
|
|
36
36
|
end
|
|
37
37
|
end),
|
|
38
|
-
TokenScanner.new(:combinator, '(and|or)\b', lambda {|raw| raw.strip.downcase.to_sym }),
|
|
39
|
-
TokenScanner.new(:function, '(if|round)\b', lambda {|raw| raw.strip.to_sym }),
|
|
40
|
-
TokenScanner.new(:identifier, '[a-z_]+', lambda {|raw| raw.downcase.to_sym })
|
|
38
|
+
TokenScanner.new(:combinator, '(and|or)\b', lambda { |raw| raw.strip.downcase.to_sym }),
|
|
39
|
+
TokenScanner.new(:function, '(if|round)\b', lambda { |raw| raw.strip.to_sym }),
|
|
40
|
+
TokenScanner.new(:identifier, '[a-z_]+', lambda { |raw| raw.downcase.to_sym })
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
LPAREN = TokenMatcher.new(:grouping, :open)
|
data/lib/dentaku/version.rb
CHANGED
data/spec/evaluator_spec.rb
CHANGED
|
@@ -60,6 +60,17 @@ describe Dentaku::Evaluator do
|
|
|
60
60
|
evaluator.evaluate(token_stream(5, :gt, 1)).should be_true
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
it 'should expand inequality ranges' do
|
|
64
|
+
stream = token_stream(5, :lt, 10, :le, 10)
|
|
65
|
+
expected = token_stream(5, :lt, 10, :and, 10, :le, 10)
|
|
66
|
+
evaluator.evaluate_step(stream, 0, 5, :expand_range).should eq(expected)
|
|
67
|
+
|
|
68
|
+
evaluator.evaluate(token_stream(5, :lt, 10, :le, 10)).should be_true
|
|
69
|
+
evaluator.evaluate(token_stream(3, :gt, 5, :ge, 1)).should be_false
|
|
70
|
+
|
|
71
|
+
lambda { evaluator.evaluate(token_stream(3, :gt, 2, :lt, 1)) }.should raise_error
|
|
72
|
+
end
|
|
73
|
+
|
|
63
74
|
it 'should evaluate combined conditionals' do
|
|
64
75
|
evaluator.evaluate(token_stream(5, :gt, 1, :or, :false)).should be_true
|
|
65
76
|
evaluator.evaluate(token_stream(5, :gt, 1, :and, :false)).should be_false
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dentaku
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.4
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rake
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70240118188300 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
@@ -21,10 +21,10 @@ dependencies:
|
|
|
21
21
|
version: '0'
|
|
22
22
|
type: :development
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70240118188300
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: rspec
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70240118187880 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ! '>='
|
|
@@ -32,7 +32,7 @@ dependencies:
|
|
|
32
32
|
version: '0'
|
|
33
33
|
type: :development
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70240118187880
|
|
36
36
|
description: ! ' Dentaku is a parser and evaluator for mathematical formulas
|
|
37
37
|
|
|
38
38
|
'
|
|
@@ -75,21 +75,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
75
75
|
- - ! '>='
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
77
|
version: '0'
|
|
78
|
-
segments:
|
|
79
|
-
- 0
|
|
80
|
-
hash: -2425877477882422646
|
|
81
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
79
|
none: false
|
|
83
80
|
requirements:
|
|
84
81
|
- - ! '>='
|
|
85
82
|
- !ruby/object:Gem::Version
|
|
86
83
|
version: '0'
|
|
87
|
-
segments:
|
|
88
|
-
- 0
|
|
89
|
-
hash: -2425877477882422646
|
|
90
84
|
requirements: []
|
|
91
85
|
rubyforge_project: dentaku
|
|
92
|
-
rubygems_version: 1.8.
|
|
86
|
+
rubygems_version: 1.8.11
|
|
93
87
|
signing_key:
|
|
94
88
|
specification_version: 3
|
|
95
89
|
summary: A formula language parser and evaluator
|