Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.analyzer.token_utils; | 5 library fasta.analyzer.token_utils; |
| 6 | 6 |
| 7 import 'package:front_end/src/fasta/parser/error_kind.dart' show | 7 import 'package:front_end/src/fasta/parser/error_kind.dart' show |
| 8 ErrorKind; | 8 ErrorKind; |
| 9 | 9 |
| 10 import 'package:front_end/src/fasta/scanner/error_token.dart' show | 10 import 'package:front_end/src/fasta/scanner/error_token.dart' show |
| 11 ErrorToken; | 11 ErrorToken; |
| 12 | 12 |
| 13 import 'package:front_end/src/fasta/scanner/keyword.dart' show | |
| 14 Keyword; | |
| 15 | |
| 16 import 'package:front_end/src/fasta/scanner/precedence.dart'; | |
| 17 | |
| 13 import 'package:front_end/src/fasta/scanner/token.dart' show | 18 import 'package:front_end/src/fasta/scanner/token.dart' show |
| 19 BeginGroupToken, | |
| 14 KeywordToken, | 20 KeywordToken, |
| 21 StringToken, | |
| 22 SymbolToken, | |
| 15 Token; | 23 Token; |
| 16 | 24 |
| 17 import 'package:front_end/src/fasta/scanner/token_constants.dart'; | 25 import 'package:front_end/src/fasta/scanner/token_constants.dart'; |
| 18 | 26 |
| 19 import 'package:front_end/src/scanner/token.dart' as analyzer show | 27 import 'package:front_end/src/scanner/token.dart' as analyzer show |
| 20 CommentToken, | 28 CommentToken, |
| 21 Keyword, | 29 Keyword, |
| 22 KeywordToken, | 30 KeywordToken, |
| 23 KeywordTokenWithComment, | 31 KeywordTokenWithComment, |
| 24 StringToken, | 32 StringToken, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 translatedToken.previous = analyzerTokenTail; | 87 translatedToken.previous = analyzerTokenTail; |
| 80 analyzerTokenTail = translatedToken; | 88 analyzerTokenTail = translatedToken; |
| 81 } | 89 } |
| 82 if (token.isEof) { | 90 if (token.isEof) { |
| 83 return analyzerTokenHead.next; | 91 return analyzerTokenHead.next; |
| 84 } | 92 } |
| 85 token = token.next; | 93 token = token.next; |
| 86 } | 94 } |
| 87 } | 95 } |
| 88 | 96 |
| 97 /// Converts a stream of Analyzer tokens (starting with [token] and continuing | |
| 98 /// to EOF) to a stream of Fasta tokens. | |
| 99 /// | |
| 100 /// TODO(paulberry): Analyzer tokens do not record error conditions, so a round | |
| 101 /// trip through this function and [toAnalyzerTokenStream] will lose error | |
| 102 /// information. | |
| 103 Token fromAnalyzerTokenStream(analyzer.Token analyzerToken) { | |
| 104 Token tokenHead = new SymbolToken(EOF_INFO, -1); | |
| 105 Token tokenTail = tokenHead; | |
| 106 analyzer.Token translateAndAppend(analyzer.Token analyzerToken) { | |
| 107 var token = fromAnalyzerToken(analyzerToken); | |
| 108 tokenTail.next = token; | |
| 109 tokenTail = token; | |
| 110 return analyzerToken.next; | |
| 111 } | |
| 112 | |
| 113 while (true) { | |
| 114 analyzer.Token commentToken = analyzerToken.precedingComments; | |
| 115 while (commentToken != null) { | |
| 116 commentToken = translateAndAppend(commentToken); | |
| 117 } | |
| 118 // TODO(paulberry): join up begingroup/endgroup. | |
| 119 if (analyzerToken.type == TokenType.EOF) { | |
| 120 tokenTail.next = new SymbolToken(EOF_INFO, analyzerToken.offset); | |
| 121 return tokenHead.next; | |
| 122 } | |
| 123 analyzerToken = translateAndAppend(analyzerToken); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 /// Converts a single analyzer token into a Fasta token. | |
| 128 Token fromAnalyzerToken(analyzer.Token token) { | |
| 129 Token beginGroup(PrecedenceInfo info) => | |
| 130 new BeginGroupToken(info, token.offset); | |
| 131 Token string(PrecedenceInfo info) => | |
| 132 new StringToken.fromString(info, token.lexeme, token.offset); | |
| 133 Token symbol(PrecedenceInfo info) => new SymbolToken(info, token.offset); | |
| 134 switch (token.type) { | |
| 135 case TokenType.DOUBLE: | |
| 136 return string(DOUBLE_INFO); | |
| 137 case TokenType.HEXADECIMAL: | |
| 138 return string(HEXADECIMAL_INFO); | |
| 139 case TokenType.IDENTIFIER: | |
| 140 // Certain identifiers have special grammatical meanings even though they | |
| 141 // are neither keywords nor built-in identifiers (e.g. "async"). Analyzer | |
| 142 // represents these as identifiers. Fasta represents them as keywords | |
| 143 // with the "isPseudo" property. | |
| 144 var keyword = Keyword.keywords[token.lexeme]; | |
| 145 if (keyword != null) { | |
| 146 assert(keyword.isPseudo); | |
| 147 return new KeywordToken(keyword, token.offset); | |
| 148 } else { | |
| 149 return string(IDENTIFIER_INFO); | |
| 150 } | |
| 151 break; | |
| 152 case TokenType.INT: | |
| 153 return string(INT_INFO); | |
| 154 case TokenType.KEYWORD: | |
| 155 var keyword = Keyword.keywords[token.lexeme]; | |
| 156 if (keyword != null) { | |
| 157 return new KeywordToken(keyword, token.offset); | |
| 158 } else { | |
| 159 return internalError('Unrecognized keyword: ${token.lexeme}'); | |
|
ahe
2017/02/12 10:07:35
For consistency: "Unrecognized keyword: '${token.l
Paul Berry
2017/02/13 17:44:33
Done.
| |
| 160 } | |
| 161 break; | |
| 162 case TokenType.MULTI_LINE_COMMENT: | |
| 163 return string(COMMENT_INFO); | |
| 164 // case TokenType.SCRIPT_TAG | |
| 165 case TokenType.SINGLE_LINE_COMMENT: | |
| 166 return string(COMMENT_INFO); | |
| 167 case TokenType.STRING: | |
| 168 return string(STRING_INFO); | |
| 169 case TokenType.AMPERSAND: | |
| 170 return symbol(AMPERSAND_INFO); | |
| 171 case TokenType.AMPERSAND_AMPERSAND: | |
| 172 return symbol(AMPERSAND_AMPERSAND_INFO); | |
| 173 // case TokenType.AMPERSAND_AMPERSAND_EQ | |
| 174 case TokenType.AMPERSAND_EQ: | |
| 175 return symbol(AMPERSAND_EQ_INFO); | |
| 176 case TokenType.AT: | |
| 177 return symbol(AT_INFO); | |
| 178 case TokenType.BANG: | |
| 179 return symbol(BANG_INFO); | |
| 180 case TokenType.BANG_EQ: | |
| 181 return symbol(BANG_EQ_INFO); | |
| 182 case TokenType.BAR: | |
| 183 return symbol(BAR_INFO); | |
| 184 case TokenType.BAR_BAR: | |
| 185 return symbol(BAR_BAR_INFO); | |
| 186 // case TokenType.BAR_BAR_EQ | |
| 187 case TokenType.BAR_EQ: | |
| 188 return symbol(BAR_EQ_INFO); | |
| 189 case TokenType.COLON: | |
| 190 return symbol(COLON_INFO); | |
| 191 case TokenType.COMMA: | |
| 192 return symbol(COMMA_INFO); | |
| 193 case TokenType.CARET: | |
| 194 return symbol(CARET_INFO); | |
| 195 case TokenType.CARET_EQ: | |
| 196 return symbol(CARET_EQ_INFO); | |
| 197 case TokenType.CLOSE_CURLY_BRACKET: | |
| 198 return symbol(CLOSE_CURLY_BRACKET_INFO); | |
| 199 case TokenType.CLOSE_PAREN: | |
| 200 return symbol(CLOSE_PAREN_INFO); | |
| 201 case TokenType.CLOSE_SQUARE_BRACKET: | |
| 202 return symbol(CLOSE_SQUARE_BRACKET_INFO); | |
| 203 case TokenType.EQ: | |
| 204 return symbol(EQ_INFO); | |
| 205 case TokenType.EQ_EQ: | |
| 206 return symbol(EQ_EQ_INFO); | |
| 207 case TokenType.FUNCTION: | |
| 208 return symbol(FUNCTION_INFO); | |
| 209 case TokenType.GT: | |
| 210 return symbol(GT_INFO); | |
| 211 case TokenType.GT_EQ: | |
| 212 return symbol(GT_EQ_INFO); | |
| 213 case TokenType.GT_GT: | |
| 214 return symbol(GT_GT_INFO); | |
| 215 case TokenType.GT_GT_EQ: | |
| 216 return symbol(GT_GT_EQ_INFO); | |
| 217 case TokenType.HASH: | |
| 218 return symbol(HASH_INFO); | |
| 219 case TokenType.INDEX: | |
| 220 return symbol(INDEX_INFO); | |
| 221 case TokenType.INDEX_EQ: | |
| 222 return symbol(INDEX_EQ_INFO); | |
| 223 case TokenType.LT: | |
| 224 return symbol(LT_INFO); | |
| 225 case TokenType.LT_EQ: | |
| 226 return symbol(LT_EQ_INFO); | |
| 227 case TokenType.LT_LT: | |
| 228 return symbol(LT_LT_INFO); | |
| 229 case TokenType.LT_LT_EQ: | |
| 230 return symbol(LT_LT_EQ_INFO); | |
| 231 case TokenType.MINUS: | |
| 232 return symbol(MINUS_INFO); | |
| 233 case TokenType.MINUS_EQ: | |
| 234 return symbol(MINUS_EQ_INFO); | |
| 235 case TokenType.MINUS_MINUS: | |
| 236 return symbol(MINUS_MINUS_INFO); | |
| 237 case TokenType.OPEN_CURLY_BRACKET: | |
| 238 return beginGroup(OPEN_CURLY_BRACKET_INFO); | |
| 239 case TokenType.OPEN_PAREN: | |
| 240 return beginGroup(OPEN_PAREN_INFO); | |
| 241 case TokenType.OPEN_SQUARE_BRACKET: | |
| 242 return beginGroup(OPEN_SQUARE_BRACKET_INFO); | |
| 243 case TokenType.PERCENT: | |
| 244 return symbol(PERCENT_INFO); | |
| 245 case TokenType.PERCENT_EQ: | |
| 246 return symbol(PERCENT_EQ_INFO); | |
| 247 case TokenType.PERIOD: | |
| 248 return symbol(PERIOD_INFO); | |
| 249 case TokenType.PERIOD_PERIOD: | |
| 250 return symbol(PERIOD_PERIOD_INFO); | |
| 251 case TokenType.PLUS: | |
| 252 return symbol(PLUS_INFO); | |
| 253 case TokenType.PLUS_EQ: | |
| 254 return symbol(PLUS_EQ_INFO); | |
| 255 case TokenType.PLUS_PLUS: | |
| 256 return symbol(PLUS_PLUS_INFO); | |
| 257 case TokenType.QUESTION: | |
| 258 return symbol(QUESTION_INFO); | |
| 259 case TokenType.QUESTION_PERIOD: | |
| 260 return symbol(QUESTION_PERIOD_INFO); | |
| 261 case TokenType.QUESTION_QUESTION: | |
| 262 return symbol(QUESTION_QUESTION_INFO); | |
| 263 case TokenType.QUESTION_QUESTION_EQ: | |
| 264 return symbol(QUESTION_QUESTION_EQ_INFO); | |
| 265 case TokenType.SEMICOLON: | |
| 266 return symbol(SEMICOLON_INFO); | |
| 267 case TokenType.SLASH: | |
| 268 return symbol(SLASH_INFO); | |
| 269 case TokenType.SLASH_EQ: | |
| 270 return symbol(SLASH_EQ_INFO); | |
| 271 case TokenType.STAR: | |
| 272 return symbol(STAR_INFO); | |
| 273 case TokenType.STAR_EQ: | |
| 274 return symbol(STAR_EQ_INFO); | |
| 275 case TokenType.STRING_INTERPOLATION_EXPRESSION: | |
| 276 return beginGroup(STRING_INTERPOLATION_INFO); | |
| 277 case TokenType.STRING_INTERPOLATION_IDENTIFIER: | |
| 278 return symbol(STRING_INTERPOLATION_IDENTIFIER_INFO); | |
| 279 case TokenType.TILDE: | |
| 280 return symbol(TILDE_INFO); | |
| 281 case TokenType.TILDE_SLASH: | |
| 282 return symbol(TILDE_SLASH_INFO); | |
| 283 case TokenType.TILDE_SLASH_EQ: | |
| 284 return symbol(TILDE_SLASH_EQ_INFO); | |
| 285 case TokenType.BACKPING: | |
| 286 return symbol(BACKPING_INFO); | |
| 287 case TokenType.BACKSLASH: | |
| 288 return symbol(BACKSLASH_INFO); | |
| 289 case TokenType.PERIOD_PERIOD_PERIOD: | |
| 290 return symbol(PERIOD_PERIOD_PERIOD_INFO); | |
| 291 // case TokenType.GENERIC_METHOD_TYPE_ASSIGN | |
| 292 // case TokenType.GENERIC_METHOD_TYPE_LIST | |
| 293 default: | |
| 294 return internalError('Unhandled token type ${token.type}'); | |
| 295 } | |
| 296 } | |
| 297 | |
| 89 /// Determines whether the given [charOffset], which came from the non-EOF token | 298 /// Determines whether the given [charOffset], which came from the non-EOF token |
| 90 /// [token], represents the end of the input. | 299 /// [token], represents the end of the input. |
| 91 bool _isAtEnd(Token token, int charOffset) { | 300 bool _isAtEnd(Token token, int charOffset) { |
| 92 while (true) { | 301 while (true) { |
| 93 // Skip to the next token. | 302 // Skip to the next token. |
| 94 token = token.next; | 303 token = token.next; |
| 95 // If we've found an EOF token, its charOffset indicates where the end of | 304 // If we've found an EOF token, its charOffset indicates where the end of |
| 96 // the input is. | 305 // the input is. |
| 97 if (token.isEof) return token.charOffset == charOffset; | 306 if (token.isEof) return token.charOffset == charOffset; |
| 98 // If we've found a non-error token, then we know there is additional input | 307 // If we've found a non-error token, then we know there is additional input |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 case BACKSLASH_TOKEN: return TokenType.BACKSLASH; | 566 case BACKSLASH_TOKEN: return TokenType.BACKSLASH; |
| 358 case PERIOD_PERIOD_PERIOD_TOKEN: return TokenType.PERIOD_PERIOD_PERIOD; | 567 case PERIOD_PERIOD_PERIOD_TOKEN: return TokenType.PERIOD_PERIOD_PERIOD; |
| 359 // case GENERIC_METHOD_TYPE_LIST_TOKEN: | 568 // case GENERIC_METHOD_TYPE_LIST_TOKEN: |
| 360 // return TokenType.GENERIC_METHOD_TYPE_LIST; | 569 // return TokenType.GENERIC_METHOD_TYPE_LIST; |
| 361 // case GENERIC_METHOD_TYPE_ASSIGN_TOKEN: | 570 // case GENERIC_METHOD_TYPE_ASSIGN_TOKEN: |
| 362 // return TokenType.GENERIC_METHOD_TYPE_ASSIGN; | 571 // return TokenType.GENERIC_METHOD_TYPE_ASSIGN; |
| 363 default: | 572 default: |
| 364 return internalError("Unhandled token ${token.info}"); | 573 return internalError("Unhandled token ${token.info}"); |
| 365 } | 574 } |
| 366 } | 575 } |
| OLD | NEW |