# Autogenerated from a Treetop grammar. Edits may be lost.


module Arithmetic
  include Treetop::Runtime

  def root
    @root || :expr
  end

  module Expr0
    def op
      elements[0]
    end

    def right
      elements[1]
    end
  end

  module Expr1
    def left
      elements[0]
    end

    def right_opt
      elements[1]
    end
  end

  module Expr2
    def value
      right_opt.elements.inject(left.value) {|acc, plus_and_right|
        acc.send \
		    plus_and_right.op.text_value,
          plus_and_right.right.value
      }
    end
  end

  def _nt_expr
    start_index = index
    if node_cache[:expr].has_key?(index)
      cached = node_cache[:expr][index]
      if cached
        cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
        @index = cached.interval.end
      end
      return cached
    end

    i0, s0 = index, []
    r1 = _nt_term
    s0 << r1
    if r1
      s2, i2 = [], index
      loop do
        i3, s3 = index, []
        if has_terminal?('\G[\\+\\-]', true, index)
          r4 = true
          @index += 1
        else
          r4 = nil
        end
        s3 << r4
        if r4
          r5 = _nt_term
          s3 << r5
        end
        if s3.last
          r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
          r3.extend(Expr0)
        else
          @index = i3
          r3 = nil
        end
        if r3
          s2 << r3
        else
          break
        end
      end
      r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
      s0 << r2
    end
    if s0.last
      r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
      r0.extend(Expr1)
      r0.extend(Expr2)
    else
      @index = i0
      r0 = nil
    end

    node_cache[:expr][start_index] = r0

    r0
  end

  module Term0
    def op
      elements[0]
    end

    def right
      elements[1]
    end
  end

  module Term1
    def left
      elements[0]
    end

    def right_opt
      elements[1]
    end
  end

  module Term2
    def value
      right_opt.elements.inject(left.value) {|acc, mul_and_right|
        acc.send \
		    mul_and_right.op.text_value,
          mul_and_right.right.value
      }
    end
  end

  def _nt_term
    start_index = index
    if node_cache[:term].has_key?(index)
      cached = node_cache[:term][index]
      if cached
        cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
        @index = cached.interval.end
      end
      return cached
    end

    i0, s0 = index, []
    r1 = _nt_factor
    s0 << r1
    if r1
      s2, i2 = [], index
      loop do
        i3, s3 = index, []
        if has_terminal?('\G[\\*\\/]', true, index)
          r4 = true
          @index += 1
        else
          r4 = nil
        end
        s3 << r4
        if r4
          r5 = _nt_factor
          s3 << r5
        end
        if s3.last
          r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
          r3.extend(Term0)
        else
          @index = i3
          r3 = nil
        end
        if r3
          s2 << r3
        else
          break
        end
      end
      r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
      s0 << r2
    end
    if s0.last
      r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
      r0.extend(Term1)
      r0.extend(Term2)
    else
      @index = i0
      r0 = nil
    end

    node_cache[:term][start_index] = r0

    r0
  end

  module Factor0
    def expr
      elements[1]
    end

  end

  module Factor1
    def value
      expr.value
    end
  end

  def _nt_factor
    start_index = index
    if node_cache[:factor].has_key?(index)
      cached = node_cache[:factor][index]
      if cached
        cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
        @index = cached.interval.end
      end
      return cached
    end

    i0 = index
    i1, s1 = index, []
    if has_terminal?('(', false, index)
      r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
      @index += 1
    else
      terminal_parse_failure('(')
      r2 = nil
    end
    s1 << r2
    if r2
      r3 = _nt_expr
      s1 << r3
      if r3
        if has_terminal?(')', false, index)
          r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
          @index += 1
        else
          terminal_parse_failure(')')
          r4 = nil
        end
        s1 << r4
      end
    end
    if s1.last
      r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
      r1.extend(Factor0)
      r1.extend(Factor1)
    else
      @index = i1
      r1 = nil
    end
    if r1
      r0 = r1
    else
      r5 = _nt_number
      if r5
        r0 = r5
      else
        @index = i0
        r0 = nil
      end
    end

    node_cache[:factor][start_index] = r0

    r0
  end

  module Number0
  end

  module Number1
    def value
      text_value.to_f
    end
  end

  def _nt_number
    start_index = index
    if node_cache[:number].has_key?(index)
      cached = node_cache[:number][index]
      if cached
        cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
        @index = cached.interval.end
      end
      return cached
    end

    i0, s0 = index, []
    if has_terminal?('\G[1-9]', true, index)
      r1 = true
      @index += 1
    else
      r1 = nil
    end
    s0 << r1
    if r1
      s2, i2 = [], index
      loop do
        if has_terminal?('\G[0-9]', true, index)
          r3 = true
          @index += 1
        else
          r3 = nil
        end
        if r3
          s2 << r3
        else
          break
        end
      end
      r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
      s0 << r2
    end
    if s0.last
      r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
      r0.extend(Number0)
      r0.extend(Number1)
    else
      @index = i0
      r0 = nil
    end

    node_cache[:number][start_index] = r0

    r0
  end

end

class ArithmeticParser < Treetop::Runtime::CompiledParser
  include Arithmetic
end


