KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > conditional > Lexer


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.conditional;
16
17 import org.apache.hivemind.util.Defense;
18
19 /**
20  * Parses a string into a series of {@link org.apache.hivemind.conditional.Token}s.
21  *
22  * @author Howard M. Lewis Ship
23  * @since 1.1
24  */

25 class Lexer
26 {
27     private char[] _input;
28
29     private int _cursor = 0;
30
31     private static final Token OPAREN = new Token(TokenType.OPAREN);
32
33     private static final Token CPAREN = new Token(TokenType.CPAREN);
34
35     private static final Token AND = new Token(TokenType.AND);
36
37     private static final Token OR = new Token(TokenType.OR);
38
39     private static final Token NOT = new Token(TokenType.NOT);
40
41     private static final Token PROPERTY = new Token(TokenType.PROPERTY);
42
43     private static final Token CLASS = new Token(TokenType.CLASS);
44
45     Lexer(String JavaDoc input)
46     {
47         Defense.notNull(input, "input");
48
49         _input = input.toCharArray();
50     }
51
52     /**
53      * Returns the next token from the input, or null when all tokens have been recognized.
54      */

55
56     Token next()
57     {
58         while (_cursor < _input.length)
59         {
60             char ch = _input[_cursor];
61
62             if (ch == ')')
63             {
64                 _cursor++;
65                 return CPAREN;
66             }
67
68             if (ch == '(')
69             {
70                 _cursor++;
71                 return OPAREN;
72             }
73
74             if (Character.isWhitespace(ch))
75             {
76                 _cursor++;
77                 continue;
78             }
79
80             if (isSymbolChar(ch))
81                 return readSymbol();
82
83             throw new RuntimeException JavaDoc(ConditionalMessages.unexpectedCharacter(_cursor, _input));
84         }
85
86         return null;
87     }
88
89     /**
90      * This is somewhat limited; a complete regexp would only allow dots within the text, would not
91      * allow consecutive dots, and would require that the string start with letter or underscore.
92      */

93
94     private boolean isSymbolChar(char ch)
95     {
96         return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')
97                 || (ch == '-') || (ch == '.') || (ch == '_');
98     }
99
100     /**
101      * Reads the next symbol at the cursor position, leaving the cursor on the character after the
102      * symbol. Also recognizes keywords.
103      */

104
105     private Token readSymbol()
106     {
107         int start = _cursor;
108
109         while (true)
110         {
111             _cursor++;
112
113             if (_cursor >= _input.length)
114                 break;
115
116             if (!isSymbolChar(_input[_cursor]))
117                 break;
118         }
119
120         String JavaDoc symbol = new String JavaDoc(_input, start, _cursor - start);
121
122         if (symbol.equalsIgnoreCase("and"))
123             return AND;
124
125         if (symbol.equalsIgnoreCase("or"))
126             return OR;
127
128         if (symbol.equalsIgnoreCase("not"))
129             return NOT;
130
131         if (symbol.equalsIgnoreCase("property"))
132             return PROPERTY;
133
134         if (symbol.equalsIgnoreCase("class"))
135             return CLASS;
136
137         return new Token(TokenType.SYMBOL, symbol);
138     }
139 }
Popular Tags