001 /* Copyright 2000, 2001, Compaq Computer Corporation */ 002 003 package javafe.parser; 004 005 import javafe.util.Assert; 006 007 /** 008 * <code>TagConstants</tt> is a class defining the constants used to 009 * identify different kinds of tokens. 010 */ 011 012 public class TagConstants extends javafe.ast.TagConstants 013 { 014 public static final int EOF = javafe.ast.TagConstants.LAST_TAG + 1; 015 016 // Value tokens 017 public static final int MAX_INT_PLUS_ONE = EOF + 1; 018 public static final int MAX_LONG_PLUS_ONE = MAX_INT_PLUS_ONE + 1; 019 020 // Pragma tokens 021 public static final int LEXICALPRAGMA = MAX_LONG_PLUS_ONE + 1; 022 public static final int MODIFIERPRAGMA = LEXICALPRAGMA + 1; 023 public static final int POSTMODIFIERPRAGMA = MODIFIERPRAGMA + 1; 024 public static final int STMTPRAGMA = POSTMODIFIERPRAGMA + 1; 025 public static final int TYPEDECLELEMPRAGMA = STMTPRAGMA + 1; 026 public static final int TYPEMODIFIERPRAGMA = TYPEDECLELEMPRAGMA + 1; 027 028 public static final int UNKNOWN_KEYWORD = TYPEMODIFIERPRAGMA + 1; 029 030 // Some punctuation tokens (rest come from OperatorTags) 031 public static final int COMMA = UNKNOWN_KEYWORD + 1; 032 public static final int SEMICOLON = COMMA + 1; 033 public static final int LBRACE = SEMICOLON + 1; 034 public static final int RBRACE = LBRACE + 1; 035 public static final int LPAREN = RBRACE + 1; 036 public static final int RPAREN = LPAREN + 1; 037 public static final int LSQBRACKET = RPAREN + 1; 038 public static final int RSQBRACKET = LSQBRACKET + 1; 039 040 public static final int QUESTIONMARK = RSQBRACKET + 1; 041 public static final int COLON = QUESTIONMARK + 1; 042 043 public static final int FIELD = COLON + 1; 044 045 public static final int C_COMMENT = FIELD + 1; 046 public static final int EOL_COMMENT = C_COMMENT + 1; 047 048 // Keywords 049 public static final int FIRST_KEYWORD = EOL_COMMENT + 1; 050 public static final int ABSTRACT = FIRST_KEYWORD; 051 public static final int ASSERT = ABSTRACT + 1; 052 public static final int BOOLEAN = ASSERT + 1; 053 public static final int BREAK = BOOLEAN + 1; 054 public static final int BYTE = BREAK + 1; 055 public static final int CASE = BYTE + 1; 056 public static final int CATCH = CASE + 1; 057 public static final int CHAR = CATCH + 1; 058 public static final int CLASS = CHAR + 1; 059 public static final int CONST = CLASS + 1; 060 public static final int CONTINUE = CONST + 1; 061 public static final int DEFAULT = CONTINUE + 1; 062 public static final int DO = DEFAULT + 1; 063 public static final int DOUBLE = DO + 1; 064 public static final int ELSE = DOUBLE + 1; 065 public static final int EXTENDS = ELSE + 1; 066 public static final int FALSE = EXTENDS + 1; 067 public static final int FINAL = FALSE + 1; 068 public static final int FINALLY = FINAL + 1; 069 public static final int FLOAT = FINALLY + 1; 070 public static final int FOR = FLOAT + 1; 071 public static final int GOTO = FOR + 1; 072 public static final int IF = GOTO + 1; 073 public static final int IMPLEMENTS = IF + 1; 074 public static final int IMPORT = IMPLEMENTS + 1; 075 public static final int INSTANCEOF = IMPORT + 1; 076 public static final int INT = INSTANCEOF + 1; 077 public static final int INTERFACE= INT + 1; 078 public static final int LONG = INTERFACE + 1; 079 public static final int NATIVE = LONG + 1; 080 public static final int NEW = NATIVE + 1; 081 public static final int NULL = NEW + 1; 082 public static final int PACKAGE = NULL + 1; 083 public static final int PRIVATE = PACKAGE + 1; 084 public static final int PROTECTED= PRIVATE + 1; 085 public static final int PUBLIC = PROTECTED + 1; 086 public static final int RETURN = PUBLIC + 1; 087 public static final int SHORT = RETURN + 1; 088 public static final int STATIC = SHORT + 1; 089 public static final int STRICT = STATIC + 1; 090 public static final int SUPER = STRICT + 1; 091 public static final int SWITCH = SUPER + 1; 092 public static final int SYNCHRONIZED = SWITCH + 1; 093 public static final int THIS = SYNCHRONIZED + 1; 094 public static final int THROW = THIS + 1; 095 public static final int THROWS = THROW + 1; 096 public static final int TRANSIENT= THROWS + 1; 097 public static final int TRUE = TRANSIENT + 1; 098 public static final int TRY = TRUE + 1; 099 public static final int VOID = TRY + 1; 100 public static final int VOLATILE = VOID + 1; 101 public static final int WHILE = VOLATILE + 1; 102 public static final int LAST_KEYWORD = WHILE; 103 104 public static final int LAST_TAG = LAST_KEYWORD; 105 106 /** 107 * @return text representation of <code>code</code> (e.g., "=" for 108 * <tt>ASSIGN</tt>). Requires <code>code</code> is one of the 109 * token constants defined in <code>Tokens</code> (including ones 110 * inherited from <code>OperatorTags</code>). 111 */ 112 113 //@ ensures \result != null; 114 public static String toString(int code) { 115 if (FIRST_KEYWORD <= code && code <= LAST_KEYWORD) 116 return getString(code - FIRST_KEYWORD); 117 for(int i = 1 + LAST_KEYWORD - FIRST_KEYWORD; i < noTokens; i++) 118 if (getCode(i) == code) return getString(i); 119 120 if (code <= javafe.ast.TagConstants.LAST_TAG) 121 return javafe.ast.TagConstants.toString(code); 122 123 return "Tag unknown to javafe.parser.TagConstants <" + code 124 + " (+" + (code - javafe.ast.TagConstants.LAST_TAG) + ") >"; 125 } 126 127 /** 128 * Alphabetical list of Java punctuation strings. In addition to 129 * being used in <code>Tokens</code>, this variable is used by 130 * <code>Lex</code> to implement <code>addJavaPunctuation</code>. 131 */ 132 133 //@ invariant \nonnullelements(punctuationStrings); 134 static final /*@ non_null @*/ String punctuationStrings[] = { 135 "!", "!=", "%", "%=", "&", "&&", "&=", "(", ")", "*", "*=", 136 "+", "++", "+=", ",", "-", "--", "-=", ".", "/", "/=", ":", ";", 137 "<", "<<", "<<=", "<=", "=", "==", ">", ">=", ">>", ">>=", ">>>", ">>>=", 138 "?", "[", "]", "^", "^=", "{", "|", "|=", "||", "}", "~", "/*", "//" 139 }; 140 141 /** 142 * List of codes for Java punctuation. Order of this list agrees 143 * with with order of punctuationStrings. In addition to being 144 * used in <code>Tokens</code>, this variable is used by 145 * <code>Lex</code> to implement 146 * <code>addJavaPunctuation</code>. 147 */ 148 149 //@ invariant punctuationCodes.length == punctuationStrings.length; 150 /*@ invariant (\forall int i; 0 <= i && i <= punctuationCodes.length 151 @ ==> punctuationCodes[i] != TagConstants.IDENT && 152 @ punctuationCodes[i] != TagConstants.BOOLEANLIT && 153 @ punctuationCodes[i] != TagConstants.INTLIT && 154 @ punctuationCodes[i] != TagConstants.LONGLIT && 155 @ punctuationCodes[i] != TagConstants.FLOATLIT && 156 @ punctuationCodes[i] != TagConstants.DOUBLELIT && 157 @ punctuationCodes[i] != TagConstants.STRINGLIT && 158 @ punctuationCodes[i] != TagConstants.CHARLIT && 159 @ punctuationCodes[i] != TagConstants.LEXICALPRAGMA && 160 @ punctuationCodes[i] != TagConstants.MODIFIERPRAGMA && 161 @ punctuationCodes[i] != TagConstants.STMTPRAGMA && 162 @ punctuationCodes[i] != TagConstants.TYPEDECLELEMPRAGMA && 163 @ punctuationCodes[i] != TagConstants.TYPEMODIFIERPRAGMA); */ 164 //@ invariant punctuationCodes.owner instanceof TagConstants; 165 //@ spec_public 166 static final int punctuationCodes[] = { 167 NOT, NE, MOD, ASGREM, BITAND, AND, ASGBITAND, LPAREN, RPAREN, STAR, ASGMUL, 168 ADD, INC, ASGADD, COMMA, SUB, DEC, ASGSUB, FIELD, DIV, ASGDIV, COLON, 169 SEMICOLON, 170 LT, LSHIFT, ASGLSHIFT, LE, ASSIGN, EQ, GT, GE, RSHIFT, ASGRSHIFT, URSHIFT, 171 ASGURSHIFT, 172 QUESTIONMARK, LSQBRACKET, RSQBRACKET, BITXOR, ASGBITXOR, LBRACE, BITOR, 173 ASGBITOR, OR, RBRACE, BITNOT, C_COMMENT, EOL_COMMENT 174 }; 175 176 /** 177 * Alphabetical list of Java keywords. The keyword codes are also 178 * alphabetical, which means that if X is code of keyword K, then 179 * keywordStrings[X - FIRST_KEYWORD] should equal K. 180 */ 181 182 //@ invariant keywordStrings.length == 1 + LAST_KEYWORD - FIRST_KEYWORD; 183 //@ invariant \nonnullelements(keywordStrings); 184 //@ spec_public 185 private static final String keywordStrings[] = { 186 "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", 187 "class", "const", "continue", "default", "do", "double", "else", 188 "extends", "false", "final", "finally", "float", "for", "goto", "if", 189 "implements", "import", "instanceof", "int", "interface", "long", 190 "native", "new", "null", 191 "package", "private", "protected", "public", "return", 192 "short", "static", "strictfp", "super", "switch", "synchronized", "this", 193 "throw", "throws", "transient", "true", "try", "void", "volatile", "while" 194 }; 195 196 //@ invariant \nonnullelements(otherStrings); 197 //@ spec_public 198 private static final String otherStrings[] = { 199 "IDENT", 200 "CHARLIT", "INTLIT", "2147483648", 201 "LONGLIT", "9223372036854775808L", "FLOATLIT", "DOUBLELIT", "STRINGLIT", 202 "LEXICALPRAGMA", "MODIFIERPRAGMA", "POSTMODIFIERPRAGMA", 203 "STMTPRAGMA", "TYPEDECLELEMPRAGMA", 204 "TYPEMODIFIERPRAGMA", "EOF" 205 }; 206 207 //@ invariant otherCodes.length == otherStrings.length; 208 //@ spec_public 209 private static final int otherCodes[] = { 210 IDENT, 211 CHARLIT, INTLIT, MAX_INT_PLUS_ONE, 212 LONGLIT, MAX_LONG_PLUS_ONE, FLOATLIT, DOUBLELIT, STRINGLIT, 213 LEXICALPRAGMA, MODIFIERPRAGMA, POSTMODIFIERPRAGMA, 214 STMTPRAGMA, TYPEDECLELEMPRAGMA, 215 TYPEMODIFIERPRAGMA, EOF 216 }; 217 218 //@ invariant noTokens == keywordStrings.length + punctuationStrings.length + otherStrings.length; 219 //@ spec_public 220 private static final int noTokens = 221 keywordStrings.length + punctuationStrings.length + otherStrings.length; 222 223 //@ requires 0 <= index && index < noTokens; 224 private static int getCode(int index) { 225 Assert.precondition(0 <= index && index < noTokens); 226 if (index < 1 + LAST_KEYWORD - FIRST_KEYWORD) return FIRST_KEYWORD + index; 227 index -= 1 + LAST_KEYWORD - FIRST_KEYWORD; 228 if (index < punctuationCodes.length) return punctuationCodes[index]; 229 index -= punctuationCodes.length; 230 if (index < otherCodes.length) return otherCodes[index]; 231 index -= otherCodes.length; 232 Assert.notFalse(false, "Bad invariant"); 233 return -1; // Dummy 234 } 235 236 //@ requires 0 <= index && index < noTokens; 237 //@ ensures \result != null; 238 private static String getString(int index) { 239 Assert.precondition(0 <= index && index < noTokens); 240 if (index < keywordStrings.length) 241 return keywordStrings[index]; 242 index -= keywordStrings.length; 243 if (index < punctuationStrings.length) 244 return punctuationStrings[index]; 245 index -= punctuationStrings.length; 246 if (index < otherStrings.length) 247 return otherStrings[index]; 248 index -= otherStrings.length; 249 Assert.notFalse(false, "Bad invariant"); 250 return null; // Dummy 251 } 252 253 /** Perform module-level checks. */ 254 public static void zzzz() { 255 Assert.notFalse(noTokens == (keywordStrings.length 256 + punctuationStrings.length 257 + otherStrings.length)); 258 Assert.notFalse(noTokens == (keywordStrings.length 259 + punctuationCodes.length 260 + otherCodes.length)); 261 // Check for duplicates 262 for(int i = 0; i < noTokens; i++) 263 for(int j = i+1; j < noTokens; j++) 264 if (getCode(i) == getCode(j)) 265 System.out.println("Duplicate (" + getCode(i) + ") at " + 266 getString(i) + " " + getString(j)); 267 } 268 }