001: package antlr;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.cs.usfca.edu
005: * Software rights: http://www.antlr.org/license.html
006: */
007:
008: import antlr.collections.impl.BitSet;
009: import antlr.collections.AST;
010:
011: public class MismatchedTokenException extends RecognitionException {
012: // Token names array for formatting
013: String[] tokenNames;
014: // The token that was encountered
015: public Token token;
016: // The offending AST node if tree walking
017: public AST node;
018:
019: String tokenText = null; // taken from node or token object
020:
021: // Types of tokens
022: public static final int TOKEN = 1;
023: public static final int NOT_TOKEN = 2;
024: public static final int RANGE = 3;
025: public static final int NOT_RANGE = 4;
026: public static final int SET = 5;
027: public static final int NOT_SET = 6;
028: // One of the above
029: public int mismatchType;
030:
031: // For TOKEN/NOT_TOKEN and RANGE/NOT_RANGE
032: public int expecting;
033:
034: // For RANGE/NOT_RANGE (expecting is lower bound of range)
035: public int upper;
036:
037: // For SET/NOT_SET
038: public BitSet set;
039:
040: /** Looking for AST wildcard, didn't find it */
041: public MismatchedTokenException() {
042: super ("Mismatched Token: expecting any AST node", "<AST>", -1,
043: -1);
044: }
045:
046: // Expected range / not range
047: public MismatchedTokenException(String[] tokenNames_, AST node_,
048: int lower, int upper_, boolean matchNot) {
049: super ("Mismatched Token", "<AST>", node_ == null ? -1 : node_
050: .getLine(), node_ == null ? -1 : node_.getColumn());
051: tokenNames = tokenNames_;
052: node = node_;
053: if (node_ == null) {
054: tokenText = "<empty tree>";
055: } else {
056: tokenText = node_.toString();
057: }
058: mismatchType = matchNot ? NOT_RANGE : RANGE;
059: expecting = lower;
060: upper = upper_;
061: }
062:
063: // Expected token / not token
064: public MismatchedTokenException(String[] tokenNames_, AST node_,
065: int expecting_, boolean matchNot) {
066: super ("Mismatched Token", "<AST>", node_ == null ? -1 : node_
067: .getLine(), node_ == null ? -1 : node_.getColumn());
068: tokenNames = tokenNames_;
069: node = node_;
070: if (node_ == null) {
071: tokenText = "<empty tree>";
072: } else {
073: tokenText = node_.toString();
074: }
075: mismatchType = matchNot ? NOT_TOKEN : TOKEN;
076: expecting = expecting_;
077: }
078:
079: // Expected BitSet / not BitSet
080: public MismatchedTokenException(String[] tokenNames_, AST node_,
081: BitSet set_, boolean matchNot) {
082: super ("Mismatched Token", "<AST>", node_ == null ? -1 : node_
083: .getLine(), node_ == null ? -1 : node_.getColumn());
084: tokenNames = tokenNames_;
085: node = node_;
086: if (node_ == null) {
087: tokenText = "<empty tree>";
088: } else {
089: tokenText = node_.toString();
090: }
091: mismatchType = matchNot ? NOT_SET : SET;
092: set = set_;
093: }
094:
095: // Expected range / not range
096: public MismatchedTokenException(String[] tokenNames_, Token token_,
097: int lower, int upper_, boolean matchNot, String fileName_) {
098: super ("Mismatched Token", fileName_, token_.getLine(), token_
099: .getColumn());
100: tokenNames = tokenNames_;
101: token = token_;
102: tokenText = token_.getText();
103: mismatchType = matchNot ? NOT_RANGE : RANGE;
104: expecting = lower;
105: upper = upper_;
106: }
107:
108: // Expected token / not token
109: public MismatchedTokenException(String[] tokenNames_, Token token_,
110: int expecting_, boolean matchNot, String fileName_) {
111: super ("Mismatched Token", fileName_, token_.getLine(), token_
112: .getColumn());
113: tokenNames = tokenNames_;
114: token = token_;
115: tokenText = token_.getText();
116: mismatchType = matchNot ? NOT_TOKEN : TOKEN;
117: expecting = expecting_;
118: }
119:
120: // Expected BitSet / not BitSet
121: public MismatchedTokenException(String[] tokenNames_, Token token_,
122: BitSet set_, boolean matchNot, String fileName_) {
123: super ("Mismatched Token", fileName_, token_.getLine(), token_
124: .getColumn());
125: tokenNames = tokenNames_;
126: token = token_;
127: tokenText = token_.getText();
128: mismatchType = matchNot ? NOT_SET : SET;
129: set = set_;
130: }
131:
132: /**
133: * Returns a clean error message (no line number/column information)
134: */
135: public String getMessage() {
136: StringBuffer sb = new StringBuffer();
137:
138: switch (mismatchType) {
139: case TOKEN:
140: sb.append("expecting " + tokenName(expecting) + ", found '"
141: + tokenText + "'");
142: break;
143: case NOT_TOKEN:
144: sb.append("expecting anything but " + tokenName(expecting)
145: + "; got it anyway");
146: break;
147: case RANGE:
148: sb.append("expecting token in range: "
149: + tokenName(expecting) + ".." + tokenName(upper)
150: + ", found '" + tokenText + "'");
151: break;
152: case NOT_RANGE:
153: sb.append("expecting token NOT in range: "
154: + tokenName(expecting) + ".." + tokenName(upper)
155: + ", found '" + tokenText + "'");
156: break;
157: case SET:
158: case NOT_SET:
159: sb.append("expecting "
160: + (mismatchType == NOT_SET ? "NOT " : "")
161: + "one of (");
162: int[] elems = set.toArray();
163: for (int i = 0; i < elems.length; i++) {
164: sb.append(" ");
165: sb.append(tokenName(elems[i]));
166: }
167: sb.append("), found '" + tokenText + "'");
168: break;
169: default:
170: sb.append(super .getMessage());
171: break;
172: }
173:
174: return sb.toString();
175: }
176:
177: private String tokenName(int tokenType) {
178: if (tokenType == Token.INVALID_TYPE) {
179: return "<Set of tokens>";
180: } else if (tokenType < 0 || tokenType >= tokenNames.length) {
181: return "<" + String.valueOf(tokenType) + ">";
182: } else {
183: return tokenNames[tokenType];
184: }
185: }
186: }
|