lamep 0.1 → 0.2
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 +4 -4
- data/lamep.gemspec +1 -1
- data/lib/lamep/Expressions/and.rb +4 -0
- data/lib/lamep/Expressions/equal.rb +4 -0
- data/lib/lamep/Expressions/greater_than.rb +5 -0
- data/lib/lamep/Expressions/greater_than_equal.rb +4 -0
- data/lib/lamep/Expressions/less_than.rb +4 -0
- data/lib/lamep/Expressions/less_than_equal.rb +4 -0
- data/lib/lamep/Expressions/not_equal.rb +4 -0
- data/lib/lamep/Expressions/operator.rb +4 -0
- data/lib/lamep/Expressions/or.rb +4 -0
- data/lib/lamep/Expressions/unary_minus.rb +4 -0
- data/lib/lamep/Expressions/value_expression.rb +8 -0
- data/lib/lamep/abstract_syntax_tree_builder.rb +2 -2
- data/lib/lamep/exceptions/missing_left_parentheses_error.rb +2 -0
- data/lib/lamep/exceptions/missing_right_parentheses_error.rb +2 -0
- data/lib/lamep/exceptions/not_enough_operands_exception.rb +10 -0
- data/lib/lamep/exceptions/not_enough_operators_exception.rb +2 -0
- data/lib/lamep/shunting_yard.rb +3 -3
- data/lib/lamep.rb +28 -0
- data/spec/lib/abstract_syntax_tree_builder_spec.rb +2 -2
- data/spec/lib/evaluation_spec.rb +66 -0
- data/spec/lib/shunting_yard_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -16
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a557b4e3fe5b67811e338d680c486345ec1bb7ed
|
4
|
+
data.tar.gz: f9ad186e84d8465682dfc46ce32da2362663d1db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64b5b8d9bed78b78e68b481e86bdc641b4b34dc3b16c8365e2c9d45348c751129a53d9b5cfdfe8271bdabd23f08a5b742f94ef5cabb1e79f3099e710be5ab99f
|
7
|
+
data.tar.gz: 67133170d913738facf242cd13a124802306a11ef9d244c47e54049a6820016320691ff258403bfa9e563e909d3173f624d709f8b7ff6fef5213cd547bedf0c5
|
data/lamep.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'lamep'
|
7
|
-
spec.version = 0.
|
7
|
+
spec.version = 0.2
|
8
8
|
spec.authors = ['Martin Svoboda', 'Miroslav Csonka']
|
9
9
|
spec.email = ['miroslav.csonka@gmail.com']
|
10
10
|
spec.summary = %q{Logical and mathematical expression parser}
|
data/lib/lamep/Expressions/or.rb
CHANGED
@@ -7,10 +7,10 @@ class AbstractSyntaxTreeBuilder
|
|
7
7
|
def build_tree
|
8
8
|
until @postfix.length == 1
|
9
9
|
operator_index = first_operator_index
|
10
|
-
fail
|
10
|
+
fail NotEnoughOperatorsException if operator_index.nil?
|
11
11
|
exp = Operator.factory!(@postfix.slice!(operator_index))
|
12
12
|
most_left_child = operator_index - exp::ARITY
|
13
|
-
fail
|
13
|
+
fail NotEnoughOperandsException, expression: exp if most_left_child < 0
|
14
14
|
children = @postfix.slice!(most_left_child, exp::ARITY)
|
15
15
|
@postfix.insert(most_left_child, exp.new(*children))
|
16
16
|
end
|
data/lib/lamep/shunting_yard.rb
CHANGED
@@ -16,7 +16,7 @@ class ShuntingYard
|
|
16
16
|
@stack << token
|
17
17
|
when ')'
|
18
18
|
bracket_sum -= 1
|
19
|
-
fail
|
19
|
+
fail MissingLeftParenthesesError if bracket_sum < 0
|
20
20
|
burn_stack_to_parentheses
|
21
21
|
else
|
22
22
|
if Operator.exists?(token)
|
@@ -27,12 +27,12 @@ class ShuntingYard
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
-
fail
|
30
|
+
fail MissingRightParenthesesError if bracket_sum > 0
|
31
31
|
@output += @stack.reverse
|
32
32
|
@output
|
33
33
|
end
|
34
34
|
|
35
|
-
def burn_stack_to_higher_precedence(token)
|
35
|
+
private def burn_stack_to_higher_precedence(token)
|
36
36
|
until @stack.empty? || @stack.last == '(' || Operator.precedence!(token) < Operator.precedence!(@stack.last)
|
37
37
|
@output << @stack.pop
|
38
38
|
end
|
data/lib/lamep.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require './lib/lamep/exceptions/not_enough_operands_exception'
|
2
|
+
require './lib/lamep/exceptions/not_enough_operators_exception'
|
3
|
+
require './lib/lamep/exceptions/missing_left_parentheses_error'
|
4
|
+
require './lib/lamep/exceptions/missing_right_parentheses_error'
|
5
|
+
require './lib/lamep/Expressions/operator'
|
6
|
+
require './lib/lamep/Expressions/arity1_operators'
|
7
|
+
require './lib/lamep/Expressions/arity2_operators'
|
8
|
+
require './lib/lamep/Expressions/value_expression'
|
9
|
+
require './lib/lamep/token_parser'
|
10
|
+
require './lib/lamep/shunting_yard'
|
11
|
+
require './lib/lamep/Expressions/equal'
|
12
|
+
require './lib/lamep/Expressions/greater_than'
|
13
|
+
require './lib/lamep/Expressions/less_than'
|
14
|
+
require './lib/lamep/Expressions/greater_than_equal'
|
15
|
+
require './lib/lamep/Expressions/less_than_equal'
|
16
|
+
require './lib/lamep/Expressions/and'
|
17
|
+
require './lib/lamep/Expressions/or'
|
18
|
+
require './lib/lamep/Expressions/unary_minus'
|
19
|
+
require './lib/lamep/Expressions/not_equal'
|
20
|
+
require './lib/lamep/abstract_syntax_tree_builder'
|
21
|
+
|
22
|
+
class Lamep
|
23
|
+
def evaluate(expression, attributes={})
|
24
|
+
tokens = TokenParser.new.parse(expression)
|
25
|
+
postfix = ShuntingYard.new(tokens).postfix
|
26
|
+
AbstractSyntaxTreeBuilder.new(postfix).build_tree.evaluate(attributes)
|
27
|
+
end
|
28
|
+
end
|
@@ -57,11 +57,11 @@ describe AbstractSyntaxTreeBuilder do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'only operands' do
|
60
|
-
expect {AbstractSyntaxTreeBuilder.new(%w(materiál cena)).build_tree }.to raise_error(
|
60
|
+
expect {AbstractSyntaxTreeBuilder.new(%w(materiál cena)).build_tree }.to raise_error(NotEnoughOperatorsException)
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'only operators' do
|
64
|
-
expect {AbstractSyntaxTreeBuilder.new(%w(&& -)).build_tree }.to raise_error(
|
64
|
+
expect {AbstractSyntaxTreeBuilder.new(%w(&& -)).build_tree }.to raise_error(NotEnoughOperandsException)
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
|
3
|
+
describe 'Evaluating of expressions' do
|
4
|
+
|
5
|
+
def matches?(filter, values={})
|
6
|
+
tokens = TokenParser.new.parse(filter)
|
7
|
+
postfix = ShuntingYard.new(tokens).postfix
|
8
|
+
AbstractSyntaxTreeBuilder.new(postfix).build_tree.evaluate(values)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Equal do
|
12
|
+
|
13
|
+
it 'is false' do
|
14
|
+
expect(matches?('true = false')).to eq false
|
15
|
+
expect(matches?('true = true')).to eq true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'replacing value holders with actual values' do
|
19
|
+
expect(matches?('name = mirek', { 'name' => 'mirek' })).to eq true
|
20
|
+
expect(matches?('name = mirek', { 'name' => 'Tomáš' })).to eq false
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
it GreaterThan do
|
27
|
+
expect(matches?('price > 200', { 'price' => '300' })).to eq true
|
28
|
+
expect(matches?('price > 200', { 'price' => 150 })).to eq false
|
29
|
+
end
|
30
|
+
|
31
|
+
it LessThan do
|
32
|
+
expect(matches?('(price < 200)', { 'price' => 150 })).to eq true
|
33
|
+
expect(matches?('(price < 200)', { 'price' => 500 })).to eq false
|
34
|
+
end
|
35
|
+
|
36
|
+
it GreaterThanEqual do
|
37
|
+
expect(matches?('price >= 200', { 'price' => '200' })).to eq true
|
38
|
+
expect(matches?('price >= 200', { 'price' => 201 })).to eq true
|
39
|
+
expect(matches?('price >= 200', { 'price' => 199 })).to eq false
|
40
|
+
end
|
41
|
+
|
42
|
+
it LessThanEqual do
|
43
|
+
expect(matches?('(price <= 200)', { 'price' => 201 })).to eq false
|
44
|
+
expect(matches?('(price <= 200)', { 'price' => 200 })).to eq true
|
45
|
+
expect(matches?('(price <= 200)', { 'price' => 199 })).to eq true
|
46
|
+
end
|
47
|
+
|
48
|
+
it And do
|
49
|
+
expect(matches?('(price > 200) && price < 500', { 'price' => 400 })).to eq true
|
50
|
+
end
|
51
|
+
|
52
|
+
it NotEqual do
|
53
|
+
expect(matches?('name != mirek')).to eq true
|
54
|
+
expect(matches?('name != name')).to eq false
|
55
|
+
end
|
56
|
+
|
57
|
+
it Or do
|
58
|
+
expect(matches?('(price > 200) || (category = 1)', { 'price' => 0, 'category' => '1' })).to eq true
|
59
|
+
expect(matches?('price > 200 || category = 1', { 'price' => '0', 'category' => '0' })).to eq false
|
60
|
+
end
|
61
|
+
|
62
|
+
it UnaryMinus do
|
63
|
+
expect(matches?('-1 = -(1)', {})).to eq true
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -35,8 +35,8 @@ describe ShuntingYard do
|
|
35
35
|
it 'brackets' do
|
36
36
|
returns %w(( cena > 180 )), %w(cena 180 >)
|
37
37
|
returns %w(( ( cena ) > ( 180 ) )), %w(cena 180 >)
|
38
|
-
expect { ShuntingYard.new(%w{( cena ) > 180 )}).postfix }.to raise_error(
|
39
|
-
expect { ShuntingYard.new(%w{((( cena ) > 180 )}).postfix }.to raise_error(
|
38
|
+
expect { ShuntingYard.new(%w{( cena ) > 180 )}).postfix }.to raise_error(MissingLeftParenthesesError )
|
39
|
+
expect { ShuntingYard.new(%w{( ( ( cena ) > 180 )}).postfix }.to raise_error(MissingRightParenthesesError)
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'difficult cases' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,4 @@
|
|
1
|
-
require './lib/lamep
|
2
|
-
require './lib/lamep/Expressions/arity1_operators'
|
3
|
-
require './lib/lamep/Expressions/arity2_operators'
|
4
|
-
require './lib/lamep/Expressions/value_expression'
|
5
|
-
require './lib/lamep/token_parser'
|
6
|
-
require './lib/lamep/shunting_yard'
|
7
|
-
require './lib/lamep/Expressions/equal'
|
8
|
-
require './lib/lamep/Expressions/greater_than'
|
9
|
-
require './lib/lamep/Expressions/less_than'
|
10
|
-
require './lib/lamep/Expressions/greater_than_equal'
|
11
|
-
require './lib/lamep/Expressions/less_than_equal'
|
12
|
-
require './lib/lamep/Expressions/and'
|
13
|
-
require './lib/lamep/Expressions/or'
|
14
|
-
require './lib/lamep/Expressions/unary_minus'
|
15
|
-
require './lib/lamep/Expressions/not_equal'
|
16
|
-
require './lib/lamep/abstract_syntax_tree_builder'
|
1
|
+
require './lib/lamep'
|
17
2
|
|
18
3
|
RSpec.configure do |config|
|
19
4
|
# rspec-expectations config goes here. You can use an alternate
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lamep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Svoboda
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01-
|
12
|
+
date: 2015-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- README.md
|
68
68
|
- Rakefile
|
69
69
|
- lamep.gemspec
|
70
|
+
- lib/lamep.rb
|
70
71
|
- lib/lamep/Expressions/and.rb
|
71
72
|
- lib/lamep/Expressions/arity1_operators.rb
|
72
73
|
- lib/lamep/Expressions/arity2_operators.rb
|
@@ -81,10 +82,15 @@ files:
|
|
81
82
|
- lib/lamep/Expressions/unary_minus.rb
|
82
83
|
- lib/lamep/Expressions/value_expression.rb
|
83
84
|
- lib/lamep/abstract_syntax_tree_builder.rb
|
85
|
+
- lib/lamep/exceptions/missing_left_parentheses_error.rb
|
86
|
+
- lib/lamep/exceptions/missing_right_parentheses_error.rb
|
87
|
+
- lib/lamep/exceptions/not_enough_operands_exception.rb
|
88
|
+
- lib/lamep/exceptions/not_enough_operators_exception.rb
|
84
89
|
- lib/lamep/shunting_yard.rb
|
85
90
|
- lib/lamep/token_parser.rb
|
86
91
|
- spec/lib/Expressions/operators_spec.rb
|
87
92
|
- spec/lib/abstract_syntax_tree_builder_spec.rb
|
93
|
+
- spec/lib/evaluation_spec.rb
|
88
94
|
- spec/lib/shunting_yard_spec.rb
|
89
95
|
- spec/lib/token_parser_spec.rb
|
90
96
|
- spec/spec_helper.rb
|
@@ -115,6 +121,7 @@ summary: Logical and mathematical expression parser
|
|
115
121
|
test_files:
|
116
122
|
- spec/lib/Expressions/operators_spec.rb
|
117
123
|
- spec/lib/abstract_syntax_tree_builder_spec.rb
|
124
|
+
- spec/lib/evaluation_spec.rb
|
118
125
|
- spec/lib/shunting_yard_spec.rb
|
119
126
|
- spec/lib/token_parser_spec.rb
|
120
127
|
- spec/spec_helper.rb
|