@@ -27,7 +27,6 @@ import 'characters.dart';
2727import 'error_token.dart'
2828 show
2929 NonAsciiIdentifierToken,
30- UnmatchedEndToken,
3130 UnmatchedToken,
3231 UnsupportedOperator,
3332 UnterminatedString,
@@ -125,35 +124,15 @@ abstract class AbstractScanner implements Scanner {
125124 */
126125 Link <BeginToken > groupingStack = const Link <BeginToken >();
127126
128- final bool inRecoveryOption;
129- int recoveryCount = 0 ;
130-
131127 AbstractScanner (ScannerConfiguration config, this .includeComments,
132128 this .languageVersionChanged,
133129 {int numberOfBytesHint})
134- : lineStarts = new LineStarts (numberOfBytesHint),
135- inRecoveryOption = false {
130+ : lineStarts = new LineStarts (numberOfBytesHint) {
136131 this .tail = this .tokens;
137132 this .errorTail = this .tokens;
138133 this .configuration = config;
139134 }
140135
141- AbstractScanner createRecoveryOptionScanner ();
142-
143- AbstractScanner .recoveryOptionScanner (AbstractScanner copyFrom)
144- : lineStarts = [],
145- includeComments = false ,
146- languageVersionChanged = null ,
147- inRecoveryOption = true {
148- this .tail = this .tokens;
149- this .errorTail = this .tokens;
150- this ._enableExtensionMethods = copyFrom._enableExtensionMethods;
151- this ._enableNonNullable = copyFrom._enableNonNullable;
152- this ._enableTripleShift = copyFrom._enableTripleShift;
153- this .tokenStart = copyFrom.tokenStart;
154- this .groupingStack = copyFrom.groupingStack;
155- }
156-
157136 @override
158137 set configuration (ScannerConfiguration config) {
159138 if (config != null ) {
@@ -383,22 +362,9 @@ abstract class AbstractScanner implements Scanner {
383362 */
384363 int appendEndGroup (TokenType type, int openKind) {
385364 assert (! identical (openKind, LT_TOKEN )); // openKind is < for > and >>
386- bool foundMatchingBrace = discardBeginGroupUntil (openKind);
387- return appendEndGroupInternal (foundMatchingBrace, type, openKind);
388- }
389-
390- /// Append the end group (parenthesis, bracket etc).
391- /// If [foundMatchingBrace] is true the grouping stack (stack of parenthesis
392- /// etc) is updated, otherwise it's left alone.
393- /// In effect, if [foundMatchingBrace] is false this end token is basically
394- /// ignored, i.e. not really seen as an end group.
395- int appendEndGroupInternal (
396- bool foundMatchingBrace, TokenType type, int openKind) {
397- if (! foundMatchingBrace) {
398- // No begin group. Leave the grouping stack alone and just continue.
399- Token ignoredToken = new Token (type, tokenStart, comments);
400- appendToken (ignoredToken);
401- prependErrorToken (new UnmatchedEndToken (ignoredToken));
365+ if (! discardBeginGroupUntil (openKind)) {
366+ // No begin group found. Just continue.
367+ appendPrecedenceToken (type);
402368 return advance ();
403369 }
404370 appendPrecedenceToken (type);
@@ -506,7 +472,7 @@ abstract class AbstractScanner implements Scanner {
506472 * then discard begin group tokens up to that match and return `true` ,
507473 * otherwise return `false` .
508474 * This recovers nicely from from situations like "{[}" and "{foo());}",
509- * but not "foo(() {bar());});"
475+ * but not "foo(() {bar());});
510476 */
511477 bool discardBeginGroupUntil (int openKind) {
512478 Link <BeginToken > originalStack = groupingStack;
@@ -533,8 +499,6 @@ abstract class AbstractScanner implements Scanner {
533499 groupingStack = groupingStack.tail;
534500 } while (! groupingStack.isEmpty);
535501
536- recoveryCount++ ;
537-
538502 // If the stack does not have any opener of the given type,
539503 // then return without discarding anything.
540504 // This recovers nicely from from situations like "{foo());}".
@@ -543,90 +507,16 @@ abstract class AbstractScanner implements Scanner {
543507 return false ;
544508 }
545509
546- // We found a matching group somewhere in the stack, but generally don't
547- // know if we should recover by inserting synthetic closers or
548- // basically ignore the current token.
549- // We're in a recovery setting so we're allowed to be 'relatively slow' ---
550- // try both and see which is better (i.e. gives fewest rewrites later).
551- // To not get exponential runtime we will not do this nested though.
552- // E.g. we can recover "{[}" as "{[]}" (better) or (with . for ignored
553- // tokens) "{[.".
554- // Or we can recover "[(])]" as "[()].." or "[(.)]" (better).
555- if (! inRecoveryOption) {
556- TokenType type;
557- switch (openKind) {
558- case OPEN_SQUARE_BRACKET_TOKEN :
559- type = TokenType .CLOSE_SQUARE_BRACKET ;
560- break ;
561- case OPEN_CURLY_BRACKET_TOKEN :
562- type = TokenType .CLOSE_CURLY_BRACKET ;
563- break ;
564- case OPEN_PAREN_TOKEN :
565- type = TokenType .CLOSE_PAREN ;
566- break ;
567- default :
568- throw new StateError ("Unexpected openKind" );
569- }
570-
571- // Option #1: Insert synthetic closers.
572- int option1Recoveries;
573- {
574- AbstractScanner option1 = createRecoveryOptionScanner ();
575- option1.insertSyntheticClosers (originalStack, groupingStack);
576- option1Recoveries =
577- option1.recoveryOptionTokenizer (option1.appendEndGroupInternal (
578- /* foundMatchingBrace = */ true ,
579- type,
580- openKind));
581- option1Recoveries += option1.groupingStack.slowLength ();
582- }
583-
584- // Option #2: ignore this token.
585- int option2Recoveries;
586- {
587- AbstractScanner option2 = createRecoveryOptionScanner ();
588- option2.groupingStack = originalStack;
589- option2Recoveries =
590- option2.recoveryOptionTokenizer (option2.appendEndGroupInternal (
591- /* foundMatchingBrace = */ false ,
592- type,
593- openKind));
594- // We add 1 to make this option pay for ignoring this token.
595- option2Recoveries += option2.groupingStack.slowLength () + 1 ;
596- }
597-
598- // The option-runs might have set invalid endGroup pointers. Reset them.
599- for (Link <BeginToken > link = originalStack;
600- link.isNotEmpty;
601- link = link.tail) {
602- link.head.endToken = null ;
603- }
604-
605- if (option2Recoveries < option1Recoveries) {
606- // Perform option #2 recovery.
607- groupingStack = originalStack;
608- return false ;
609- }
610- // option #1 is the default, so fall though.
611- }
612-
613- // Insert synthetic closers and report errors for any unbalanced openers.
614- // This recovers nicely from from situations like "{[}".
615- insertSyntheticClosers (originalStack, groupingStack);
616- return true ;
617- }
618-
619- void insertSyntheticClosers (
620- Link <BeginToken > originalStack, Link <BeginToken > entryToUse) {
621510 // Insert synthetic closers and report errors for any unbalanced openers.
622511 // This recovers nicely from from situations like "{[}".
623- while (! identical (originalStack, entryToUse )) {
512+ while (! identical (originalStack, groupingStack )) {
624513 // Don't report unmatched errors for <; it is also the less-than operator.
625- if (! identical (entryToUse .head.kind, LT_TOKEN )) {
514+ if (! identical (groupingStack .head.kind, LT_TOKEN )) {
626515 unmatchedBeginGroup (originalStack.head);
627516 }
628517 originalStack = originalStack.tail;
629518 }
519+ return true ;
630520 }
631521
632522 /**
@@ -711,7 +601,6 @@ abstract class AbstractScanner implements Scanner {
711601 appendToken (new SyntheticToken (type, tokenStart)..beforeSynthetic = tail);
712602 begin.endGroup = tail;
713603 prependErrorToken (new UnmatchedToken (begin));
714- recoveryCount++ ;
715604 }
716605
717606 /// Return true when at EOF.
@@ -751,26 +640,6 @@ abstract class AbstractScanner implements Scanner {
751640 return firstToken ();
752641 }
753642
754- /// Tokenize a (small) part of the data. Used for recovery "option testing".
755- ///
756- /// Returns the number of recoveries performed.
757- int recoveryOptionTokenizer (int next) {
758- int iterations = 0 ;
759- while (! atEndOfFile ()) {
760- while (! identical (next, $EOF )) {
761- // TODO(jensj): Look at number of lines, tokens, parenthesis stack,
762- // semi-colon etc, not just number of iterations.
763- next = bigSwitch (next);
764- iterations++ ;
765-
766- if (iterations > 100 ) {
767- break ;
768- }
769- }
770- }
771- return recoveryCount;
772- }
773-
774643 int bigHeaderSwitch (int next) {
775644 if (! identical (next, $SLASH )) {
776645 return bigSwitch (next);
0 commit comments