001    /* Generated By:JavaCC: Do not edit this line. ParseException.java Version 0.7pre6 */
002    
003    /*
004     * Cobertura - http://cobertura.sourceforge.net/
005     *
006     * This file was taken from JavaNCSS
007     * http://www.kclee.com/clemens/java/javancss/
008     * Copyright (C) 2000 Chr. Clemens Lee <clemens a.t kclee d.o.t com>
009     *
010     * Cobertura is free software; you can redistribute it and/or modify
011     * it under the terms of the GNU General Public License as published
012     * by the Free Software Foundation; either version 2 of the License,
013     * or (at your option) any later version.
014     *
015     * Cobertura is distributed in the hope that it will be useful, but
016     * WITHOUT ANY WARRANTY; without even the implied warranty of
017     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018     * General Public License for more details.
019     *
020     * You should have received a copy of the GNU General Public License
021     * along with Cobertura; if not, write to the Free Software
022     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
023     * USA
024     */
025    package net.sourceforge.cobertura.javancss;
026    
027    /**
028     * This exception is thrown when parse errors are encountered.
029     * You can explicitly create objects of this exception type by
030     * calling the method generateParseException in the generated
031     * parser.
032     *
033     * You can modify this class to customize your error reporting
034     * mechanisms so long as you retain the public fields.
035     */
036    public class ParseException extends Exception {
037    
038      /**
039       * This constructor is used by the method "generateParseException"
040       * in the generated parser.  Calling this constructor generates
041       * a new object of this type with the fields "currentToken",
042       * "expectedTokenSequences", and "tokenImage" set.  The boolean
043       * flag "specialConstructor" is also set to true to indicate that
044       * this constructor was used to create this object.
045       * This constructor calls its super class with the empty string
046       * to force the "toString" method of parent class "Throwable" to
047       * print the error message in the form:
048       *     ParseException: <result of getMessage>
049       */
050      public ParseException(Token currentTokenVal,
051                            int[][] expectedTokenSequencesVal,
052                            String[] tokenImageVal
053                           )
054      {
055        super("");
056        specialConstructor = true;
057        currentToken = currentTokenVal;
058        expectedTokenSequences = expectedTokenSequencesVal;
059        tokenImage = tokenImageVal;
060      }
061    
062      /**
063       * The following constructors are for use by you for whatever
064       * purpose you can think of.  Constructing the exception in this
065       * manner makes the exception behave in the normal way - i.e., as
066       * documented in the class "Throwable".  The fields "errorToken",
067       * "expectedTokenSequences", and "tokenImage" do not contain
068       * relevant information.  The JavaCC generated code does not use
069       * these constructors.
070       */
071    
072      public ParseException() {
073        super();
074        specialConstructor = false;
075      }
076    
077      public ParseException(String message) {
078        super(message);
079        specialConstructor = false;
080      }
081    
082      /**
083       * This variable determines which constructor was used to create
084       * this object and thereby affects the semantics of the
085       * "getMessage" method (see below).
086       */
087      protected boolean specialConstructor;
088    
089      /**
090       * This is the last token that has been consumed successfully.  If
091       * this object has been created due to a parse error, the token
092       * followng this token will (therefore) be the first error token.
093       */
094      public Token currentToken;
095    
096      /**
097       * Each entry in this array is an array of integers.  Each array
098       * of integers represents a sequence of tokens (by their ordinal
099       * values) that is expected at this point of the parse.
100       */
101      public int[][] expectedTokenSequences;
102    
103      /**
104       * This is a reference to the "tokenImage" array of the generated
105       * parser within which the parse error occurred.  This array is
106       * defined in the generated ...Constants interface.
107       */
108      public String[] tokenImage;
109    
110      /**
111       * This method has the standard behavior when this object has been
112       * created using the standard constructors.  Otherwise, it uses
113       * "currentToken" and "expectedTokenSequences" to generate a parse
114       * error message and returns it.  If this object has been created
115       * due to a parse error, and you do not catch it (it gets thrown
116       * from the parser), then this method is called during the printing
117       * of the final stack trace, and hence the correct error message
118       * gets displayed.
119       */
120      public String getMessage() {
121        if (!specialConstructor) {
122          return super.getMessage();
123        }
124        String expected = "";
125        int maxSize = 0;
126        for (int i = 0; i < expectedTokenSequences.length; i++) {
127          if (maxSize < expectedTokenSequences[i].length) {
128            maxSize = expectedTokenSequences[i].length;
129          }
130          for (int j = 0; j < expectedTokenSequences[i].length; j++) {
131            expected += tokenImage[expectedTokenSequences[i][j]] + " ";
132          }
133          if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
134            expected += "...";
135          }
136          expected += eol + "    ";
137        }
138        String retval = "Encountered \"";
139        Token tok = currentToken.next;
140        for (int i = 0; i < maxSize; i++) {
141          if (i != 0) retval += " ";
142          if (tok.kind == 0) {
143            retval += tokenImage[0];
144            break;
145          }
146          retval += add_escapes(tok.image);
147          tok = tok.next; 
148        }
149        retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn + "." + eol;
150        if (expectedTokenSequences.length == 1) {
151          retval += "Was expecting:" + eol + "    ";
152        } else {
153          retval += "Was expecting one of:" + eol + "    ";
154        }
155        retval += expected;
156        return retval;
157      }
158    
159      /**
160       * The end of line string for this machine.
161       */
162      protected String eol = System.getProperty("line.separator", "\n");
163     
164      /**
165       * Used to convert raw characters to their escaped version
166       * when these raw version cannot be used as part of an ASCII
167       * string literal.
168       */
169      protected String add_escapes(String str) {
170          StringBuffer retval = new StringBuffer();
171          char ch;
172          for (int i = 0; i < str.length(); i++) {
173            switch (str.charAt(i))
174            {
175               case 0 :
176                  continue;
177               case '\b':
178                  retval.append("\\b");
179                  continue;
180               case '\t':
181                  retval.append("\\t");
182                  continue;
183               case '\n':
184                  retval.append("\\n");
185                  continue;
186               case '\f':
187                  retval.append("\\f");
188                  continue;
189               case '\r':
190                  retval.append("\\r");
191                  continue;
192               case '\"':
193                  retval.append("\\\"");
194                  continue;
195               case '\'':
196                  retval.append("\\\'");
197                  continue;
198               case '\\':
199                  retval.append("\\\\");
200                  continue;
201               default:
202                  if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
203                     String s = "0000" + Integer.toString(ch, 16);
204                     retval.append("\\u" + s.substring(s.length() - 4, s.length()));
205                  } else {
206                     retval.append(ch);
207                  }
208                  continue;
209            }
210          }
211          return retval.toString();
212       }
213    
214    }