001    /* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
002    /* JavaCCOptions:KEEP_LINE_COL=null */
003    /*
004     *   Copyright (c) 2009 The JOMC Project
005     *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
006     *   All rights reserved.
007     *
008     *   Redistribution and use in source and binary forms, with or without
009     *   modification, are permitted provided that the following conditions
010     *   are met:
011     *
012     *     o Redistributions of source code must retain the above copyright
013     *       notice, this list of conditions and the following disclaimer.
014     *
015     *     o Redistributions in binary form must reproduce the above copyright
016     *       notice, this list of conditions and the following disclaimer in
017     *       the documentation and/or other materials provided with the
018     *       distribution.
019     *
020     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     *
032     *   $Id: VersionParser.jj 733 2009-10-05 17:22:57Z schulte2005 $
033     *
034     */
035    package org.jomc.util;
036    
037    /**
038     * This exception is thrown when parse errors are encountered.
039     * You can explicitly create objects of this exception type by
040     * calling the method generateParseException in the generated
041     * parser.
042     *
043     * You can modify this class to customize your error reporting
044     * mechanisms so long as you retain the public fields.
045     */
046    public class ParseException extends Exception {
047    
048      /**
049       * The version identifier for this Serializable class.
050       * Increment only if the <i>serialized</i> form of the
051       * class changes.
052       */
053      private static final long serialVersionUID = 1L;
054    
055      /**
056       * This constructor is used by the method "generateParseException"
057       * in the generated parser.  Calling this constructor generates
058       * a new object of this type with the fields "currentToken",
059       * "expectedTokenSequences", and "tokenImage" set.
060       */
061      public ParseException(Token currentTokenVal,
062                            int[][] expectedTokenSequencesVal,
063                            String[] tokenImageVal
064                           )
065      {
066        super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
067        currentToken = currentTokenVal;
068        expectedTokenSequences = expectedTokenSequencesVal;
069        tokenImage = tokenImageVal;
070      }
071    
072      /**
073       * The following constructors are for use by you for whatever
074       * purpose you can think of.  Constructing the exception in this
075       * manner makes the exception behave in the normal way - i.e., as
076       * documented in the class "Throwable".  The fields "errorToken",
077       * "expectedTokenSequences", and "tokenImage" do not contain
078       * relevant information.  The JavaCC generated code does not use
079       * these constructors.
080       */
081    
082      public ParseException() {
083        super();
084      }
085    
086      /** Constructor with message. */
087      public ParseException(String message) {
088        super(message);
089      }
090    
091    
092      /**
093       * This is the last token that has been consumed successfully.  If
094       * this object has been created due to a parse error, the token
095       * followng this token will (therefore) be the first error token.
096       */
097      public Token currentToken;
098    
099      /**
100       * Each entry in this array is an array of integers.  Each array
101       * of integers represents a sequence of tokens (by their ordinal
102       * values) that is expected at this point of the parse.
103       */
104      public int[][] expectedTokenSequences;
105    
106      /**
107       * This is a reference to the "tokenImage" array of the generated
108       * parser within which the parse error occurred.  This array is
109       * defined in the generated ...Constants interface.
110       */
111      public String[] tokenImage;
112    
113      /**
114       * It uses "currentToken" and "expectedTokenSequences" to generate a parse
115       * error message and returns it.  If this object has been created
116       * due to a parse error, and you do not catch it (it gets thrown
117       * from the parser) the correct error message
118       * gets displayed.
119       */
120      private static String initialise(Token currentToken,
121                               int[][] expectedTokenSequences,
122                               String[] tokenImage) {
123        String eol = System.getProperty("line.separator", "\n");
124        StringBuffer expected = new StringBuffer();
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.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
132          }
133          if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
134            expected.append("...");
135          }
136          expected.append(eol).append("    ");
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 += " " + tokenImage[tok.kind];
147          retval += " \"";
148          retval += add_escapes(tok.image);
149          retval += " \"";
150          tok = tok.next;
151        }
152        retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
153        retval += "." + eol;
154        if (expectedTokenSequences.length == 1) {
155          retval += "Was expecting:" + eol + "    ";
156        } else {
157          retval += "Was expecting one of:" + eol + "    ";
158        }
159        retval += expected.toString();
160        return retval;
161      }
162    
163      /**
164       * The end of line string for this machine.
165       */
166      protected String eol = System.getProperty("line.separator", "\n");
167    
168      /**
169       * Used to convert raw characters to their escaped version
170       * when these raw version cannot be used as part of an ASCII
171       * string literal.
172       */
173      static String add_escapes(String str) {
174          StringBuffer retval = new StringBuffer();
175          char ch;
176          for (int i = 0; i < str.length(); i++) {
177            switch (str.charAt(i))
178            {
179               case 0 :
180                  continue;
181               case '\b':
182                  retval.append("\\b");
183                  continue;
184               case '\t':
185                  retval.append("\\t");
186                  continue;
187               case '\n':
188                  retval.append("\\n");
189                  continue;
190               case '\f':
191                  retval.append("\\f");
192                  continue;
193               case '\r':
194                  retval.append("\\r");
195                  continue;
196               case '\"':
197                  retval.append("\\\"");
198                  continue;
199               case '\'':
200                  retval.append("\\\'");
201                  continue;
202               case '\\':
203                  retval.append("\\\\");
204                  continue;
205               default:
206                  if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
207                     String s = "0000" + Integer.toString(ch, 16);
208                     retval.append("\\u" + s.substring(s.length() - 4, s.length()));
209                  } else {
210                     retval.append(ch);
211                  }
212                  continue;
213            }
214          }
215          return retval.toString();
216       }
217    
218    }
219    /* JavaCC - OriginalChecksum=86ad1318fee326cd05ac75e58d942188 (do not edit this line) */