001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.util.parser; 033 034/** 035 * This exception is thrown when parse errors are encountered. You can 036 * explicitly create objects of this exception type by calling the method 037 * generateParseException in the generated parser. 038 * 039 * You can modify this class to customize your error reporting mechanisms so 040 * long as you retain the public fields. 041 */ 042public class ParseException extends Exception { 043 044 /** 045 * The version identifier for this Serializable class. Increment only if the 046 * <i>serialized</i> form of the class changes. 047 */ 048 private static final long serialVersionUID = 1L; 049 050 /** 051 * This constructor is used by the method "generateParseException" in the 052 * generated parser. Calling this constructor generates a new object of this 053 * type with the fields "currentToken", "expectedTokenSequences", and 054 * "tokenImage" set. 055 */ 056 public ParseException(Token currentTokenVal, 057 int[][] expectedTokenSequencesVal, String[] tokenImageVal) { 058 super(initialise(currentTokenVal, expectedTokenSequencesVal, 059 tokenImageVal)); 060 currentToken = currentTokenVal; 061 expectedTokenSequences = expectedTokenSequencesVal; 062 tokenImage = tokenImageVal; 063 } 064 065 /** 066 * The following constructors are for use by you for whatever purpose you 067 * can think of. Constructing the exception in this manner makes the 068 * exception behave in the normal way - i.e., as documented in the class 069 * "Throwable". The fields "errorToken", "expectedTokenSequences", and 070 * "tokenImage" do not contain relevant information. The JavaCC generated 071 * code does not use these constructors. 072 */ 073 074 public ParseException() { 075 super(); 076 } 077 078 /** Constructor with message. */ 079 public ParseException(String message) { 080 super(message); 081 } 082 083 /** 084 * This is the last token that has been consumed successfully. If this 085 * object has been created due to a parse error, the token followng this 086 * token will (therefore) be the first error token. 087 */ 088 public Token currentToken; 089 090 /** 091 * Each entry in this array is an array of integers. Each array of integers 092 * represents a sequence of tokens (by their ordinal values) that is 093 * expected at this point of the parse. 094 */ 095 public int[][] expectedTokenSequences; 096 097 /** 098 * This is a reference to the "tokenImage" array of the generated parser 099 * within which the parse error occurred. This array is defined in the 100 * generated ...Constants interface. 101 */ 102 public String[] tokenImage; 103 104 /** 105 * It uses "currentToken" and "expectedTokenSequences" to generate a parse 106 * error message and returns it. If this object has been created due to a 107 * parse error, and you do not catch it (it gets thrown from the parser) the 108 * correct error message gets displayed. 109 */ 110 private static String initialise(Token currentToken, 111 int[][] expectedTokenSequences, String[] tokenImage) { 112 String eol = System.getProperty("line.separator", "\n"); 113 StringBuffer expected = new StringBuffer(); 114 int maxSize = 0; 115 for (int i = 0; i < expectedTokenSequences.length; i++) { 116 if (maxSize < expectedTokenSequences[i].length) { 117 maxSize = expectedTokenSequences[i].length; 118 } 119 for (int j = 0; j < expectedTokenSequences[i].length; j++) { 120 expected.append(tokenImage[expectedTokenSequences[i][j]]) 121 .append(' '); 122 } 123 if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { 124 expected.append("..."); 125 } 126 expected.append(eol).append(" "); 127 } 128 String retval = "Encountered \""; 129 Token tok = currentToken.next; 130 for (int i = 0; i < maxSize; i++) { 131 if (i != 0) 132 retval += " "; 133 if (tok.kind == 0) { 134 retval += tokenImage[0]; 135 break; 136 } 137 retval += " " + tokenImage[tok.kind]; 138 retval += " \""; 139 retval += add_escapes(tok.image); 140 retval += " \""; 141 tok = tok.next; 142 } 143 retval += "\" at line " + currentToken.next.beginLine + ", column " 144 + currentToken.next.beginColumn; 145 retval += "." + eol; 146 if (expectedTokenSequences.length == 1) { 147 retval += "Was expecting:" + eol + " "; 148 } else { 149 retval += "Was expecting one of:" + eol + " "; 150 } 151 retval += expected.toString(); 152 return retval; 153 } 154 155 /** 156 * The end of line string for this machine. 157 */ 158 protected String eol = System.getProperty("line.separator", "\n"); 159 160 /** 161 * Used to convert raw characters to their escaped version when these raw 162 * version cannot be used as part of an ASCII string literal. 163 */ 164 static String add_escapes(String str) { 165 StringBuffer retval = new StringBuffer(); 166 char ch; 167 for (int i = 0; i < str.length(); i++) { 168 switch (str.charAt(i)) { 169 case 0: 170 continue; 171 case '\b': 172 retval.append("\\b"); 173 continue; 174 case '\t': 175 retval.append("\\t"); 176 continue; 177 case '\n': 178 retval.append("\\n"); 179 continue; 180 case '\f': 181 retval.append("\\f"); 182 continue; 183 case '\r': 184 retval.append("\\r"); 185 continue; 186 case '\"': 187 retval.append("\\\""); 188 continue; 189 case '\'': 190 retval.append("\\\'"); 191 continue; 192 case '\\': 193 retval.append("\\\\"); 194 continue; 195 default: 196 if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { 197 String s = "0000" + Integer.toString(ch, 16); 198 retval.append("\\u" 199 + s.substring(s.length() - 4, s.length())); 200 } else { 201 retval.append(ch); 202 } 203 continue; 204 } 205 } 206 return retval.toString(); 207 } 208 209} 210/* 211 * JavaCC - OriginalChecksum=9046b556c7577c2f7d673183ae801879 (do not edit this 212 * line) 213 */