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 import 'package:front_end/src/base/errors.dart'; | 5 import 'package:front_end/src/base/errors.dart'; |
6 import 'package:front_end/src/fasta/fasta_codes.dart'; | 6 import 'package:front_end/src/fasta/fasta_codes.dart'; |
7 import 'package:front_end/src/fasta/scanner/error_token.dart'; | 7 import 'package:front_end/src/fasta/scanner/error_token.dart'; |
8 import 'package:front_end/src/scanner/token.dart' show Token; | 8 import 'package:front_end/src/scanner/token.dart' show Token, TokenType; |
9 import 'package:front_end/src/fasta/scanner/token_constants.dart'; | 9 import 'package:front_end/src/fasta/scanner/token_constants.dart'; |
10 | 10 |
11 /** | 11 /** |
12 * The error codes used for errors detected by the scanner. | 12 * The error codes used for errors detected by the scanner. |
13 */ | 13 */ |
14 class ScannerErrorCode extends ErrorCode { | 14 class ScannerErrorCode extends ErrorCode { |
15 /** | 15 /** |
16 * Parameters: | 16 * Parameters: |
| 17 * 0: the token that was expected but not found |
| 18 */ |
| 19 static const ScannerErrorCode EXPECTED_TOKEN = |
| 20 const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'."); |
| 21 |
| 22 /** |
| 23 * Parameters: |
17 * 0: the illegal character | 24 * 0: the illegal character |
18 */ | 25 */ |
19 static const ScannerErrorCode ILLEGAL_CHARACTER = | 26 static const ScannerErrorCode ILLEGAL_CHARACTER = |
20 const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'."); | 27 const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'."); |
21 | 28 |
22 static const ScannerErrorCode MISSING_DIGIT = | 29 static const ScannerErrorCode MISSING_DIGIT = |
23 const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected."); | 30 const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected."); |
24 | 31 |
25 static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode( | 32 static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode( |
26 'MISSING_HEX_DIGIT', "Hexidecimal digit expected."); | 33 'MISSING_HEX_DIGIT', "Hexidecimal digit expected."); |
27 | 34 |
| 35 static const ScannerErrorCode MISSING_IDENTIFIER = |
| 36 const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier."); |
| 37 |
28 static const ScannerErrorCode MISSING_QUOTE = | 38 static const ScannerErrorCode MISSING_QUOTE = |
29 const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \")."); | 39 const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \")."); |
30 | 40 |
31 /** | 41 /** |
32 * Parameters: | 42 * Parameters: |
33 * 0: the path of the file that cannot be read | 43 * 0: the path of the file that cannot be read |
34 */ | 44 */ |
35 static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode( | 45 static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode( |
36 'UNABLE_GET_CONTENT', "Unable to get content of '{0}'."); | 46 'UNABLE_GET_CONTENT', "Unable to get content of '{0}'."); |
37 | 47 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 case "MISSING_HEX_DIGIT": | 122 case "MISSING_HEX_DIGIT": |
113 // TODO(paulberry,ahe): Fasta reports the error location as the entire | 123 // TODO(paulberry,ahe): Fasta reports the error location as the entire |
114 // number; analyzer expects the end of the number. | 124 // number; analyzer expects the end of the number. |
115 charOffset = endOffset - 1; | 125 charOffset = endOffset - 1; |
116 return _makeError(ScannerErrorCode.MISSING_HEX_DIGIT, null); | 126 return _makeError(ScannerErrorCode.MISSING_HEX_DIGIT, null); |
117 | 127 |
118 case "ILLEGAL_CHARACTER": | 128 case "ILLEGAL_CHARACTER": |
119 return _makeError(ScannerErrorCode.ILLEGAL_CHARACTER, [token.character]); | 129 return _makeError(ScannerErrorCode.ILLEGAL_CHARACTER, [token.character]); |
120 | 130 |
121 default: | 131 default: |
122 if (errorCode == codeUnmatchedToken || | 132 if (errorCode == codeUnmatchedToken) { |
123 errorCode == codeUnexpectedDollarInString) { | 133 TokenType type = token.begin?.type; |
124 return null; | 134 if (type == TokenType.OPEN_CURLY_BRACKET || |
| 135 type == TokenType.STRING_INTERPOLATION_EXPRESSION) { |
| 136 return _makeError(ScannerErrorCode.EXPECTED_TOKEN, ['}']); |
| 137 } |
| 138 if (type == TokenType.OPEN_SQUARE_BRACKET) { |
| 139 return _makeError(ScannerErrorCode.EXPECTED_TOKEN, [']']); |
| 140 } |
| 141 if (type == TokenType.OPEN_PAREN) { |
| 142 return _makeError(ScannerErrorCode.EXPECTED_TOKEN, [')']); |
| 143 } |
| 144 } else if (errorCode == codeUnexpectedDollarInString) { |
| 145 return _makeError(ScannerErrorCode.MISSING_IDENTIFIER, null); |
125 } | 146 } |
126 throw new UnimplementedError('$errorCode'); | 147 throw new UnimplementedError('$errorCode'); |
127 } | 148 } |
128 } | 149 } |
129 | 150 |
130 /** | 151 /** |
131 * Determines whether the given [charOffset], which came from the non-EOF token | 152 * Determines whether the given [charOffset], which came from the non-EOF token |
132 * [token], represents the end of the input. | 153 * [token], represents the end of the input. |
133 */ | 154 */ |
134 bool _isAtEnd(Token token, int charOffset) { | 155 bool _isAtEnd(Token token, int charOffset) { |
135 while (true) { | 156 while (true) { |
136 // Skip to the next token. | 157 // Skip to the next token. |
137 token = token.next; | 158 token = token.next; |
138 // If we've found an EOF token, its charOffset indicates where the end of | 159 // If we've found an EOF token, its charOffset indicates where the end of |
139 // the input is. | 160 // the input is. |
140 if (token.isEof) return token.charOffset == charOffset; | 161 if (token.isEof) return token.charOffset == charOffset; |
141 // If we've found a non-error token, then we know there is additional input | 162 // If we've found a non-error token, then we know there is additional input |
142 // text after [charOffset]. | 163 // text after [charOffset]. |
143 if (token.type.kind != BAD_INPUT_TOKEN) return false; | 164 if (token.type.kind != BAD_INPUT_TOKEN) return false; |
144 // Otherwise keep looking. | 165 // Otherwise keep looking. |
145 } | 166 } |
146 } | 167 } |
OLD | NEW |