OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 /** | |
6 * A keyword in the Dart programming language. | |
7 */ | |
8 class Keyword implements SourceString { | |
9 static final Keyword BREAK = const Keyword("break"); | |
10 static final Keyword CASE = const Keyword("case"); | |
11 static final Keyword CATCH = const Keyword("catch"); | |
12 static final Keyword CLASS = const Keyword("class"); | |
13 static final Keyword CONST = const Keyword("const"); | |
14 static final Keyword CONTINUE = const Keyword("continue"); | |
15 static final Keyword DEFAULT = const Keyword("default"); | |
16 static final Keyword DO = const Keyword("do"); | |
17 static final Keyword ELSE = const Keyword("else"); | |
18 static final Keyword EXTENDS = const Keyword("extends"); | |
19 static final Keyword FALSE = const Keyword("false"); | |
20 static final Keyword FINAL = const Keyword("final"); | |
21 static final Keyword FINALLY = const Keyword("finally"); | |
22 static final Keyword FOR = const Keyword("for"); | |
23 static final Keyword IF = const Keyword("if"); | |
24 static final Keyword IN = const Keyword("in"); | |
25 static final Keyword IS = const Keyword("is", info: IS_INFO); | |
26 static final Keyword NEW = const Keyword("new"); | |
27 static final Keyword NULL = const Keyword("null"); | |
28 static final Keyword RETURN = const Keyword("return"); | |
29 static final Keyword SUPER = const Keyword("super"); | |
30 static final Keyword SWITCH = const Keyword("switch"); | |
31 static final Keyword THIS = const Keyword("this"); | |
32 static final Keyword THROW = const Keyword("throw"); | |
33 static final Keyword TRUE = const Keyword("true"); | |
34 static final Keyword TRY = const Keyword("try"); | |
35 static final Keyword VAR = const Keyword("var"); | |
36 static final Keyword VOID = const Keyword("void"); | |
37 static final Keyword WHILE = const Keyword("while"); | |
38 | |
39 // Pseudo keywords: | |
40 static final Keyword ABSTRACT = const Keyword("abstract", isPseudo: true); | |
41 static final Keyword ASSERT = const Keyword("assert", isPseudo: true); | |
42 static final Keyword FACTORY = const Keyword("factory", isPseudo: true); | |
43 static final Keyword GET = const Keyword("get", isPseudo: true); | |
44 static final Keyword IMPLEMENTS = const Keyword("implements", isPseudo: true); | |
45 static final Keyword IMPORT = const Keyword("import", isPseudo: true); | |
46 static final Keyword INTERFACE = const Keyword("interface", isPseudo: true); | |
47 static final Keyword LIBRARY = const Keyword("library", isPseudo: true); | |
48 static final Keyword NATIVE = const Keyword("native", isPseudo: true); | |
49 static final Keyword NEGATE = const Keyword("negate", isPseudo: true); | |
50 static final Keyword OPERATOR = const Keyword("operator", isPseudo: true); | |
51 static final Keyword SET = const Keyword("set", isPseudo: true); | |
52 static final Keyword SOURCE = const Keyword("source", isPseudo: true); | |
53 static final Keyword STATIC = const Keyword("static", isPseudo: true); | |
54 static final Keyword TYPEDEF = const Keyword("typedef", isPseudo: true); | |
55 | |
56 static final List<Keyword> values = const <Keyword> [ | |
57 BREAK, | |
58 CASE, | |
59 CATCH, | |
60 CONST, | |
61 CONTINUE, | |
62 DEFAULT, | |
63 DO, | |
64 ELSE, | |
65 FALSE, | |
66 FINAL, | |
67 FINALLY, | |
68 FOR, | |
69 IF, | |
70 IN, | |
71 IS, | |
72 NEW, | |
73 NULL, | |
74 RETURN, | |
75 SUPER, | |
76 SWITCH, | |
77 THIS, | |
78 THROW, | |
79 TRUE, | |
80 TRY, | |
81 VAR, | |
82 VOID, | |
83 WHILE, | |
84 ABSTRACT, | |
85 ASSERT, | |
86 CLASS, | |
87 EXTENDS, | |
88 FACTORY, | |
89 GET, | |
90 IMPLEMENTS, | |
91 IMPORT, | |
92 INTERFACE, | |
93 LIBRARY, | |
94 NATIVE, | |
95 NEGATE, | |
96 OPERATOR, | |
97 SET, | |
98 SOURCE, | |
99 STATIC, | |
100 TYPEDEF ]; | |
101 | |
102 final String syntax; | |
103 final bool isPseudo; | |
104 final PrecedenceInfo info; | |
105 | |
106 static Map<String, Keyword> _keywords; | |
107 static Map<String, Keyword> get keywords() { | |
108 if (_keywords === null) { | |
109 _keywords = computeKeywordMap(); | |
110 } | |
111 return _keywords; | |
112 } | |
113 | |
114 const Keyword(String this.syntax, | |
115 [bool this.isPseudo = false, | |
116 PrecedenceInfo this.info = KEYWORD_INFO]); | |
117 | |
118 static Map<String, Keyword> computeKeywordMap() { | |
119 Map<String, Keyword> result = new LinkedHashMap<String, Keyword>(); | |
120 for (Keyword keyword in values) { | |
121 result[keyword.syntax] = keyword; | |
122 } | |
123 return result; | |
124 } | |
125 | |
126 int hashCode() => syntax.hashCode(); | |
127 | |
128 bool operator ==(other) { | |
129 return other is SourceString && toString() == other.slowToString(); | |
130 } | |
131 | |
132 Iterator<int> iterator() => new StringCodeIterator(syntax); | |
133 | |
134 void printOn(StringBuffer sb) { | |
135 sb.add(syntax); | |
136 } | |
137 | |
138 String toString() => syntax; | |
139 String slowToString() => syntax; | |
140 String get stringValue() => syntax; | |
141 | |
142 bool isEmpty() => false; | |
143 bool isPrivate() => false; | |
144 } | |
145 | |
146 /** | |
147 * Abstract state in a state machine for scanning keywords. | |
148 */ | |
149 class KeywordState { | |
150 abstract bool isLeaf(); | |
151 abstract KeywordState next(int c); | |
152 abstract Keyword get keyword(); | |
153 | |
154 static KeywordState _KEYWORD_STATE; | |
155 static KeywordState get KEYWORD_STATE() { | |
156 if (_KEYWORD_STATE === null) { | |
157 List<String> strings = new List<String>(Keyword.values.length); | |
158 for (int i = 0; i < Keyword.values.length; i++) { | |
159 strings[i] = Keyword.values[i].syntax; | |
160 } | |
161 strings.sort((a,b) => a.compareTo(b)); | |
162 _KEYWORD_STATE = computeKeywordStateTable(0, strings, 0, strings.length); | |
163 } | |
164 return _KEYWORD_STATE; | |
165 } | |
166 | |
167 static KeywordState computeKeywordStateTable(int start, List<String> strings, | |
168 int offset, int length) { | |
169 List<KeywordState> result = new List<KeywordState>(26); | |
170 assert(length != 0); | |
171 int chunk = 0; | |
172 int chunkStart = -1; | |
173 bool isLeaf = false; | |
174 for (int i = offset; i < offset + length; i++) { | |
175 if (strings[i].length == start) { | |
176 isLeaf = true; | |
177 } | |
178 if (strings[i].length > start) { | |
179 int c = strings[i].charCodeAt(start); | |
180 if (chunk != c) { | |
181 if (chunkStart != -1) { | |
182 assert(result[chunk - $a] === null); | |
183 result[chunk - $a] = computeKeywordStateTable(start + 1, strings, | |
184 chunkStart, | |
185 i - chunkStart); | |
186 } | |
187 chunkStart = i; | |
188 chunk = c; | |
189 } | |
190 } | |
191 } | |
192 if (chunkStart != -1) { | |
193 assert(result[chunk - $a] === null); | |
194 result[chunk - $a] = | |
195 computeKeywordStateTable(start + 1, strings, chunkStart, | |
196 offset + length - chunkStart); | |
197 } else { | |
198 assert(length == 1); | |
199 return new LeafKeywordState(strings[offset]); | |
200 } | |
201 if (isLeaf) { | |
202 return new ArrayKeywordState(result, strings[offset]); | |
203 } else { | |
204 return new ArrayKeywordState(result, null); | |
205 } | |
206 } | |
207 } | |
208 | |
209 /** | |
210 * A state with multiple outgoing transitions. | |
211 */ | |
212 class ArrayKeywordState extends KeywordState { | |
213 final List<KeywordState> table; | |
214 final Keyword keyword; | |
215 | |
216 ArrayKeywordState(List<KeywordState> this.table, String syntax) | |
217 : keyword = (syntax === null) ? null : Keyword.keywords[syntax]; | |
218 | |
219 bool isLeaf() => false; | |
220 | |
221 KeywordState next(int c) => table[c - $a]; | |
222 | |
223 String toString() { | |
224 StringBuffer sb = new StringBuffer(); | |
225 sb.add("["); | |
226 if (keyword !== null) { | |
227 sb.add("*"); | |
228 sb.add(keyword); | |
229 sb.add(" "); | |
230 } | |
231 List<KeywordState> foo = table; | |
232 for (int i = 0; i < foo.length; i++) { | |
233 if (foo[i] != null) { | |
234 sb.add("${new String.fromCharCodes([i + $a])}: ${foo[i]}; "); | |
235 } | |
236 } | |
237 sb.add("]"); | |
238 return sb.toString(); | |
239 } | |
240 } | |
241 | |
242 /** | |
243 * A state that has no outgoing transitions. | |
244 */ | |
245 class LeafKeywordState extends KeywordState { | |
246 final Keyword keyword; | |
247 | |
248 LeafKeywordState(String syntax) : keyword = Keyword.keywords[syntax]; | |
249 | |
250 bool isLeaf() => true; | |
251 | |
252 KeywordState next(int c) => null; | |
253 | |
254 String toString() => keyword.syntax; | |
255 } | |
OLD | NEW |