|
1 /* |
|
2 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 |
|
25 import java.util.HashMap; |
|
26 import java.util.Locale; |
|
27 import java.util.Map; |
|
28 |
|
29 import static java.util.Calendar.*; |
|
30 import static java.util.GregorianCalendar.*; |
|
31 |
|
32 public class Symbol { |
|
33 |
|
34 private static Map<String, Symbol> symbols; |
|
35 |
|
36 String name; |
|
37 Type type; |
|
38 int value; |
|
39 boolean isArithmetic; |
|
40 |
|
41 private Symbol(Type type, Integer value) { |
|
42 this(type, value, false); |
|
43 } |
|
44 |
|
45 private Symbol(Type type) { |
|
46 this(type, null, false); |
|
47 } |
|
48 |
|
49 private Symbol(Type type, boolean isArithmetic) { |
|
50 this(type, null, isArithmetic); |
|
51 } |
|
52 |
|
53 private Symbol(Type type, Integer value, boolean isArithmetic) { |
|
54 this.name = type.toString().toLowerCase(Locale.ROOT); |
|
55 this.type = type; |
|
56 if (value != null) |
|
57 this.value = value; |
|
58 this.isArithmetic = isArithmetic; |
|
59 } |
|
60 |
|
61 public int value() { |
|
62 return value; |
|
63 } |
|
64 |
|
65 public String toString() { |
|
66 return type.name(); |
|
67 } |
|
68 |
|
69 public boolean isArithmetic() { |
|
70 return isArithmetic; |
|
71 } |
|
72 |
|
73 public static Symbol get(String s) { |
|
74 return symbols.get(s); |
|
75 } |
|
76 |
|
77 public static enum Type { |
|
78 // Directives |
|
79 TEST, |
|
80 // Commands |
|
81 LOCALE, TIMEZONE, NEW, USE, ASSIGN, EVAL, |
|
82 CLEAR, SET, GET, ADD, ROLL, CHECK, PRINT, EXCEPTION, |
|
83 IF, |
|
84 // Operands |
|
85 INSTANCE, GREGORIAN, ALL, MILLIS, DATE, DATETIME, TIMEOFDAY, |
|
86 LENIENT, NONLENIENT, |
|
87 MINIMUM, GREATESTMINIMUM, ACTUALMINIMUM, |
|
88 MAXIMUM, LEASTMAXIMUM, ACTUALMAXIMUM, |
|
89 FIRSTDAYOFWEEK, MINIMALDAYSINFIRSTWEEK, |
|
90 // Arithmetic operators |
|
91 PLUS, MINUS, MULTIPLY, DIVIDE, MOD, |
|
92 // Relational operators |
|
93 GT, GE, EQ, NEQ, LE, LT, |
|
94 // Calendar field indices |
|
95 FIELD, |
|
96 // Day of week |
|
97 DAYOFWEEK, |
|
98 // Month |
|
99 MONTH, |
|
100 // AM/PM |
|
101 AMPM, |
|
102 // Era values |
|
103 ERA; |
|
104 } |
|
105 |
|
106 private static final void put(String key, Symbol sym) { |
|
107 Symbol s = symbols.put(key, sym); |
|
108 if (s != null) { |
|
109 throw new RuntimeException("duplicated key: " + key); |
|
110 } |
|
111 } |
|
112 |
|
113 static { |
|
114 symbols = new HashMap<String, Symbol>(); |
|
115 Symbol sym; |
|
116 // Directives |
|
117 put("test", new Symbol(Type.TEST)); |
|
118 |
|
119 // Commands |
|
120 put("locale", new Symbol(Type.LOCALE)); |
|
121 sym = new Symbol(Type.TIMEZONE); |
|
122 put("tz", sym); |
|
123 put("timezone", sym); |
|
124 put("new", new Symbol(Type.NEW)); |
|
125 put("use", new Symbol(Type.USE)); |
|
126 put("assign", new Symbol(Type.ASSIGN)); |
|
127 put("eval", new Symbol(Type.EVAL)); |
|
128 put("clear", new Symbol(Type.CLEAR)); |
|
129 put("set", new Symbol(Type.SET)); |
|
130 put("get", new Symbol(Type.GET)); |
|
131 put("add", new Symbol(Type.ADD)); |
|
132 put("roll", new Symbol(Type.ROLL)); |
|
133 put("check", new Symbol(Type.CHECK)); |
|
134 put("print", new Symbol(Type.PRINT)); |
|
135 put("exception", new Symbol(Type.EXCEPTION)); |
|
136 put("throw", get("exception")); |
|
137 put("if", new Symbol(Type.IF)); |
|
138 |
|
139 // Operands |
|
140 put("instance", new Symbol(Type.INSTANCE)); |
|
141 put("gregorian", new Symbol(Type.GREGORIAN)); |
|
142 put("all", new Symbol(Type.ALL)); |
|
143 put("millis", new Symbol(Type.MILLIS)); |
|
144 put("date", new Symbol(Type.DATE)); |
|
145 put("datetime", new Symbol(Type.DATETIME)); |
|
146 put("timeofday", new Symbol(Type.TIMEOFDAY)); |
|
147 put("lenient", new Symbol(Type.LENIENT)); |
|
148 sym = new Symbol(Type.NONLENIENT); |
|
149 put("non-lenient", sym); |
|
150 put("nonlenient", sym); |
|
151 put("firstdayofweek", new Symbol(Type.FIRSTDAYOFWEEK)); |
|
152 put("minimaldaysinfirstweek", new Symbol(Type.MINIMALDAYSINFIRSTWEEK)); |
|
153 |
|
154 sym = new Symbol(Type.MINIMUM); |
|
155 put("minimum", sym); |
|
156 put("min", sym); |
|
157 sym = new Symbol(Type.GREATESTMINIMUM); |
|
158 put("greatestminimum", sym); |
|
159 put("greatestmin", sym); |
|
160 sym = new Symbol(Type.ACTUALMINIMUM); |
|
161 put("actualminimum", sym); |
|
162 put("actualmin", sym); |
|
163 sym = new Symbol(Type.MAXIMUM); |
|
164 put("maximum", sym); |
|
165 put("max", sym); |
|
166 sym = new Symbol(Type.LEASTMAXIMUM); |
|
167 put("leastmaximum", sym); |
|
168 put("leastmax", sym); |
|
169 sym = new Symbol(Type.ACTUALMAXIMUM); |
|
170 put("actualmaximum", sym); |
|
171 put("actualmax", sym); |
|
172 |
|
173 // Arithmetic operators |
|
174 put("+", new Symbol(Type.PLUS, true)); |
|
175 put("-", new Symbol(Type.MINUS, true)); |
|
176 put("*", new Symbol(Type.MULTIPLY, true)); |
|
177 put("/", new Symbol(Type.DIVIDE, true)); |
|
178 put("%", new Symbol(Type.MOD, true)); |
|
179 |
|
180 // Relational operators |
|
181 put(">", new Symbol(Type.GT, false)); |
|
182 put(">=", new Symbol(Type.GE, false)); |
|
183 put("==", new Symbol(Type.EQ, false)); |
|
184 put("!=", new Symbol(Type.NEQ, false)); |
|
185 put("<=", new Symbol(Type.LE, false)); |
|
186 put("<", new Symbol(Type.LT, false)); |
|
187 |
|
188 // Calendar Fields |
|
189 put("era", new Symbol(Type.FIELD, ERA)); |
|
190 put("year", new Symbol(Type.FIELD, YEAR)); |
|
191 put("month", new Symbol(Type.FIELD, MONTH)); |
|
192 sym = new Symbol(Type.FIELD, WEEK_OF_YEAR); |
|
193 put("week_of_year", sym); |
|
194 put("weekofyear", sym); |
|
195 put("woy", sym); |
|
196 sym = new Symbol(Type.FIELD, WEEK_OF_MONTH); |
|
197 put("week_of_month", sym); |
|
198 put("weekofmonth", sym); |
|
199 put("wom", sym); |
|
200 sym = new Symbol(Type.FIELD, DAY_OF_MONTH); |
|
201 put("day_of_month", sym); |
|
202 put("dayofmonth", sym); |
|
203 put("dom", sym); |
|
204 sym = new Symbol(Type.FIELD, DAY_OF_YEAR); |
|
205 put("day_of_year", sym); |
|
206 put("dayofyear", sym); |
|
207 put("doy", sym); |
|
208 |
|
209 sym = new Symbol(Type.FIELD, DAY_OF_WEEK); |
|
210 put("day_of_week", sym); |
|
211 put("dayofweek", sym); |
|
212 put("dow", sym); |
|
213 sym = new Symbol(Type.FIELD, DAY_OF_WEEK_IN_MONTH); |
|
214 put("day_of_week_in_month", sym); |
|
215 put("dayofweekinmonth", sym); |
|
216 put("dowim", sym); |
|
217 sym = new Symbol(Type.FIELD, AM_PM); |
|
218 put("am_pm", sym); |
|
219 put("ampm", sym); |
|
220 put("hour", new Symbol(Type.FIELD, HOUR)); |
|
221 sym = new Symbol(Type.FIELD, HOUR_OF_DAY); |
|
222 put("hour_of_day", sym); |
|
223 put("hourofday", sym); |
|
224 put("hod", sym); |
|
225 put("minute", new Symbol(Type.FIELD, MINUTE)); |
|
226 put("second", new Symbol(Type.FIELD, SECOND)); |
|
227 put("millisecond", new Symbol(Type.FIELD, MILLISECOND)); |
|
228 sym = new Symbol(Type.FIELD, ZONE_OFFSET); |
|
229 put("zone_offset", sym); |
|
230 put("zoneoffset", sym); |
|
231 put("zo", sym); |
|
232 sym = new Symbol(Type.FIELD, DST_OFFSET); |
|
233 put("dst_offset", sym); |
|
234 put("dstoffset", sym); |
|
235 put("do", sym); |
|
236 |
|
237 // Day of week |
|
238 sym = new Symbol(Type.DAYOFWEEK, SUNDAY); |
|
239 put("sunday", sym); |
|
240 put("sun", sym); |
|
241 sym = new Symbol(Type.DAYOFWEEK, MONDAY); |
|
242 put("monday", sym); |
|
243 put("mon", sym); |
|
244 sym = new Symbol(Type.DAYOFWEEK, TUESDAY); |
|
245 put("tuesday", sym); |
|
246 put("tue", sym); |
|
247 sym = new Symbol(Type.DAYOFWEEK, WEDNESDAY); |
|
248 put("wednesday", sym); |
|
249 put("wed", sym); |
|
250 sym = new Symbol(Type.DAYOFWEEK, THURSDAY); |
|
251 put("thursday", sym); |
|
252 put("thu", sym); |
|
253 sym = new Symbol(Type.DAYOFWEEK, FRIDAY); |
|
254 put("friday", sym); |
|
255 put("fri", sym); |
|
256 sym = new Symbol(Type.DAYOFWEEK, SATURDAY); |
|
257 put("saturday", sym); |
|
258 put("sat", sym); |
|
259 |
|
260 |
|
261 // Month |
|
262 sym = new Symbol(Type.MONTH, JANUARY); |
|
263 put("january", sym); |
|
264 put("jan", sym); |
|
265 sym = new Symbol(Type.MONTH, FEBRUARY); |
|
266 put("february", sym); |
|
267 put("feb", sym); |
|
268 sym = new Symbol(Type.MONTH, MARCH); |
|
269 put("march", sym); |
|
270 put("mar", sym); |
|
271 sym = new Symbol(Type.MONTH, APRIL); |
|
272 put("april", sym); |
|
273 put("apr", sym); |
|
274 sym = new Symbol(Type.MONTH, MAY); |
|
275 put("may", sym); |
|
276 sym = new Symbol(Type.MONTH, JUNE); |
|
277 put("june", sym); |
|
278 put("jun", sym); |
|
279 sym = new Symbol(Type.MONTH, JULY); |
|
280 put("july", sym); |
|
281 put("jul", sym); |
|
282 sym = new Symbol(Type.MONTH, AUGUST); |
|
283 put("august", sym); |
|
284 put("aug", sym); |
|
285 sym = new Symbol(Type.MONTH, SEPTEMBER); |
|
286 put("september", sym); |
|
287 put("sep", sym); |
|
288 sym = new Symbol(Type.MONTH, OCTOBER); |
|
289 put("octobwe", sym); |
|
290 put("oct", sym); |
|
291 sym = new Symbol(Type.MONTH, NOVEMBER); |
|
292 put("november", sym); |
|
293 put("nov", sym); |
|
294 sym = new Symbol(Type.MONTH, DECEMBER); |
|
295 put("december", sym); |
|
296 put("dec", sym); |
|
297 sym = new Symbol(Type.MONTH, UNDECIMBER); |
|
298 put("undecimber", sym); |
|
299 |
|
300 // AM/PM |
|
301 put("am", new Symbol(Type.AMPM, AM)); |
|
302 put("pm", new Symbol(Type.AMPM, PM)); |
|
303 |
|
304 // Eras |
|
305 |
|
306 // Julian eras |
|
307 sym = new Symbol(Type.ERA, BC); |
|
308 put("bc", sym); |
|
309 put("bce", sym); |
|
310 sym = new Symbol(Type.ERA, AD); |
|
311 put("ad", sym); |
|
312 put("ce", sym); |
|
313 |
|
314 // Buddhist era |
|
315 put("be", new Symbol(Type.ERA, 1)); |
|
316 |
|
317 // Japanese imperial eras |
|
318 sym = new Symbol(Type.ERA, 0); |
|
319 put("before_meiji", sym); |
|
320 put("beforemeiji", sym); |
|
321 put("meiji", new Symbol(Type.ERA, 1)); |
|
322 put("taisho", new Symbol(Type.ERA, 2)); |
|
323 put("showa", new Symbol(Type.ERA, 3)); |
|
324 put("heisei", new Symbol(Type.ERA, 4)); |
|
325 put("newera", new Symbol(Type.ERA, 5)); |
|
326 |
|
327 } |
|
328 } |