title: Recursion and Iteration method to locate missing brackets
body: <p>For this assignment, the specification is simple. You are given a text file of arbitrary length
  (Possibly thousands of characters). To be considered correct, it must contain matching pairs of
  brackets <code>{ }</code>, <code>[ ]</code>, and <code>( )</code>. Bracket pairs may be nested to arbitrary depth (but not so deeply that
  you need to worry about stack overflow) with arbitrary amounts of text between brackets. A file
  that contains no brackets is trivially correct. When you discover a pair of mismatched brackets,
  you must report the brackets and their index in the file. The first character in the file is index 0.
  For example, if the file contains
  This file has an open <code>{ and another { followed by ) and }</code> and some text.
  your program should report a mismatch because the <code>{  at index 36 is closed by the  )</code> at index 50.
  You can think of the start of the file as a super <code>opening bracket</code> that does not match any
  closing bracket. If the file contains too many closing brackets, the mismatched <code>opening bracket</code> is the start of the file. You should use the string <code>STX</code> (old ascii <code>start of text</code>) to report this. For example, this closing ] has no matching open [.
  In this case, your program should report a mismatch because
  STX at index -1 is closed by the <code>]</code> at index 13. Similarly, you can think of the end of the file as a super <code>closing bracket</code> that does not match any opening bracket. A file may contain too many open brackets. Report this as if the mismatched <code>closing bracket</code> is really a (nonexistent) close bracket after the end of the file. For example this open ( has no match Reoprt this as a mismatch because the <code>(</code>  at index 10 is closed by EOF at index 24. Your task is to write two methods, a recursive method, recursiveMatch , and an iterative method, iterativeMatch , to process a file and check if the brackets match. When either method
  detects a bracket mismatch, it should throw an exception of class
  Matchfail. The information in a Matchfail object should include the mismatched brackets and their indices in the file.</p>
  
  <p>here is the code i have so far:</p>
  
  <pre><code>import java.io.File ;
  import java.io.FileReader ;
  import java.io.IOException ;
  
  /**
  * Development driver for Assignment #4, matching brackets.
   * 
   * @author lou
   * @param args[0]
   *            name of a file to check
   */
  public class Assign4 {
  
   public static void main(String[] args) {
  /*
   * Check that the user has supplied a file name, and that the file
   * exists and is readable.
   */
  if (args.length &lt;= 0) {
    System.out.println("Usage: java Assign4 &lt;filename&gt;") ;
    System.exit(1) ;
  }
  String fileName = args[0] ;
  File handle = new File(fileName) ;
  if (!(handle.exists() &amp;&amp; handle.canRead())) {
    System.out.println("Please check that file \"" + fileName
        + "\" exists and is readable.") ;
    System.exit(2) ;
  }
  /*
   * Create an input stream of type FileReader to read the file character
   * by character. This can throw a (checked) IOException so we need to
   * wrap it in a try/catch block.
   *
   * It's good practice to always close a FileReader to avoid
   * a resource leak (resources that are allocated but not released). If
   * src is not null, resources may have been allocated even if creation of
   * the FileReader fails and we should attempt a close to free them.
   * Closing a file reader can itself throw an IOException, so we need a
   * nested try/catch block.
   */
  FileReader src = null ;
  try {
    src = new FileReader(handle) ;
  } catch (IOException ex) {
    System.out.println("Exception while opening file \"" +
        fileName + "\" for read.") ;
    System.out.println("Exception: " + ex) ;
    try {
  if (src != null) src.close() ;
    } catch (IOException closeEx) {
  System.out.println(
      "Exception while closing file \"" + fileName + "\".") ;
  System.out.println("Exception: " + closeEx) ;
    }
    System.exit(3) ;
  }
  /*
   * Try the recursive match method first. A MatchFail exception is
   * certainly a possibility. Allow that other exceptions might be thrown
   * but don't attempt to do anything.
   */
  MatchBrackets matcher = new MatchBrackets() ;
  try {
    matcher.recursiveMatch(src) ;
    System.out.println("Brackets match (recursive)!") ;
  } catch (MatchFail ex) {
    System.out.println("A bracket on its own is up to no good!") ;
    System.out.println(ex) ;
  } catch (Exception ex) {
    System.out.println("Unexpected exception "+ex) ;
  }
  /*
   * We need to return to the beginning of the file to test the iterative
   * match. For a FileReader, this requires closing and reopening the file.
   */
  try {
    System.out.println("Attempting close and reopen.") ;
    src.close() ;
    src = new FileReader(handle) ;
  } catch (IOException ex) {
    System.out.println("Exception while reopening file \"" + fileName
    + "\" for read.") ;
    System.out.println("Exception: " + ex) ;
    try {
  if (src != null) src.close() ;
    } catch (IOException closeEx) {
  System.out.println(
      "Exception while closing file \"" + fileName + "\".") ;
  System.out.println("Exception: " + closeEx) ;
    }
    System.exit(3) ;
  }
  /*
   * Try the iterative match method.
   */
  try {
    matcher.iterativeMatch(src) ;
    System.out.println("Brackets match (iterative)!") ;
  } catch (MatchFail ex) {
    System.out.println("A bracket on its own is up to no good!") ;
    System.out.println(ex) ;
  } catch (Exception ex) {
    System.out.println("Unexpected exception "+ex) ;
  }
  /*
   * Close the file and we're done.
   */
  try {
    src.close() ;
  } catch (IOException ex) {
    System.out.println(
        "Exception while closing file \"" + fileName + "\".") ;
    System.out.println("Exception: " + ex) ;
    System.exit(3) ;
  }
  return ;
  }
  }
  </code></pre>
  
  <p>and </p>
  
  <pre><code>import java.io.FileReader ;
  import java.io.IOException ;
  import java.util.ArrayDeque ;
  
  /**
    Skeleton for the MatchBrackets class.
  */
  public class MatchBrackets {
  
    /**
     * Make a constant so it's clear we're recognising end-of-file.
     */
    private final int EOF = -1 ;
  
    /**
     * A helper method to encapsulate the activity of reading a
     * character.
     * 
     * The FileReader class uses a common convention in character i/o:
     * return each character as an int; this allows the value -1 to be
     * used to indicate EOF. This little helper routine simply hides the
     * try/catch statement that's required to handle the possibility
     * that FileReader.read might throw an IOException.
     * 
     * @param source
     *        source of characters
     * @return EOF on end-of-file or exception, or a single character
     *         (as an int)
     */
    private int getOneChar (FileReader source)
    {
      int charAsInt = EOF ;
     try {
    charAsInt = source.read() ;
      } catch (IOException ex) {
     System.out.println("Exception: " + ex) ;
    charAsInt = EOF ;
     }
     return (charAsInt) ;
    }
  
  /**
   * Recursive method to match brackets.
   * 
   * @param src
   *        source of characters
   */
  public void recursiveMatch (FileReader src)
         throws MatchFail 
  {
  /*
    You must write a proper body for recursiveMatch. The bit of code below
    is just to show you how to use getOneChar and throw an exception.
  */
  int charAsInt = getOneChar(src) ;
  if (charAsInt != EOF) {
    char firstChar = (char) charAsInt ;
    System.out.println(
        "The first character of the file is '" + firstChar + "'.") ;
  } else {
    System.out.println("This file is empty!") ;
  }
  throw new MatchFail("You must write recursiveMatch!",42,
              Character.toString('}'),42) ;
  }
  
  /**
   * Iterative method to match brackets.
   * 
   * @param src
   *        source of characters
   */
  public void iterativeMatch (FileReader src) throws MatchFail
  {
    /*
      You must write a proper body for this method, too.
    */
    throw new MatchFail() ;
  }
  
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>/**
   Exception class for use by the bracket matching methods.
   &lt;p&gt;
   When a bracket mismatch is detected, this exception object should be
   created, loaded with information about the mismatched pair of brackets, and
   thrown.
   &lt;/p&gt;&lt;p&gt;
   The information provided should include the opening bracket and its index in
   the file, and the closing bracket and its index in the file.
   For a file containing K characters, character indices range from 0 to K-1.
   By definition,
   &lt;ul&gt;
   &lt;li&gt; the `character' before the start of the file has index -1 and is
   represented by the string "STX" (start of text).&lt;/li&gt;
   &lt;li&gt; the `character' after the end of the file has index K and is
       represented by the string "EOF" (end of file).&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/p&gt;&lt;p&gt;
   MatchFail is subclassed from Exception, hence it is a checkable exception
   and methods that might throw MatchFail must declare the exception with a
   throws clause.
    */
  
   public class MatchFail extends Exception
   {
  
  /**
  Index of opening bracket of the mismatched pair.
  */
  private int openNdx ;
  
  /**
  String representation of the opening bracket of the mismatched
  pair.
  */
  private String openBkt ;
  
  /**
  Index of closing bracket of the mismatched pair.
  */
  private int closeNdx ;
  
  /**
  String representation of the opening bracket of the mismatched
  pair.
  */
  private String closeBkt ;
  
  /**
  Convenience constructor to set all attributes.
  */
  public MatchFail (String openBkt, int openNdx,
          String closeBkt, int closeNdx)
  { this.openBkt = openBkt ;
  this.openNdx = openNdx ;
  this.closeBkt = closeBkt ;
  this.closeNdx = closeNdx ;
  }
  
  /**
  Constructor.
  &lt;p&gt;
  Initialise the attributes to values that are obviously invalid so it's
  easy to detect algorithm errors.
  &lt;/p&gt;
  */
  public MatchFail ()
  {
    this("invalid",-10,"invalid",-10) ;
  }
  
  /** Retrieve the opening bracket. */
  public String getOpenBkt () { return (openBkt) ; }
  
  /** Retrieve the index of the opening bracket. */
  public int getOpenIndex () { return (openNdx) ; }
  
  /** Retrieve the closing bracket. */
  public String getCloseBkt () { return (closeBkt) ; }
  
  /** Retrieve the index of the opening bracket. */
  public int getCloseIndex () { return (closeNdx) ; }
  
  /** Set the opening bracket. */
  public void setOpenBkt (String openBkt) { this.openBkt = openBkt ; }
  
  /** Set the index of the opening bracket. */
  public void setOpenIndex (int openNdx) { this.openNdx = openNdx ; }
  
  /** Set the closing bracket. */
  public void setCloseBkt (String closeBkt) { this.closeBkt = closeBkt ; }
  
  /** Set the index of the closing bracket. */
  public void setCloseIndex (int closeNdx) { this.closeNdx = closeNdx ; }
  
  /** Return a string representation of the exception. */
  public String toString ()
  {
    String rep = "'"+openBkt+"' at index "+openNdx+" matched to '" +
           closeBkt+"' at index "+closeNdx ;
     return (rep) ;
  }
  
  }
  </code></pre>
  
  <p>The problem i am having is in creating the recursive and iterator method in order to find the brackets and report the index where the missing bracket is located. I don't really understand how i am supposed to do this. Any help at all would be appreciated!
  Thank You.</p>