boolean-expression 0.0.1 → 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-