class Algebra::AlgebraicParser

Constants

Dlm
Gr
Num
Op
Var

Public Class Methods

eval(str, klass) click to toggle source
# File lib/algebra/algebraic-parser.rb, line 11
def self.eval(str, klass) # , coeff = Numeric)
  new(str, klass).compile
end
new(str, klass) click to toggle source
# File lib/algebra/algebraic-parser.rb, line 21
def initialize(str, klass)
  @klass = klass
  @coeff = klass.ground
  @s = str.gsub(/\s+/, '').scan(/#{Dlm}|#{Num}|#{Op}|#{Gr}|#{Var}|.+/o)
  @basis = [] # stack for the basis of the power
end

Public Instance Methods

compile() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 28
def compile
  sentence
end

Private Instance Methods

expr() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 52
def expr
  e = expr1
  while /^[+-]$/ =~ head
    case succ
    when '+'
      e += expr1
    when '-'
      e -= expr1
    end
  end
  e
end
expr1() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 65
def expr1
  case head
  when '+' then succ; term
  when '-' then succ; - term
  else term
  end
end
factor() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 108
def factor
  case head
  when '(' then succ; e = sentence; succ(')'); e
  when /^#{Num}$/o
    @basis.empty? ? @coeff.indeterminate(succ) : eval(succ)
  when /^#{Var}$/o then @klass.indeterminate(succ)
  else
    raise "unknown token '#{head}'"
  end
end
head() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 34
def head
  @s[0]
end
power() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 92
def power
  @basis.push(k = factor)
  n = 0
  while /^(?:\*\*)$|^\^$/ =~ head
    succ
    @basis.push(factor)
    n += 1
  end
  f = @basis.pop
  while n > 0
    f = @basis.pop**f
    n -= 1
  end
  f
end
sentence() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 43
def sentence
  e = expr
  while /^#{Dlm}$/ =~ head
    succ(';')
    e = expr
  end
  e
end
sequence() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 86
def sequence
  e = power
  e *= power while head && head !~ /^#{Dlm}$|^#{Op}$|^#{Gr}$/o
  e
end
succ(x = nil) click to toggle source
# File lib/algebra/algebraic-parser.rb, line 38
def succ(x = nil)
  raise "Error: receive #{x} expect #{head}" if x && x != head
  @s.shift
end
term() click to toggle source
# File lib/algebra/algebraic-parser.rb, line 73
def term
  e = sequence
  while /^[*\/]$/ =~ head # /
    case succ
    when '*'
      e *= sequence
    when '/'
      e /= sequence
    end
  end
  e
end