/*******************************************************************************
* Copyright (c) 2008 Scott Stanchfield.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Based on the ANTLR parser generator by Terence Parr, http://antlr.org
* Ric Klaren <klaren@cs.utwente.nl>
* Scott Stanchfield - Modifications for XML Parsing
*******************************************************************************/
package com.javadude.antxr;
import com.javadude.antxr.collections.impl.BitSet;
public class MismatchedCharException extends RecognitionException {
private static final long serialVersionUID = 1L;
// Types of chars
public static final int CHAR = 1;
public static final int NOT_CHAR = 2;
public static final int RANGE = 3;
public static final int NOT_RANGE = 4;
public static final int SET = 5;
public static final int NOT_SET = 6;
// One of the above
public int mismatchType;
// what was found on the input stream
public int foundChar;
// For CHAR/NOT_CHAR and RANGE/NOT_RANGE
public int expecting;
// For RANGE/NOT_RANGE (expecting is lower bound of range)
public int upper;
// For SET/NOT_SET
public BitSet set;
// who knows...they may want to ask scanner questions
public CharScanner scanner;
/**
* MismatchedCharException constructor comment.
*/
public MismatchedCharException() {
super("Mismatched char");
}
// Expected range / not range
public MismatchedCharException(char c, char lower, char upper_, boolean matchNot, CharScanner scanner_) {
super("Mismatched char", scanner_.getFilename(), scanner_.getLine(), scanner_.getColumn());
mismatchType = matchNot ? MismatchedCharException.NOT_RANGE : MismatchedCharException.RANGE;
foundChar = c;
expecting = lower;
upper = upper_;
scanner = scanner_;
}
// Expected token / not token
public MismatchedCharException(char c, char expecting_, boolean matchNot, CharScanner scanner_) {
super("Mismatched char", scanner_.getFilename(), scanner_.getLine(), scanner_.getColumn());
mismatchType = matchNot ? MismatchedCharException.NOT_CHAR : MismatchedCharException.CHAR;
foundChar = c;
expecting = expecting_;
scanner = scanner_;
}
// Expected BitSet / not BitSet
public MismatchedCharException(char c, BitSet set_, boolean matchNot, CharScanner scanner_) {
super("Mismatched char", scanner_.getFilename(), scanner_.getLine(), scanner_.getColumn());
mismatchType = matchNot ? MismatchedCharException.NOT_SET : MismatchedCharException.SET;
foundChar = c;
set = set_;
scanner = scanner_;
}
/**
* Returns a clean error message (no line number/column information)
*/
@Override
public String getMessage() {
StringBuffer sb = new StringBuffer();
switch (mismatchType) {
case CHAR:
sb.append("expecting "); appendCharName(sb, expecting);
sb.append(", found "); appendCharName(sb, foundChar);
break;
case NOT_CHAR:
sb.append("expecting anything but '");
appendCharName(sb, expecting);
sb.append("'; got it anyway");
break;
case RANGE:
case NOT_RANGE:
sb.append("expecting token ");
if (mismatchType == MismatchedCharException.NOT_RANGE) {
sb.append("NOT ");
}
sb.append("in range: ");
appendCharName(sb, expecting);
sb.append("..");
appendCharName(sb, upper);
sb.append(", found ");
appendCharName(sb, foundChar);
break;
case SET:
case NOT_SET:
sb.append("expecting " + (mismatchType == MismatchedCharException.NOT_SET ? "NOT " : "") + "one of (");
int[] elems = set.toArray();
for (int i = 0; i < elems.length; i++) {
appendCharName(sb, elems[i]);
}
sb.append("), found ");
appendCharName(sb, foundChar);
break;
default :
sb.append(super.getMessage());
break;
}
return sb.toString();
}
/** Append a char to the msg buffer. If special,
* then show escaped version
*/
private void appendCharName(StringBuffer sb, int c) {
switch (c) {
case 65535 :
// 65535 = (char) -1 = EOF
sb.append("'<EOF>'");
break;
case '\n' :
sb.append("'\\n'");
break;
case '\r' :
sb.append("'\\r'");
break;
case '\t' :
sb.append("'\\t'");
break;
default :
sb.append('\'');
sb.append((char) c);
sb.append('\'');
break;
}
}
}