| 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 |