boolean-expression 0.0.1 → 0.0.1.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.
@@ -22,120 +22,113 @@ unless defined?(Boolean)
22
22
  end
23
23
 
24
24
  class Boolean::Expression
25
- EvaluationError = Class.new(Exception)
26
-
27
- class << self
28
- def parse (text)
29
- base = Group.new
30
- name = nil
31
- stack = [base]
32
- logic = nil
33
-
34
- text.to_s.each_char.to_a.each_with_index {|char, index|
35
- begin
36
- if char == ')' && stack.length == 1
37
- raise SyntaxError.new('Closing an unopened parenthesis')
38
- end
39
-
40
- if char.match(/\s|\(|\)/) || (!logic && ['|', '&', '!'].member?(char))
41
- if logic || (name && name.match(/(and|or|not)/i))
42
- stack.last << Logic.new(logic || name)
43
- logic = nil
44
- name = nil
45
- elsif name
46
- stack.last << Name.new(name)
47
- name = nil
48
- end
49
- end
50
-
51
- if name || logic
52
- name << char if name
53
- logic << char if logic
54
- else
55
- case char
56
- when '('; stack.push Group.new
57
- when ')'; stack[-2] << stack.pop
58
- when '|'; logic = '|'
59
- when '&'; logic = '&'
60
- when '!'; stack.last << Logic.new('!')
61
- else; name = char if !char.match(/\s/)
62
- end
63
- end
64
- rescue SyntaxError => e
65
- raise "#{e.message} near `#{text[index - 4, 8]}` at character #{index}"
66
- end
67
- }
68
-
69
- if stack.length != 1
70
- raise SyntaxError.new('Not all parenthesis are closed')
71
- end
72
-
73
- if logic
74
- raise SyntaxError.new('The expression cannot end with a logic operator')
75
- end
76
-
77
- base << Name.new(name) if name
78
-
79
- if base.length == 1 && base.first.is_a?(Group)
80
- base = base.first
81
- end
82
-
83
- self.new(base)
84
- end
85
-
86
- alias [] parse
87
- end
88
-
89
- attr_reader :base
90
-
91
- def initialize (base=Group.new)
92
- @base = base
93
- end
94
-
95
- def evaluate (*args)
96
- _evaluate(@base, args.flatten.compact.map {|piece|
97
- piece.to_s
98
- })
99
- end
100
-
101
- alias [] evaluate
102
-
103
- def to_s
104
- @base.inspect
105
- end
106
-
107
- private
108
- def _evaluate (group, pieces)
109
- return false if pieces.empty?
110
-
111
- values = []
112
-
113
- group.each {|thing|
114
- case thing
115
- when Logic; values << thing
116
- when Group; values << _evaluate(thing, pieces)
117
- when Name; values << pieces.member?(thing.to_s)
118
- end
119
- }
120
-
121
- at = 0
122
- while at < values.length
123
- if values[at].is_a?(Logic) && values[at].type == :not
124
- values[at] = values.delete_at(at).evaluate(values[at])
125
- values[at] = !values[at]
126
- end
127
-
128
- at += 1
129
- end
130
-
131
- while values.length > 1
132
- a, logic, b = values.shift(3)
133
-
134
- values.unshift(logic.evaluate(a, b))
135
- end
136
-
137
- values.first
138
- end
25
+ def self.parse (text)
26
+ base = Group.new
27
+ name = nil
28
+ stack = [base]
29
+ logic = nil
30
+
31
+ text.to_s.chars.each_with_index {|char, index|
32
+ begin
33
+ if char == ')' && stack.length == 1
34
+ raise SyntaxError, 'closing an unopened parenthesis'
35
+ end
36
+
37
+ if char.match(/\s|\(|\)/) || (!logic && ['|', '&', '!'].member?(char))
38
+ if logic || (name && name.match(/(and|or|not)/i))
39
+ stack.last << Logic.new(logic || name)
40
+ logic = nil
41
+ name = nil
42
+ elsif name
43
+ stack.last << Name.new(name)
44
+ name = nil
45
+ end
46
+ end
47
+
48
+ if name || logic
49
+ name << char if name
50
+ logic << char if logic
51
+ else
52
+ case char
53
+ when '(' then stack.push Group.new
54
+ when ')' then stack[-2] << stack.pop
55
+ when '|' then logic = '|'
56
+ when '&' then logic = '&'
57
+ when '!' then stack.last << Logic.new('!')
58
+ else name = char if !char.match(/\s/)
59
+ end
60
+ end
61
+ rescue SyntaxError => e
62
+ raise "#{e.message} near `#{text[index - 4, 8]}` at character #{index}"
63
+ end
64
+ }
65
+
66
+ raise SyntaxError, 'not all parenthesis are closed' if stack.length != 1
67
+
68
+ raise SyntaxError, 'the expression cannot end with a logic operator' if logic
69
+
70
+ base << Name.new(name) if name
71
+
72
+ base = base.first if base.length == 1 && base.first.is_a?(Group)
73
+
74
+ new(base)
75
+ end
76
+
77
+ def self.[] (*args)
78
+ parse(*args)
79
+ end
80
+
81
+ attr_reader :base
82
+
83
+ def initialize (base = Group.new)
84
+ @base = base
85
+ end
86
+
87
+ def evaluate (*args)
88
+ _evaluate(@base, args.flatten.compact.map {|piece|
89
+ piece.to_s
90
+ })
91
+ end
92
+
93
+ alias [] evaluate
94
+
95
+ def to_s
96
+ @base.inspect
97
+ end
98
+
99
+ private
100
+ def _evaluate (group, pieces)
101
+ return false if pieces.empty?
102
+
103
+ values = []
104
+
105
+ group.each {|thing|
106
+ case thing
107
+ when Logic then values << thing
108
+ when Group then values << _evaluate(thing, pieces)
109
+ when Name then values << pieces.member?(thing.to_s)
110
+ end
111
+ }
112
+
113
+ at = 0
114
+ while at < values.length
115
+ if values[at].is_a?(Logic) && values[at].type == :not
116
+ value = values.delete_at(at + 1)
117
+
118
+ values[at] = !(value.is_a?(Group) ? value.evaluate(values[at]) : value)
119
+ end
120
+
121
+ at += 1
122
+ end
123
+
124
+ while values.length > 1
125
+ a, logic, b = values.shift(3)
126
+
127
+ values.unshift(logic.evaluate(a, b))
128
+ end
129
+
130
+ values.first
131
+ end
139
132
  end
140
133
 
141
134
  require 'boolean/expression/name'
@@ -18,7 +18,7 @@
18
18
  #++
19
19
 
20
20
  class Boolean::Expression::Group < Array
21
- def inspect
22
- '(' + self.map {|e| e.inspect}.join(' ') + ')'
23
- end
21
+ def inspect
22
+ '(' + map { |e| e.inspect }.join(' ') + ')'
23
+ end
24
24
  end
@@ -18,27 +18,26 @@
18
18
  #++
19
19
 
20
20
  class Boolean::Expression::Logic
21
- attr_reader :type
21
+ attr_reader :type
22
22
 
23
- def initialize (what)
24
- @type = case what
25
- when '!', /not/i then :not
26
- when '&&', /and/i then :and
27
- when '||', /or/i then :or
28
- end
23
+ def initialize (what)
24
+ @type = case what
25
+ when '!', /not/i then :not
26
+ when '&&', /and/i then :and
27
+ when '||', /or/i then :or
28
+ else raise SyntaxError, 'invalid logical operator, logical fallacies everywhere'
29
+ end
30
+ end
29
31
 
30
- raise SyntaxError.new('Invalid logical operator, logical fallacies everywhere') unless @type
31
- end
32
+ def evaluate (a, b=nil)
33
+ case @type
34
+ when :not then !a
35
+ when :and then !!(a && b)
36
+ when :or then !!(a || b)
37
+ end
38
+ end
32
39
 
33
- def evaluate (a, b=nil)
34
- case @type
35
- when :not then !a
36
- when :and then !!(a && b)
37
- when :or then !!(a || b)
38
- end
39
- end
40
-
41
- def inspect
42
- self.type.to_s.upcase
43
- end
40
+ def inspect
41
+ type.to_s.upcase
42
+ end
44
43
  end
@@ -18,7 +18,7 @@
18
18
  #++
19
19
 
20
20
  class Boolean::Expression::Name < String
21
- def inspect
22
- self.to_s.downcase
23
- end
21
+ def inspect
22
+ to_s.downcase
23
+ end
24
24
  end
metadata CHANGED
@@ -1,57 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: boolean-expression
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.1
4
5
  prerelease:
5
- version: 0.0.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - meh.
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-06-22 00:00:00 Z
12
+ date: 2012-01-28 00:00:00.000000000 Z
14
13
  dependencies: []
15
-
16
14
  description:
17
15
  email: meh@paranoici.org
18
16
  executables: []
19
-
20
17
  extensions: []
21
-
22
18
  extra_rdoc_files: []
23
-
24
- files:
19
+ files:
25
20
  - lib/boolean/expression.rb
26
21
  - lib/boolean/expression/logic.rb
27
22
  - lib/boolean/expression/name.rb
28
23
  - lib/boolean/expression/group.rb
29
24
  homepage: http://github.com/meh/boolean-expression
30
25
  licenses: []
31
-
32
26
  post_install_message:
33
27
  rdoc_options: []
34
-
35
- require_paths:
28
+ require_paths:
36
29
  - lib
37
- required_ruby_version: !ruby/object:Gem::Requirement
30
+ required_ruby_version: !ruby/object:Gem::Requirement
38
31
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: "0"
43
- required_rubygems_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
37
  none: false
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: "0"
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
49
42
  requirements: []
50
-
51
43
  rubyforge_project:
52
- rubygems_version: 1.8.5
44
+ rubygems_version: 1.8.10
53
45
  signing_key:
54
46
  specification_version: 3
55
47
  summary: A simple library to evaluate boolean expressions.
56
48
  test_files: []
57
-