def generate_tree(operands, operators, parent_node)
    return operands[0] if operands.length==1

    i = index_of_lowest_precedence(operators)
    operator = operators[i]
    new_operand = node_class.new(parent_node)
    new_operand.add_match generate_tree(operands[0..i], operators[0..i-1],new_operand), :left
    new_operand.add_match operators[i], :operator_node
    new_operand.add_match generate_tree(operands[i+1..-1], operators[i+1..-1],new_operand), :right
    new_operand
  end
def generate_tree(operands, operators, parent_node)
    return operands[0] if operands.length==1

    i = index_of_lowest_precedence(operators)
    operator = operators[i]
    new_operand = node_class.new(parent_node)
    new_operand.add_match generate_tree(operands[0..i], operators[0..i-1],new_operand), :left
    new_operand.add_match operators[i], :operator_node
    new_operand.add_match generate_tree(operands[i+1..-1], operators[i+1..-1],new_operand), :right
    new_operand
  end
generates a tree of nodes of the specified node_class
 The nodes have access to the following useful methods:
    self.left -> return the left operand parse-tree-node
    self.right -> return the right operand parse-tree-node
    self.operator_node -> return the operator parse-tree-node
    self.operator -> return the operator as a ruby symbol