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