lxl 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/CHANGES +7 -0
  2. data/VERSION +1 -1
  3. data/lib/lxl.rb +41 -44
  4. metadata +1 -1
data/CHANGES CHANGED
@@ -1,3 +1,10 @@
1
+ 0.2.2
2
+
3
+ - Seperated tokenize's text=>formula into tokenize_text
4
+ - LittleLexer returns types as [Symbol*] vs String (tokenize updated accordingly)
5
+ - F and C types removed (no need)
6
+ - General refactoring (code/doc cleanup)
7
+
1
8
  0.2.0
2
9
 
3
10
  - Double quotes only used to define strings.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.2
data/lib/lxl.rb CHANGED
@@ -54,8 +54,6 @@
54
54
  # t Token
55
55
  # ( Open (
56
56
  # ) Close )
57
- # C Constant
58
- # F Function
59
57
  #
60
58
  module LXL
61
59
 
@@ -111,29 +109,25 @@ class LXL::Parser
111
109
  ops = EXCEL_OPERATORS.collect { |v| Regexp.quote(v) }.join('|')
112
110
  #
113
111
  @lexer = LXL::LittleLexer.new([
114
- [/\A[\s,]+/,?w], # Whitespace (includes Commas)
115
- [/\A(#{ops})/,?o], # Operator
116
- [/\A[0-9]+\.[0-9]+/,?f], # Float
117
- [/\A[0-9]+/,?i], # Integer
118
- [/\A("([^"]|"")*")/m,?s], # String
119
- [/\A\w+/,?t], # Token
120
- [/\A\(/,?(], # Open (
121
- [/\A\)/,?)], # Close )
112
+ [/\A[\s,]+/, ?w], # Whitespace (includes Commas)
113
+ [/\A(#{ops})/, ?o], # Operator
114
+ [/\A("([^"]|"")*")/m, ?s], # String
115
+ [/\A[0-9]+\.[0-9]+/, ?f], # Float
116
+ [/\A[0-9]+/, ?i], # Integer
117
+ [/\A\w+/, ?t], # Token
118
+ [/\A\(/, ?(], # Open (
119
+ [/\A\)/, ?)], # Close )
122
120
  ], false)
123
-
124
- # Other
125
- @tokens = Array.new
126
- @types = Array.new
127
121
  end
128
122
 
129
123
  # Evaluate formula
130
124
  #
131
125
  def eval(formula)
132
126
  formulas = formula.to_s.split(';').collect { |f| f.strip }.find_all { |f| ! f.empty? }
133
- formulas.collect! { |f| Kernel.eval(tokenize(f).join, binding) }
127
+ formulas.collect! { |f| Kernel.eval(tokenize_text(f).join, binding) }
134
128
  formulas.size == 1 ? formulas.first : formulas
135
129
  end
136
-
130
+
137
131
  # Register a function
138
132
  #
139
133
  # * Converts name to symbol
@@ -181,44 +175,45 @@ class LXL::Parser
181
175
  }
182
176
  end
183
177
 
178
+ # Translates text to a formula before tokenizing
179
+ #
180
+ def tokenize_text(text)
181
+ formula = (text =~ /^=/) ? text : '="'+text.gsub('"','""')+'"'
182
+ tokenize(formula)
183
+ end
184
+
184
185
  # Tokenize formula (String => Array)
185
186
  #
186
187
  def tokenize(formula)
187
188
  ops = Hash[*EXCEL_OPERATORS.zip(RUBY_OPERATORS).flatten]
188
189
 
189
190
  # Parse formula
190
- formula = '="'+formula.gsub('"','""')+'"' unless formula =~ /^=/ # text to formula (text to ="quoted-text")
191
191
  types, tokens = @lexer.scan(formula.gsub(/^=/,''))
192
- types = types.split(//)
193
192
  raise SyntaxError, 'unbalanced parentheses' unless balanced?(tokens)
194
193
 
195
194
  # Parse tokens
196
195
  tokens.each_index do |i|
197
196
  type, token = types[i], tokens[i]
198
- token = case type
199
- when 'i': token.to_i
200
- when 'f': token.to_f
201
- when 's': token.gsub(/([^\\])""/,'\1\"') # "" to \"
202
- else token
203
- end
204
- if type == 't'
205
- token = name(token)
206
- if @functions.key?(token)
207
- if tokens[i+1] != '('
208
- raise ArgumentError, "wrong number of arguments for #{token}"
197
+ tokens[i] = case type
198
+ when :i then token.to_i
199
+ when :f then token.to_f
200
+ when :s then token.gsub(/([^\\])""/,'\1\"') # "" to \"
201
+ when :t then
202
+ name = name(token)
203
+ if @functions.key?(name)
204
+ if tokens[i+1] != '('
205
+ raise ArgumentError, "wrong number of arguments for #{token}"
206
+ else
207
+ "@functions[:#{name}].call"
208
+ end
209
+ elsif @constants.key?(name)
210
+ "@constants[:#{name}]"
209
211
  else
210
- types[i] = 'F'
211
- token = '@functions['+token.inspect+'].call'
212
+ raise NameError, "unknown constant #{token}"
212
213
  end
213
- elsif @constants.key?(token)
214
- types[i] = 'C'
215
- token = '@constants['+token.inspect+']'
216
214
  else
217
- raise NameError, "unknown constant #{token}"
218
- end
215
+ EXCEL_OPERATORS.include?(token) ? ops[token] : token
219
216
  end
220
- token = ops[token] if EXCEL_OPERATORS.include?(token)
221
- tokens[i] = token
222
217
  end
223
218
 
224
219
  tokens
@@ -242,33 +237,34 @@ end
242
237
  #
243
238
  # http://www.rubyforge.org/projects/littlelexer
244
239
  #
240
+ # CHANGE: types are returned as [Symbol*] vs String
241
+ #
245
242
  class LXL::LittleLexer #:nodoc: all
246
243
 
247
244
  class LexerJammed < Exception; end
248
245
 
249
- def initialize(regex_to_char,skip_white_space = true)
246
+ def initialize(regex_to_char,skip_white_space=true)
250
247
  @skip_white_space = skip_white_space
251
248
  @regex_to_char = regex_to_char
252
249
  end
253
250
 
254
251
  def scan(string,string_token_list=nil)
255
- result_string = ''
252
+ result_list = []
256
253
  token_list = []
257
-
258
254
  if string_token_list
259
255
  next_token(string) do |t,token, tail|
260
- result_string << t
256
+ result_list << t.chr.to_sym
261
257
  token_list << [string_token_list[0...tail], string[0...tail]]
262
258
  string = string[tail..-1]
263
259
  string_token_list = string_token_list[tail..-1]
264
260
  end
265
261
  else
266
262
  next_token(string) do |t,token, tail|
267
- result_string << t
263
+ result_list << t.chr.to_sym
268
264
  token_list << token
269
265
  end
270
266
  end
271
- return result_string, token_list
267
+ return result_list, token_list
272
268
  end
273
269
 
274
270
  private
@@ -317,4 +313,5 @@ if $0 == __FILE__
317
313
 
318
314
  # multiple formulas separated by semi-colon
319
315
  puts LXL.eval(formulas).inspect # => ["This is some text", "This is some \"quoted\" text", 6, true, true, [1, "two", 3.0], true, false, true, "yes"]
316
+
320
317
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.3
3
3
  specification_version: 1
4
4
  name: lxl
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.0
6
+ version: 0.2.2
7
7
  date: 2005-02-08
8
8
  summary: LXL (Like Excel) is a mini-language that mimics Microsoft Excel formulas. Easily extended with new constants and functions.
9
9
  require_paths: