| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.scanner.keywords; | 5 library fasta.scanner.keywords; |
| 6 | 6 |
| 7 import 'characters.dart' show | 7 import 'characters.dart' show |
| 8 $a, $z, $A, $Z; | 8 $a; |
| 9 | 9 |
| 10 import 'precedence.dart' show | 10 import 'precedence.dart' show |
| 11 PrecedenceInfo; | 11 PrecedenceInfo; |
| 12 | 12 |
| 13 import 'precedence.dart' show | 13 import 'precedence.dart' show |
| 14 AS_INFO, | 14 AS_INFO, |
| 15 IS_INFO, | 15 IS_INFO, |
| 16 KEYWORD_INFO; | 16 KEYWORD_INFO; |
| 17 | 17 |
| 18 /** | 18 /** |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 const Keyword("library", isBuiltIn: true), | 70 const Keyword("library", isBuiltIn: true), |
| 71 const Keyword("operator", isBuiltIn: true), | 71 const Keyword("operator", isBuiltIn: true), |
| 72 const Keyword("part", isBuiltIn: true), | 72 const Keyword("part", isBuiltIn: true), |
| 73 const Keyword("set", isBuiltIn: true), | 73 const Keyword("set", isBuiltIn: true), |
| 74 const Keyword("static", isBuiltIn: true), | 74 const Keyword("static", isBuiltIn: true), |
| 75 const Keyword("typedef", isBuiltIn: true), | 75 const Keyword("typedef", isBuiltIn: true), |
| 76 | 76 |
| 77 const Keyword("async", isPseudo: true), | 77 const Keyword("async", isPseudo: true), |
| 78 const Keyword("await", isPseudo: true), | 78 const Keyword("await", isPseudo: true), |
| 79 const Keyword("deferred", isPseudo: true), | 79 const Keyword("deferred", isPseudo: true), |
| 80 const Keyword("Function", isPseudo: true), | |
| 81 const Keyword("hide", isPseudo: true), | 80 const Keyword("hide", isPseudo: true), |
| 82 const Keyword("native", isPseudo: true), | 81 const Keyword("native", isPseudo: true), |
| 83 const Keyword("of", isPseudo: true), | 82 const Keyword("of", isPseudo: true), |
| 84 const Keyword("on", isPseudo: true), | 83 const Keyword("on", isPseudo: true), |
| 85 const Keyword("patch", isPseudo: true), | 84 const Keyword("patch", isPseudo: true), |
| 86 const Keyword("show", isPseudo: true), | 85 const Keyword("show", isPseudo: true), |
| 87 const Keyword("source", isPseudo: true), | 86 const Keyword("source", isPseudo: true), |
| 88 const Keyword("sync", isPseudo: true), | 87 const Keyword("sync", isPseudo: true), |
| 89 const Keyword("yield", isPseudo: true), | 88 const Keyword("yield", isPseudo: true), |
| 90 ]; | 89 ]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 115 return result; | 114 return result; |
| 116 } | 115 } |
| 117 | 116 |
| 118 String toString() => syntax; | 117 String toString() => syntax; |
| 119 } | 118 } |
| 120 | 119 |
| 121 /** | 120 /** |
| 122 * Abstract state in a state machine for scanning keywords. | 121 * Abstract state in a state machine for scanning keywords. |
| 123 */ | 122 */ |
| 124 abstract class KeywordState { | 123 abstract class KeywordState { |
| 124 KeywordState(this.keyword); |
| 125 |
| 125 KeywordState next(int c); | 126 KeywordState next(int c); |
| 126 KeywordState nextCapital(int c); | 127 final Keyword keyword; |
| 127 | |
| 128 Keyword get keyword; | |
| 129 | 128 |
| 130 static KeywordState _KEYWORD_STATE; | 129 static KeywordState _KEYWORD_STATE; |
| 131 static KeywordState get KEYWORD_STATE { | 130 static KeywordState get KEYWORD_STATE { |
| 132 if (_KEYWORD_STATE == null) { | 131 if (_KEYWORD_STATE == null) { |
| 133 List<String> strings = new List<String>(Keyword.values.length); | 132 List<String> strings = new List<String>(Keyword.values.length); |
| 134 for (int i = 0; i < Keyword.values.length; i++) { | 133 for (int i = 0; i < Keyword.values.length; i++) { |
| 135 strings[i] = Keyword.values[i].syntax; | 134 strings[i] = Keyword.values[i].syntax; |
| 136 } | 135 } |
| 137 strings.sort((a, b) => a.compareTo(b)); | 136 strings.sort((a, b) => a.compareTo(b)); |
| 138 _KEYWORD_STATE = computeKeywordStateTable(0, strings, 0, strings.length); | 137 _KEYWORD_STATE = computeKeywordStateTable(0, strings, 0, strings.length); |
| 139 } | 138 } |
| 140 return _KEYWORD_STATE; | 139 return _KEYWORD_STATE; |
| 141 } | 140 } |
| 142 | 141 |
| 143 static KeywordState computeKeywordStateTable( | 142 static KeywordState computeKeywordStateTable( |
| 144 int start, List<String> strings, int offset, int length) { | 143 int start, List<String> strings, int offset, int length) { |
| 145 bool isLowercase = true; | 144 List<KeywordState> result = new List<KeywordState>(26); |
| 146 | |
| 147 List<KeywordState> table = new List<KeywordState>($z - $A + 1); | |
| 148 assert(length != 0); | 145 assert(length != 0); |
| 149 int chunk = 0; | 146 int chunk = 0; |
| 150 int chunkStart = -1; | 147 int chunkStart = -1; |
| 151 bool isLeaf = false; | 148 bool isLeaf = false; |
| 152 for (int i = offset; i < offset + length; i++) { | 149 for (int i = offset; i < offset + length; i++) { |
| 153 if (strings[i].length == start) { | 150 if (strings[i].length == start) { |
| 154 isLeaf = true; | 151 isLeaf = true; |
| 155 } | 152 } |
| 156 if (strings[i].length > start) { | 153 if (strings[i].length > start) { |
| 157 int c = strings[i].codeUnitAt(start); | 154 int c = strings[i].codeUnitAt(start); |
| 158 if ($A <= c && c <= $Z) { | |
| 159 isLowercase = false; | |
| 160 } | |
| 161 if (chunk != c) { | 155 if (chunk != c) { |
| 162 if (chunkStart != -1) { | 156 if (chunkStart != -1) { |
| 163 assert(table[chunk - $A] == null); | 157 assert(result[chunk - $a] == null); |
| 164 table[chunk - $A] = computeKeywordStateTable( | 158 result[chunk - $a] = computeKeywordStateTable( |
| 165 start + 1, strings, chunkStart, i - chunkStart); | 159 start + 1, strings, chunkStart, i - chunkStart); |
| 166 } | 160 } |
| 167 chunkStart = i; | 161 chunkStart = i; |
| 168 chunk = c; | 162 chunk = c; |
| 169 } | 163 } |
| 170 } | 164 } |
| 171 } | 165 } |
| 172 if (chunkStart != -1) { | 166 if (chunkStart != -1) { |
| 173 assert(table[chunk - $A] == null); | 167 assert(result[chunk - $a] == null); |
| 174 table[chunk - $A] = computeKeywordStateTable( | 168 result[chunk - $a] = computeKeywordStateTable( |
| 175 start + 1, strings, chunkStart, offset + length - chunkStart); | 169 start + 1, strings, chunkStart, offset + length - chunkStart); |
| 176 } else { | 170 } else { |
| 177 assert(length == 1); | 171 assert(length == 1); |
| 178 return new LeafKeywordState(strings[offset]); | 172 return new LeafKeywordState(strings[offset]); |
| 179 } | 173 } |
| 180 String syntax = isLeaf ? strings[offset] : null; | 174 if (isLeaf) { |
| 181 if (isLowercase) { | 175 return new ArrayKeywordState(result, strings[offset]); |
| 182 table = table.sublist($a - $A); | |
| 183 return new LowerCaseArrayKeywordState(table, syntax); | |
| 184 } else { | 176 } else { |
| 185 return new UpperCaseArrayKeywordState(table, syntax); | 177 return new ArrayKeywordState(result, null); |
| 186 } | 178 } |
| 187 } | 179 } |
| 188 } | 180 } |
| 189 | 181 |
| 190 /** | 182 /** |
| 191 * A state with multiple outgoing transitions. | 183 * A state with multiple outgoing transitions. |
| 192 */ | 184 */ |
| 193 abstract class ArrayKeywordState implements KeywordState { | 185 class ArrayKeywordState extends KeywordState { |
| 194 final List<KeywordState> table; | 186 final List<KeywordState> table; |
| 195 final Keyword keyword; | |
| 196 | 187 |
| 197 ArrayKeywordState(List<KeywordState> this.table, String syntax) | 188 ArrayKeywordState(List<KeywordState> this.table, String syntax) |
| 198 : keyword = ((syntax == null) ? null : Keyword.keywords[syntax]); | 189 : super((syntax == null) ? null : Keyword.keywords[syntax]); |
| 199 | 190 |
| 200 KeywordState next(int c); | 191 KeywordState next(int c) => table[c - $a]; |
| 201 | |
| 202 KeywordState nextCapital(int c); | |
| 203 | 192 |
| 204 String toString() { | 193 String toString() { |
| 205 StringBuffer sb = new StringBuffer(); | 194 StringBuffer sb = new StringBuffer(); |
| 206 sb.write("["); | 195 sb.write("["); |
| 207 if (keyword != null) { | 196 if (keyword != null) { |
| 208 sb.write("*"); | 197 sb.write("*"); |
| 209 sb.write(keyword); | 198 sb.write(keyword); |
| 210 sb.write(" "); | 199 sb.write(" "); |
| 211 } | 200 } |
| 212 List<KeywordState> foo = table; | 201 List<KeywordState> foo = table; |
| 213 for (int i = 0; i < foo.length; i++) { | 202 for (int i = 0; i < foo.length; i++) { |
| 214 if (foo[i] != null) { | 203 if (foo[i] != null) { |
| 215 sb.write("${new String.fromCharCodes([i + $a])}: " | 204 sb.write("${new String.fromCharCodes([i + $a])}: " |
| 216 "${foo[i]}; "); | 205 "${foo[i]}; "); |
| 217 } | 206 } |
| 218 } | 207 } |
| 219 sb.write("]"); | 208 sb.write("]"); |
| 220 return sb.toString(); | 209 return sb.toString(); |
| 221 } | 210 } |
| 222 } | 211 } |
| 223 | 212 |
| 224 class LowerCaseArrayKeywordState extends ArrayKeywordState { | |
| 225 | |
| 226 LowerCaseArrayKeywordState(List<KeywordState> table, String syntax) | |
| 227 : super(table, syntax) { | |
| 228 assert(table.length == $z - $a + 1); | |
| 229 } | |
| 230 | |
| 231 KeywordState next(int c) => table[c - $a]; | |
| 232 | |
| 233 KeywordState nextCapital(int c) => null; | |
| 234 | |
| 235 } | |
| 236 | |
| 237 class UpperCaseArrayKeywordState extends ArrayKeywordState { | |
| 238 | |
| 239 UpperCaseArrayKeywordState(List<KeywordState> table, String syntax) | |
| 240 : super(table, syntax) { | |
| 241 assert(table.length == $z - $A + 1); | |
| 242 } | |
| 243 | |
| 244 KeywordState next(int c) => table[c - $A]; | |
| 245 | |
| 246 KeywordState nextCapital(int c) => table[c - $A]; | |
| 247 | |
| 248 } | |
| 249 | |
| 250 /** | 213 /** |
| 251 * A state that has no outgoing transitions. | 214 * A state that has no outgoing transitions. |
| 252 */ | 215 */ |
| 253 class LeafKeywordState implements KeywordState { | 216 class LeafKeywordState extends KeywordState { |
| 254 final Keyword keyword; | 217 LeafKeywordState(String syntax) : super(Keyword.keywords[syntax]); |
| 255 | |
| 256 LeafKeywordState(String syntax) : keyword = Keyword.keywords[syntax]; | |
| 257 | 218 |
| 258 KeywordState next(int c) => null; | 219 KeywordState next(int c) => null; |
| 259 KeywordState nextCapital(int c) => null; | |
| 260 | 220 |
| 261 String toString() => keyword.syntax; | 221 String toString() => keyword.syntax; |
| 262 } | 222 } |
| OLD | NEW |