Class: LXL::Parser
- Inherits:
-
Object
- Object
- LXL::Parser
- Defined in:
- lib/lxl.rb
Overview
Lexical Types
; Statement separator
, Argument separator
( Tuple open
) Tuple close
w Whitespace
o Operator
s String
r Range
p Percentage
f Float
i Integer
t Token
F Function
C Constant
Constant Summary collapse
- RUBY_OPERATORS =
['+', '-', '*', '/', '<=', '>=', '==', '!=', '<', '>', '+', '**']
- EXCEL_OPERATORS =
['+', '-', '*', '/', '<=', '>=', '=', '<>', '<', '>', '&', '^' ]
Class Method Summary collapse
-
.eval(formula) ⇒ Object
Evaluate a formula.
-
.lexer_class ⇒ Object
Default lexer class.
-
.namespace_class ⇒ Object
Default namespace class.
-
.range_class ⇒ Object
Default range class.
Instance Method Summary collapse
-
#eval(formula) ⇒ Object
Evaluate a formula.
-
#initialize(namespace = self.class.namespace_class.new) ⇒ Parser
constructor
Initialize namespace and parser.
Constructor Details
#initialize(namespace = self.class.namespace_class.new) ⇒ Parser
Initialize namespace and parser.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/lxl.rb', line 214 def initialize(namespace=self.class.namespace_class.new) @namespace = namespace ops = EXCEL_OPERATORS.collect { |v| Regexp.quote(v) }.join('|') xlr = LXL::Range::EXCEL_RANGE @lexer = self.class.lexer_class.new([ [/\A;+/, ?;], # Statement separator [/\A,+/, ?,], # Argument separator [/\A\(/, ?(], # Tuple open [/\A\)/, ?)], # Tuple close [/\A\s+/, ?w], # Whitespace [/\A(#{ops})/, ?o], # Operator [/\A("([^"]|"")*")/m, ?s], # String [xlr, ?r], # Range [/\A\d+(\.\d+)?%/, ?p], # Percentage [/\A\d+\.\d+/, ?f], # Float [/\A\d+/, ?i], # Integer [/\A\w+/, ?t], # Token ], false) end |
Class Method Details
.eval(formula) ⇒ Object
Evaluate a formula.
190 191 192 |
# File 'lib/lxl.rb', line 190 def self.eval(formula) self.new.eval(formula) end |
.lexer_class ⇒ Object
Default lexer class.
196 197 198 |
# File 'lib/lxl.rb', line 196 def self.lexer_class LXL::Lexer end |
.namespace_class ⇒ Object
Default namespace class.
202 203 204 |
# File 'lib/lxl.rb', line 202 def self.namespace_class LXL::Namespace end |
.range_class ⇒ Object
Default range class.
208 209 210 |
# File 'lib/lxl.rb', line 208 def self.range_class LXL::Range end |
Instance Method Details
#eval(formula) ⇒ Object
Evaluate a formula.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/lxl.rb', line 236 def eval(formula) formulas = Array.new << Array.new formula = formula.to_s.gsub(/(\n)(\s*=)/,'\1;\2') # infer statement separators types,tokens = tokenize(formula) tokens.each_index { |i| tokens[i] == ';' ? formulas << Array.new : formulas.last << [types[i], tokens[i]] } formulas.collect! { |f| types = f.collect { |t| t.first } tokens = f.collect { |t| t.last } token = tokens.join.strip if token =~ /\A=/ tokens.each_index { |i| tokens[i] = translate_quotes(tokens[i]) if types[i] == ?s } token = tokens.join.strip.gsub(/\A=+/,'') else token = translate_quotes(quote(tokens.join.strip)) end } formulas.delete_if { |f| f == '""' } formulas.collect! { |f| Kernel.eval(f, binding) } formulas.size == 1 ? formulas.first : formulas end |