OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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.abstract_scanner; | 5 library fasta.scanner.abstract_scanner; |
6 | 6 |
7 import 'dart:collection' show ListMixin; | 7 import 'dart:collection' show ListMixin; |
8 | 8 |
9 import 'dart:typed_data' show Uint16List, Uint32List; | 9 import 'dart:typed_data' show Uint16List, Uint32List; |
10 | 10 |
11 import '../scanner.dart' | 11 import '../scanner.dart' |
12 show ErrorToken, Scanner, buildUnexpectedCharacterToken; | 12 show ErrorToken, Scanner, buildUnexpectedCharacterToken; |
13 | 13 |
14 import 'error_token.dart' show UnmatchedToken, UnterminatedToken; | 14 import 'error_token.dart' show UnterminatedToken; |
15 | 15 |
16 import 'keyword.dart' show KeywordState, Keyword; | 16 import 'keyword.dart' show KeywordState, Keyword; |
17 | 17 |
18 import 'precedence.dart'; | 18 import 'precedence.dart'; |
19 | 19 |
20 import 'token.dart' show BeginGroupToken, CommentToken, SymbolToken, Token; | 20 import 'token.dart' show BeginGroupToken, CommentToken, SymbolToken, Token; |
21 | 21 |
22 import 'token_constants.dart'; | 22 import 'token_constants.dart'; |
23 | 23 |
24 import 'characters.dart'; | 24 import 'characters.dart'; |
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 } | 1109 } |
1110 | 1110 |
1111 int advanceAfterError(bool shouldAdvance) { | 1111 int advanceAfterError(bool shouldAdvance) { |
1112 if (atEndOfFile()) return $EOF; | 1112 if (atEndOfFile()) return $EOF; |
1113 if (shouldAdvance) { | 1113 if (shouldAdvance) { |
1114 return advance(); // Ensure progress. | 1114 return advance(); // Ensure progress. |
1115 } else { | 1115 } else { |
1116 return -1; | 1116 return -1; |
1117 } | 1117 } |
1118 } | 1118 } |
1119 | |
1120 void unmatchedBeginGroup(BeginGroupToken begin) { | |
1121 // We want to ensure that unmatched BeginGroupTokens are reported as | |
1122 // errors. However, the diet parser assumes that groups are well-balanced | |
1123 // and will never look at the endGroup token. This is a nice property that | |
1124 // allows us to skip quickly over correct code. By inserting an additional | |
1125 // synthetic token in the stream, we can keep ignoring endGroup tokens. | |
1126 // | |
1127 // [begin] --next--> [tail] | |
1128 // [begin] --endG--> [synthetic] --next--> [next] --next--> [tail] | |
1129 // | |
1130 // This allows the diet parser to skip from [begin] via endGroup to | |
1131 // [synthetic] and ignore the [synthetic] token (assuming it's correct), | |
1132 // then the error will be reported when parsing the [next] token. | |
1133 // | |
1134 // For example, tokenize("{[1};") produces: | |
1135 // | |
1136 // SymbolToken({) --endGroup-----+ | |
1137 // | | | |
1138 // next | | |
1139 // v | | |
1140 // SymbolToken([) --endGroup--+ | | |
1141 // | | | | |
1142 // next | | | |
1143 // v | | | |
1144 // StringToken(1) | | | |
1145 // | v | | |
1146 // next SymbolToken(]) | <- Synthetic token. | |
1147 // | | | | |
1148 // | next | | |
1149 // v | | | |
1150 // UnmatchedToken([)<---------+ | | |
1151 // | | | |
1152 // next | | |
1153 // v | | |
1154 // SymbolToken(})<---------------+ | |
1155 // | | |
1156 // next | |
1157 // v | |
1158 // SymbolToken(;) | |
1159 // | | |
1160 // next | |
1161 // v | |
1162 // EOF | |
1163 Token synthetic = | |
1164 new SymbolToken(closeBraceInfoFor(begin), begin.charOffset); | |
1165 UnmatchedToken next = new UnmatchedToken(begin); | |
1166 begin.endGroup = synthetic; | |
1167 synthetic.next = next; | |
1168 appendErrorToken(next); | |
1169 } | |
1170 } | 1119 } |
1171 | 1120 |
1172 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { | 1121 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { |
1173 return const { | 1122 return const { |
1174 '(': CLOSE_PAREN_INFO, | 1123 '(': CLOSE_PAREN_INFO, |
1175 '[': CLOSE_SQUARE_BRACKET_INFO, | 1124 '[': CLOSE_SQUARE_BRACKET_INFO, |
1176 '{': CLOSE_CURLY_BRACKET_INFO, | 1125 '{': CLOSE_CURLY_BRACKET_INFO, |
1177 '<': GT_INFO, | 1126 '<': GT_INFO, |
1178 r'${': CLOSE_CURLY_BRACKET_INFO, | 1127 r'${': CLOSE_CURLY_BRACKET_INFO, |
1179 }[begin.lexeme]; | 1128 }[begin.lexeme]; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 switchToUint32(newLength); | 1197 switchToUint32(newLength); |
1249 } | 1198 } |
1250 } | 1199 } |
1251 | 1200 |
1252 void switchToUint32(int newLength) { | 1201 void switchToUint32(int newLength) { |
1253 final newArray = new Uint32List(newLength); | 1202 final newArray = new Uint32List(newLength); |
1254 newArray.setRange(0, arrayLength, array); | 1203 newArray.setRange(0, arrayLength, array); |
1255 array = newArray; | 1204 array = newArray; |
1256 } | 1205 } |
1257 } | 1206 } |
OLD | NEW |