[parser] Enable coverage in `abstract_scanner`; increase coverage; remove unreachable places

Change-Id: Icf634b29f0cea274c2039deea48218b4c15872a8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/437440
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index df46757..67513b8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -396,7 +396,10 @@
   }
 
   int _getLineOf(Token token) {
-    if (lineStarts.isEmpty) return -1;
+    if (lineStarts.isEmpty) {
+      // Coverage-ignore-block(suite): Not run.
+      return -1;
+    }
     final int offset = token.offset;
     int low = 0, high = lineStarts.length - 1;
     while (low < high) {
@@ -425,7 +428,10 @@
   /// `a` because it's the indentation of the `if`, even though the _line_ of a
   /// has a different indentation of the _line_ of `{`.
   int _spacesAtStartOfLogicalLineOf(Token token) {
-    if (lineStarts.isEmpty) return -1;
+    if (lineStarts.isEmpty) {
+      // Coverage-ignore-block(suite): Not run.
+      return -1;
+    }
 
     // If the previous token is a `)`, e.g. if this is the start curly brace in
     // an if, we find the first token before the corresponding `(` (in this case
@@ -433,7 +439,10 @@
     // for - e.g. if the if is spread over several lines the given token itself
     // will - if formatted by the formatter - be indented more than the "if".
     if (token.isA(TokenType.OPEN_CURLY_BRACKET)) {
-      if (token.previous == null) return -1;
+      if (token.previous == null) {
+        // Coverage-ignore-block(suite): Not run.
+        return -1;
+      }
       Token previous = token.previous!;
       bool foundWanted = false;
       if (previous.isA(TokenType.CLOSE_PAREN)) {
@@ -477,6 +486,7 @@
     // Now find the line of [token].
     final int lineIndex = _getLineOf(token);
     if (lineIndex == 0) {
+      // Coverage-ignore-block(suite): Not run.
       // On first line.
       return tokens.next?.charOffset ?? -1;
     }
@@ -492,6 +502,7 @@
       return candidate.next!.offset - lineStartOfToken;
     }
 
+    // Coverage-ignore(suite): Not run.
     return -1;
   }
 
@@ -792,6 +803,7 @@
         case OPEN_PAREN_TOKEN:
           type = TokenType.CLOSE_PAREN;
           break;
+        // Coverage-ignore(suite): Not run.
         default:
           throw new StateError("Unexpected openKind");
       }
@@ -974,11 +986,8 @@
       while (next != $EOF) {
         next = bigSwitch(next);
       }
-      if (atEndOfFile()) {
-        appendEofToken();
-      } else {
-        unexpectedEof();
-      }
+      assert(atEndOfFile());
+      appendEofToken();
     }
 
     // Always pretend that there's a line at the end of the file.
@@ -1000,18 +1009,11 @@
         iterations++;
 
         if (iterations > 100) {
+          // Coverage-ignore-block(suite): Not run.
           return recoveryCount;
         }
       }
-      if (!atEndOfFile()) {
-        // $EOF in the middle of the file. Skip it as `tokenize`.
-        next = advance();
-        iterations++;
-
-        if (iterations > 100) {
-          return recoveryCount;
-        }
-      }
+      assert(atEndOfFile());
     }
     return recoveryCount;
   }
@@ -1193,11 +1195,15 @@
     }
 
     if (next == $BACKPING) {
+      // Coverage-ignore-block(suite): Not run.
+      // Hit when parsing doc comments in the analyzer.
       appendPrecedenceToken(TokenType.BACKPING);
       return advance();
     }
 
     if (next == $BACKSLASH) {
+      // Coverage-ignore-block(suite): Not run.
+      // Hit when parsing doc comments in the analyzer.
       appendPrecedenceToken(TokenType.BACKSLASH);
       return advance();
     }
@@ -1225,7 +1231,9 @@
           next = advance();
           if (next > 127) asciiOnly = false;
         } while (next != $LF && next != $CR && next != $EOF);
-        if (!asciiOnly) handleUnicode(start);
+        if (!asciiOnly) {
+          handleUnicode(start);
+        }
         appendSubstringToken(TokenType.SCRIPT_TAG, start, asciiOnly);
         return next;
       }
@@ -1288,6 +1296,7 @@
     next = advance();
     if (next == $BAR) {
       next = advance();
+      // Coverage-ignore(suite): Not run.
       if (LAZY_ASSIGNMENT_ENABLED && next == $EQ) {
         appendPrecedenceToken(TokenType.BAR_BAR_EQ);
         return advance();
@@ -1308,6 +1317,7 @@
     next = advance();
     if (next == $AMPERSAND) {
       next = advance();
+      // Coverage-ignore(suite): Not run.
       if (LAZY_ASSIGNMENT_ENABLED && next == $EQ) {
         appendPrecedenceToken(TokenType.AMPERSAND_AMPERSAND_EQ);
         return advance();
@@ -1625,25 +1635,16 @@
     }
   }
 
+  /// [next] has to be in [0-9eE].
   int tokenizeFractionPart(int next, int start, bool hasSeparators) {
+    assert(($0 <= next && next <= $9) || ($e == next || $E == next));
     bool done = false;
-    bool hasDigit = false;
     bool previousWasSeparator = false;
     LOOP:
     while (!done) {
       if ($0 <= next && next <= $9) {
-        hasDigit = true;
         previousWasSeparator = false;
       } else if ($_ == next) {
-        if (!hasDigit) {
-          prependErrorToken(
-            new UnterminatedToken(
-              messageUnexpectedSeparatorInNumber,
-              start,
-              stringOffset,
-            ),
-          );
-        }
         hasSeparators = true;
         previousWasSeparator = true;
       } else if ($e == next || $E == next) {
@@ -1657,7 +1658,6 @@
             ),
           );
         }
-        hasDigit = true;
         previousWasSeparator = false;
         next = advance();
         while (next == $_) {
@@ -1745,27 +1745,6 @@
       }
       next = advance();
     }
-    if (!hasDigit) {
-      // Reduce offset, we already advanced to the token past the period.
-      appendSubstringToken(
-        TokenType.INT,
-        start,
-        /* asciiOnly = */ true,
-        /* extraOffset = */ -1,
-      );
-
-      // TODO(ahe): Wrong offset for the period. Cannot call beginToken because
-      // the scanner already advanced past the period.
-      if ($PERIOD == next) {
-        return select(
-          $PERIOD,
-          TokenType.PERIOD_PERIOD_PERIOD,
-          TokenType.PERIOD_PERIOD,
-        );
-      }
-      appendPrecedenceToken(TokenType.PERIOD);
-      return next;
-    }
     TokenType tokenType =
         hasSeparators ? TokenType.DOUBLE_WITH_SEPARATORS : TokenType.DOUBLE;
     appendSubstringToken(tokenType, start, /* asciiOnly = */ true);
@@ -1934,7 +1913,9 @@
     bool dartdoc = $STAR == next;
     while (true) {
       if ($EOF == next) {
-        if (!asciiOnlyLines) handleUnicode(unicodeStart);
+        if (!asciiOnlyLines) {
+          handleUnicode(unicodeStart);
+        }
         prependErrorToken(
           new UnterminatedToken(
             messageUnterminatedComment,
@@ -2174,14 +2155,18 @@
       if (next == $BACKSLASH) {
         next = advance();
       } else if (next == $$) {
-        if (!asciiOnly) handleUnicode(start);
+        if (!asciiOnly) {
+          handleUnicode(start);
+        }
         next = tokenizeStringInterpolation(start, asciiOnly);
         start = scanOffset;
         asciiOnly = true;
         continue;
       }
       if (next <= $CR && (next == $LF || next == $CR || next == $EOF)) {
-        if (!asciiOnly) handleUnicode(start);
+        if (!asciiOnly) {
+          handleUnicode(start);
+        }
         unterminatedString(
           quoteChar,
           quoteStart,
@@ -2260,12 +2245,16 @@
     bool asciiOnly = true;
     while (next != $EOF) {
       if (next == quoteChar) {
-        if (!asciiOnly) handleUnicode(quoteStart);
+        if (!asciiOnly) {
+          handleUnicode(quoteStart);
+        }
         next = advance();
         appendSubstringToken(TokenType.STRING, quoteStart, asciiOnly);
         return next;
       } else if (next == $LF || next == $CR) {
-        if (!asciiOnly) handleUnicode(quoteStart);
+        if (!asciiOnly) {
+          handleUnicode(quoteStart);
+        }
         unterminatedString(
           quoteChar,
           quoteStart,
@@ -2280,7 +2269,9 @@
       }
       next = advance();
     }
-    if (!asciiOnly) handleUnicode(quoteStart);
+    if (!asciiOnly) {
+      handleUnicode(quoteStart);
+    }
     unterminatedString(
       quoteChar,
       quoteStart,
@@ -2319,14 +2310,18 @@
       if (next == quoteChar) {
         next = advance();
         if (next == quoteChar) {
-          if (!asciiOnlyLine) handleUnicode(unicodeStart);
+          if (!asciiOnlyLine) {
+            handleUnicode(unicodeStart);
+          }
           next = advance();
           appendSubstringToken(TokenType.STRING, quoteStart, asciiOnlyString);
           return next;
         }
       }
     }
-    if (!asciiOnlyLine) handleUnicode(unicodeStart);
+    if (!asciiOnlyLine) {
+      handleUnicode(unicodeStart);
+    }
     unterminatedString(
       quoteChar,
       quoteStart,
@@ -2339,7 +2334,9 @@
   }
 
   int tokenizeMultiLineString(int quoteChar, int quoteStart, bool raw) {
-    if (raw) return tokenizeMultiLineRawString(quoteChar, quoteStart);
+    if (raw) {
+      return tokenizeMultiLineRawString(quoteChar, quoteStart);
+    }
     int start = quoteStart;
     bool asciiOnlyString = true;
     bool asciiOnlyLine = true;
@@ -2347,7 +2344,9 @@
     int next = advance(); // Advance past the (last) quote (of three).
     while (next != $EOF) {
       if (next == $$) {
-        if (!asciiOnlyLine) handleUnicode(unicodeStart);
+        if (!asciiOnlyLine) {
+          handleUnicode(unicodeStart);
+        }
         next = tokenizeStringInterpolation(start, asciiOnlyString);
         start = scanOffset;
         unicodeStart = start;
@@ -2360,7 +2359,9 @@
         if (next == quoteChar) {
           next = advance();
           if (next == quoteChar) {
-            if (!asciiOnlyLine) handleUnicode(unicodeStart);
+            if (!asciiOnlyLine) {
+              handleUnicode(unicodeStart);
+            }
             next = advance();
             appendSubstringToken(TokenType.STRING, start, asciiOnlyString);
             return next;
@@ -2370,7 +2371,9 @@
       }
       if (next == $BACKSLASH) {
         next = advance();
-        if (next == $EOF) break;
+        if (next == $EOF) {
+          break;
+        }
       }
       if (next == $LF) {
         if (!asciiOnlyLine) {
@@ -2386,7 +2389,9 @@
       }
       next = advance();
     }
-    if (!asciiOnlyLine) handleUnicode(unicodeStart);
+    if (!asciiOnlyLine) {
+      handleUnicode(unicodeStart);
+    }
     unterminatedString(
       quoteChar,
       quoteStart,
@@ -2435,11 +2440,6 @@
     }
   }
 
-  void unexpectedEof() {
-    ErrorToken errorToken = buildUnexpectedCharacterToken($EOF, tokenStart);
-    prependErrorToken(errorToken);
-  }
-
   void unterminatedString(
     int quoteChar,
     int quoteStart,
@@ -2497,6 +2497,7 @@
   }
 
   @override
+  // Coverage-ignore(suite): Not run.
   void set length(int newLength) {
     if (newLength > array.length) {
       grow(newLength);
@@ -2505,6 +2506,7 @@
   }
 
   @override
+  // Coverage-ignore(suite): Not run.
   void operator []=(int index, int value) {
     if (value > 65535 && array is! Uint32List) {
       switchToUint32(array.length);
@@ -2518,7 +2520,10 @@
     if (arrayLength >= array.length) {
       grow(/* newLengthMinimum = */ 0);
     }
-    if (value > 65535 && array is! Uint32List) {
+    if (value > 65535 &&
+        // Coverage-ignore(suite): Not run.
+        array is! Uint32List) {
+      // Coverage-ignore-block(suite): Not run.
       switchToUint32(array.length);
     }
     array[arrayLength++] = value;
@@ -2535,10 +2540,12 @@
       newArray.setRange(/* start = */ 0, arrayLength, array);
       array = newArray;
     } else {
+      // Coverage-ignore-block(suite): Not run.
       switchToUint32(newLength);
     }
   }
 
+  // Coverage-ignore(suite): Not run.
   void switchToUint32(int newLength) {
     final Uint32List newArray = new Uint32List(newLength);
     newArray.setRange(/* start = */ 0, arrayLength, array);
@@ -2550,6 +2557,7 @@
     final int expectedNumberOfLines = 1 + (numberOfBytesHint ~/ 22);
 
     if (numberOfBytesHint > 65535) {
+      // Coverage-ignore-block(suite): Not run.
       return new Uint32List(expectedNumberOfLines);
     } else {
       return new Uint16List(expectedNumberOfLines);
diff --git a/pkg/front_end/lib/src/util/parser_ast.dart b/pkg/front_end/lib/src/util/parser_ast.dart
index eeb0c74..1ab7fcb 100644
--- a/pkg/front_end/lib/src/util/parser_ast.dart
+++ b/pkg/front_end/lib/src/util/parser_ast.dart
@@ -57,7 +57,6 @@
   ParserASTListener listener = new ParserASTListener();
   Parser parser;
   if (includeBody) {
-    // Coverage-ignore-block(suite): Not run.
     parser = new Parser(
       listener,
       useImplicitCreationExpression: useImplicitCreationExpressionInCfe,
@@ -1027,7 +1026,6 @@
   }
 }
 
-// Coverage-ignore(suite): Not run.
 extension TopLevelDeclarationExtension on TopLevelDeclarationEnd {
   IdentifierHandle getIdentifier() {
     for (ParserAstNode child in children!) {
@@ -1036,6 +1034,7 @@
     throw "Not found.";
   }
 
+  // Coverage-ignore(suite): Not run.
   ClassDeclarationEnd getClassDeclaration() {
     if (!isClass()) {
       throw "Not a class";
@@ -1076,8 +1075,8 @@
   }
 }
 
-// Coverage-ignore(suite): Not run.
 extension ClassDeclarationExtension on ClassDeclarationEnd {
+  // Coverage-ignore(suite): Not run.
   ClassOrMixinOrExtensionBodyEnd getClassOrMixinOrExtensionBody() {
     for (ParserAstNode child in children!) {
       if (child is ClassOrMixinOrExtensionBodyEnd) {
@@ -1087,6 +1086,7 @@
     throw "Not found.";
   }
 
+  // Coverage-ignore(suite): Not run.
   ClassExtendsHandle getClassExtends() {
     for (ParserAstNode child in children!) {
       if (child is ClassExtendsHandle) return child;
@@ -1094,6 +1094,7 @@
     throw "Not found.";
   }
 
+  // Coverage-ignore(suite): Not run.
   ImplementsHandle getClassImplements() {
     for (ParserAstNode child in children!) {
       if (child is ImplementsHandle) {
@@ -1103,6 +1104,7 @@
     throw "Not found.";
   }
 
+  // Coverage-ignore(suite): Not run.
   ClassWithClauseHandle? getClassWithClause() {
     for (ParserAstNode child in children!) {
       if (child is ClassWithClauseHandle) {
@@ -1630,7 +1632,6 @@
   }
 }
 
-// Coverage-ignore(suite): Not run.
 extension TopLevelMethodExtension on TopLevelMethodEnd {
   IdentifierHandle getNameIdentifier() {
     for (ParserAstNode child in children!) {
@@ -1643,6 +1644,7 @@
     throw "Didn't find the name identifier!";
   }
 
+  // Coverage-ignore(suite): Not run.
   Token getNameIdentifierToken() {
     return getNameIdentifier().token;
   }
@@ -1838,7 +1840,6 @@
   }
 }
 
-// Coverage-ignore(suite): Not run.
 bool _isTypeOrNoType(ParserAstNode node) {
   return node is TypeHandle ||
       node is RecordTypeEnd ||
@@ -1847,8 +1848,8 @@
       node is FunctionTypeEnd;
 }
 
-// Coverage-ignore(suite): Not run.
 extension ClassMethodExtension on ClassMethodEnd {
+  // Coverage-ignore(suite): Not run.
   BlockFunctionBodyEnd? getBlockFunctionBody() {
     for (ParserAstNode child in children!) {
       if (child is BlockFunctionBodyEnd) {
@@ -1867,9 +1868,11 @@
       if (foundType && child is IdentifierHandle) {
         return child.token;
       } else if (foundType && child is OperatorNameHandle) {
+        // Coverage-ignore-block(suite): Not run.
         return child.token;
       }
     }
+    // Coverage-ignore-block(suite): Not run.
     throw "No identifier found: $children";
   }
 
@@ -2288,9 +2291,7 @@
                 end == "EnumFields")) {
           // beginFields is ended by one of endTopLevelFields, endMixinFields,
           // endEnumFields or endExtensionFields.
-        } else if (begin == "ForStatement" &&
-            // Coverage-ignore(suite): Not run.
-            end == "ForIn") {
+        } else if (begin == "ForStatement" && end == "ForIn") {
           // beginForStatement is ended by either endForStatement or endForIn.
         } else if (begin == "FactoryMethod" &&
             (end == "ClassFactoryMethod" ||
@@ -2301,9 +2302,7 @@
           // beginFactoryMethod is ended by either endClassFactoryMethod,
           // endMixinFactoryMethod, endExtensionFactoryMethod, or
           // endEnumFactoryMethod.
-        }
-        // Coverage-ignore(suite): Not run.
-        else if (begin == "ForControlFlow" && (end == "ForInControlFlow")) {
+        } else if (begin == "ForControlFlow" && (end == "ForInControlFlow")) {
           // beginForControlFlow is ended by either endForControlFlow or
           // endForInControlFlow.
         } else if (begin == "IfControlFlow" && (end == "IfElseControlFlow")) {
@@ -2322,6 +2321,7 @@
           // beginParenthesizedExpressionOrRecordLiteral is ended by either
           // endParenthesizedExpression or endRecordLiteral.
         } else {
+          // Coverage-ignore-block(suite): Not run.
           throw "Unknown combination: begin$begin and end$end";
         }
         List<ParserAstNode> children = data.sublist(beginIndex);
diff --git a/pkg/front_end/parser_testcases/coverage/at_dart.dart b/pkg/front_end/parser_testcases/coverage/at_dart.dart
new file mode 100644
index 0000000..972d9ad
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/at_dart.dart
@@ -0,0 +1,14 @@
+//@
+//@d
+//@da
+//@dar
+//@dart
+//@dart=
+//@dart=a
+//@dart=3
+//@dart=3.
+//@dart=3.1
+//@dart=3.a
+//@dart=a.b
+//@dart=3.1  
+//@dart=3.1  hello
diff --git a/pkg/front_end/parser_testcases/coverage/at_dart.dart.expect b/pkg/front_end/parser_testcases/coverage/at_dart.dart.expect
new file mode 100644
index 0000000..48410be
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/at_dart.dart.expect
@@ -0,0 +1,2 @@
+beginCompilationUnit()
+endCompilationUnit(0, )
diff --git a/pkg/front_end/parser_testcases/coverage/at_dart.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/at_dart.dart.intertwined.expect
new file mode 100644
index 0000000..b518dc4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/at_dart.dart.intertwined.expect
@@ -0,0 +1,6 @@
+parseUnit()
+  skipErrorTokens()
+  listener: beginCompilationUnit()
+  syntheticPreviousToken()
+  reportAllErrorTokens()
+  listener: endCompilationUnit(0, )
diff --git a/pkg/front_end/parser_testcases/coverage/at_dart.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/at_dart.dart.parser.expect
new file mode 100644
index 0000000..aa3f60b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/at_dart.dart.parser.expect
@@ -0,0 +1 @@
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/at_dart.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/at_dart.dart.scanner.expect
new file mode 100644
index 0000000..aa3f60b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/at_dart.dart.scanner.expect
@@ -0,0 +1 @@
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/bar_eq.dart b/pkg/front_end/parser_testcases/coverage/bar_eq.dart
new file mode 100644
index 0000000..a0d0241
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/bar_eq.dart
@@ -0,0 +1,3 @@
+void foo(dynamic bar) {
+  bar |= 2;
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/bar_eq.dart.expect b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.expect
new file mode 100644
index 0000000..83ab598
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.expect
@@ -0,0 +1,32 @@
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(dynamic)
+        endMetadataStar(0)
+        beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(dynamic, typeReference)
+          handleNoTypeArguments(bar)
+          handleType(dynamic, null)
+          handleIdentifier(bar, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(bar, expression)
+        handleNoTypeArguments(|=)
+        handleNoArguments(|=)
+        handleSend(bar, bar)
+        handleLiteralInt(2)
+        handleAssignmentExpression(|=, 2)
+        handleExpressionStatement(bar, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/bar_eq.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.intertwined.expect
new file mode 100644
index 0000000..2625712
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.intertwined.expect
@@ -0,0 +1,72 @@
+parseUnit(void)
+  skipErrorTokens(void)
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(, DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar()
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(, null, null, , VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(dynamic)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(dynamic, typeReference)
+                listener: handleNoTypeArguments(bar)
+                listener: handleType(dynamic, null)
+                ensureIdentifier(dynamic, formalParameterDeclaration)
+                  listener: handleIdentifier(bar, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, bar)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null)
+                looksLikeLocalFunction(bar)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true, ConstantPatternContext.none)
+                      parseUnaryExpression({, true, ConstantPatternContext.none)
+                        parsePrimary({, expression, ConstantPatternContext.none)
+                          parseSendOrFunctionLiteral({, expression, ConstantPatternContext.none)
+                            parseSend({, expression, ConstantPatternContext.none)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(bar, expression)
+                              listener: handleNoTypeArguments(|=)
+                              parseArgumentsOpt(bar)
+                                listener: handleNoArguments(|=)
+                              listener: handleSend(bar, bar)
+                      parsePrecedenceExpression(|=, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(|=, true, ConstantPatternContext.none)
+                          parsePrimary(|=, expression, ConstantPatternContext.none)
+                            parseLiteralInt(|=)
+                              listener: handleLiteralInt(2)
+                      listener: handleAssignmentExpression(|=, 2)
+                  ensureSemicolon(2)
+                  listener: handleExpressionStatement(bar, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(void)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/bar_eq.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.parser.expect
new file mode 100644
index 0000000..c94152e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.parser.expect
@@ -0,0 +1,7 @@
+void foo(dynamic bar) {
+bar |= 2;
+}
+
+void[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+bar[StringToken] |=[SimpleToken] 2[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/bar_eq.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.scanner.expect
new file mode 100644
index 0000000..c94152e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/bar_eq.dart.scanner.expect
@@ -0,0 +1,7 @@
+void foo(dynamic bar) {
+bar |= 2;
+}
+
+void[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+bar[StringToken] |=[SimpleToken] 2[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/comments.dart b/pkg/front_end/parser_testcases/coverage/comments.dart
new file mode 100644
index 0000000..39c16a0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/comments.dart
@@ -0,0 +1 @@
+/*æbler
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/comments.dart.expect b/pkg/front_end/parser_testcases/coverage/comments.dart.expect
new file mode 100644
index 0000000..734d82f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/comments.dart.expect
@@ -0,0 +1,10 @@
+Problems reported:
+
+parser/coverage/comments:1:1: Comment starting with '/*' must end with '*/'.
+/*æbler
+^
+
+beginCompilationUnit()
+  handleErrorToken(UnterminatedToken(UnterminatedComment))
+  handleRecoverableError(UnterminatedComment, UnterminatedToken(UnterminatedComment), UnterminatedToken(UnterminatedComment))
+endCompilationUnit(0, )
diff --git a/pkg/front_end/parser_testcases/coverage/comments.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/comments.dart.intertwined.expect
new file mode 100644
index 0000000..f2ca6b7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/comments.dart.intertwined.expect
@@ -0,0 +1,8 @@
+parseUnit(UnterminatedToken(UnterminatedComment))
+  skipErrorTokens(UnterminatedToken(UnterminatedComment))
+  listener: beginCompilationUnit()
+  syntheticPreviousToken()
+  reportAllErrorTokens(UnterminatedToken(UnterminatedComment))
+    listener: handleErrorToken(UnterminatedToken(UnterminatedComment))
+    listener: handleRecoverableError(UnterminatedComment, UnterminatedToken(UnterminatedComment), UnterminatedToken(UnterminatedComment))
+  listener: endCompilationUnit(0, )
diff --git a/pkg/front_end/parser_testcases/coverage/comments.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/comments.dart.parser.expect
new file mode 100644
index 0000000..3578717
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/comments.dart.parser.expect
@@ -0,0 +1 @@
+[UnterminatedToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/comments.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/comments.dart.scanner.expect
new file mode 100644
index 0000000..3578717
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/comments.dart.scanner.expect
@@ -0,0 +1 @@
+[UnterminatedToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart
new file mode 100644
index 0000000..3561cd9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart
@@ -0,0 +1,2 @@
+void foo() {
+  print("${(
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.expect b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.expect
new file mode 100644
index 0000000..61458fb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.expect
@@ -0,0 +1,68 @@
+Problems reported:
+
+parser/coverage/interpolated_eof:2:13: Expected ';' after this.
+  print("${(
+            ^...
+
+WARNING: Reporting at eof --- see below for details.
+
+parser/coverage/interpolated_eof:2:12: Can't find ')' to match '('.
+  print("${(
+           ^
+
+parser/coverage/interpolated_eof:2:10: Can't find '}' to match '${'.
+  print("${(
+         ^
+
+parser/coverage/interpolated_eof:2:9: String starting with " must end with ".
+  print("${(
+        ^^^^
+
+parser/coverage/interpolated_eof:2:8: Can't find ')' to match '('.
+  print("${(
+       ^
+
+parser/coverage/interpolated_eof:1:12: Can't find '}' to match '{'.
+void foo() {
+           ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(UnmatchedToken({), null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(print, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          beginLiteralString(")
+            beginParenthesizedExpressionOrRecordLiteral(()
+            endRecordLiteral((, 0, null)
+            handleInterpolationExpression(${, })
+            handleStringPart(")
+          endLiteralString(1, ))
+        endArguments(1, (, ))
+        handleSend(print, ))
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], , )
+        // WARNING: Reporting at eof for .
+        handleExpressionStatement(print, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnmatchedToken(())
+  handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+  handleErrorToken(UnmatchedToken(${))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '${'., null, {string: }, lexeme: ${}], UnmatchedToken(${), UnmatchedToken(${))
+  handleErrorToken(UnterminatedString("))
+  handleRecoverableError(Message[UnterminatedString, String starting with " must end with "., null, {string: ", string2: "}], UnterminatedString("), UnterminatedString("))
+  handleErrorToken(UnmatchedToken(())
+  handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+  handleErrorToken(UnmatchedToken({))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.intertwined.expect
new file mode 100644
index 0000000..2e45a95
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.intertwined.expect
@@ -0,0 +1,92 @@
+parseUnit(UnmatchedToken(())
+  skipErrorTokens(UnmatchedToken(())
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnmatchedToken({))
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken({))
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(UnmatchedToken({), null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, print)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true, ConstantPatternContext.none)
+                      parseUnaryExpression({, true, ConstantPatternContext.none)
+                        parsePrimary({, expression, ConstantPatternContext.none)
+                          parseSendOrFunctionLiteral({, expression, ConstantPatternContext.none)
+                            looksLikeFunctionBody(})
+                            parseSend({, expression, ConstantPatternContext.none)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true, ConstantPatternContext.none)
+                                        parseUnaryExpression((, true, ConstantPatternContext.none)
+                                          parsePrimary((, expression, ConstantPatternContext.none)
+                                            parseLiteralString(()
+                                              parseSingleLiteralString(()
+                                                listener: beginLiteralString(")
+                                                parseExpression(${)
+                                                  parsePrecedenceExpression(${, 1, true, ConstantPatternContext.none)
+                                                    parseUnaryExpression(${, true, ConstantPatternContext.none)
+                                                      parsePrimary(${, expression, ConstantPatternContext.none)
+                                                        parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(${, ConstantPatternContext.none)
+                                                          parseParenthesizedExpressionOrRecordLiteral(${, null, ConstantPatternContext.none)
+                                                            listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                                            ensureCloseParen((, ()
+                                                            listener: endRecordLiteral((, 0, null)
+                                                listener: handleInterpolationExpression(${, })
+                                                parseStringPart(})
+                                                  listener: handleStringPart(")
+                                                listener: endLiteralString(1, ))
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ))
+                  ensureSemicolon())
+                    reportRecoverableError(", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], , )
+                      listener: // WARNING: Reporting at eof for .
+                    rewriter()
+                  listener: handleExpressionStatement(print, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnmatchedToken(())
+    listener: handleErrorToken(UnmatchedToken(())
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+    listener: handleErrorToken(UnmatchedToken(${))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '${'., null, {string: }, lexeme: ${}], UnmatchedToken(${), UnmatchedToken(${))
+    listener: handleErrorToken(UnterminatedString("))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with " must end with "., null, {string: ", string2: "}], UnterminatedString("), UnterminatedString("))
+    listener: handleErrorToken(UnmatchedToken(())
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+    listener: handleErrorToken(UnmatchedToken({))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.parser.expect
new file mode 100644
index 0000000..3e01b72
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.parser.expect
@@ -0,0 +1,7 @@
+NOTICE: Stream was rewritten by parser!
+
+void foo() {
+print("${()}");}
+
+[UnmatchedToken][UnmatchedToken][UnterminatedString][UnmatchedToken][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]"[StringToken]${[BeginToken]([BeginToken])[SyntheticToken]}[SyntheticToken]"[SyntheticStringToken])[SyntheticToken];[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.scanner.expect
new file mode 100644
index 0000000..d7dec63
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/interpolated_eof.dart.scanner.expect
@@ -0,0 +1,5 @@
+void foo() {
+print("${()}")}
+
+[UnmatchedToken][UnmatchedToken][UnterminatedString][UnmatchedToken][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]"[StringToken]${[BeginToken]([BeginToken])[SyntheticToken]}[SyntheticToken]"[SyntheticStringToken])[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/numbers.dart b/pkg/front_end/parser_testcases/coverage/numbers.dart
new file mode 100644
index 0000000..b612537
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/numbers.dart
@@ -0,0 +1,18 @@
+void foo() {
+  12_e;
+  12_E;
+  12_.;
+  12_;
+  0x_;
+  0xA_;
+  .1;
+  1.2_;
+  1.2_e;
+  1.2_E;
+  1.2e_;
+  1.2E_;
+  1.2e-_;
+  1.2E-_;
+  1.2e-1_;
+  1.2E-1_;
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/numbers.dart.expect b/pkg/front_end/parser_testcases/coverage/numbers.dart.expect
new file mode 100644
index 0000000..85eabae
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/numbers.dart.expect
@@ -0,0 +1,204 @@
+Problems reported:
+
+parser/coverage/numbers:4:7: Expected an identifier, but got ';'.
+  12_.;
+      ^
+
+parser/coverage/numbers:2:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  12_e;
+  ^
+
+parser/coverage/numbers:2:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  12_e;
+  ^
+
+parser/coverage/numbers:3:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  12_E;
+  ^
+
+parser/coverage/numbers:3:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  12_E;
+  ^
+
+parser/coverage/numbers:4:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  12_.;
+  ^
+
+parser/coverage/numbers:5:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  12_;
+  ^
+
+parser/coverage/numbers:6:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  0x_;
+  ^
+
+parser/coverage/numbers:6:3: A hex digit (0-9 or A-F) must follow '0x'.
+  0x_;
+  ^
+
+parser/coverage/numbers:7:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  0xA_;
+  ^
+
+parser/coverage/numbers:9:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2_;
+  ^
+
+parser/coverage/numbers:10:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2_e;
+  ^
+
+parser/coverage/numbers:10:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2_e;
+  ^
+
+parser/coverage/numbers:11:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2_E;
+  ^
+
+parser/coverage/numbers:11:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2_E;
+  ^
+
+parser/coverage/numbers:12:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2e_;
+  ^
+
+parser/coverage/numbers:12:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2e_;
+  ^
+
+parser/coverage/numbers:13:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2E_;
+  ^
+
+parser/coverage/numbers:13:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2E_;
+  ^
+
+parser/coverage/numbers:14:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2e-_;
+  ^
+
+parser/coverage/numbers:14:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2e-_;
+  ^
+
+parser/coverage/numbers:15:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2E-_;
+  ^
+
+parser/coverage/numbers:15:3: Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+  1.2E-_;
+  ^
+
+parser/coverage/numbers:16:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2e-1_;
+  ^
+
+parser/coverage/numbers:17:3: Digit separators ('_') in a number literal can only be placed between two digits.
+  1.2E-1_;
+  ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(UnterminatedToken(UnexpectedSeparatorInNumber), null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleLiteralDoubleWithSeparators(12_e0)
+        handleExpressionStatement(12_e0, ;)
+        handleLiteralDoubleWithSeparators(12_E0)
+        handleExpressionStatement(12_E0, ;)
+        handleLiteralIntWithSeparators(12_)
+        handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ';'., Try inserting an identifier before ';'., {lexeme: ;}], ;, ;)
+        handleIdentifier(, expressionContinuation)
+        handleNoTypeArguments(;)
+        handleNoArguments(;)
+        handleSend(, )
+        handleEndingBinaryExpression(., )
+        handleExpressionStatement(12_, ;)
+        handleLiteralIntWithSeparators(12_)
+        handleExpressionStatement(12_, ;)
+        handleLiteralInt(0x_0)
+        handleExpressionStatement(0x_0, ;)
+        handleLiteralIntWithSeparators(0xA_)
+        handleExpressionStatement(0xA_, ;)
+        handleLiteralDouble(.1)
+        handleExpressionStatement(.1, ;)
+        handleLiteralDoubleWithSeparators(1.2_)
+        handleExpressionStatement(1.2_, ;)
+        handleLiteralDoubleWithSeparators(1.2_e0)
+        handleExpressionStatement(1.2_e0, ;)
+        handleLiteralDoubleWithSeparators(1.2_E0)
+        handleExpressionStatement(1.2_E0, ;)
+        handleLiteralDoubleWithSeparators(1.2e_0)
+        handleExpressionStatement(1.2e_0, ;)
+        handleLiteralDoubleWithSeparators(1.2E_0)
+        handleExpressionStatement(1.2E_0, ;)
+        handleLiteralDoubleWithSeparators(1.2e-_0)
+        handleExpressionStatement(1.2e-_0, ;)
+        handleLiteralDoubleWithSeparators(1.2E-_0)
+        handleExpressionStatement(1.2E-_0, ;)
+        handleLiteralDoubleWithSeparators(1.2e-1_)
+        handleExpressionStatement(1.2e-1_, ;)
+        handleLiteralDoubleWithSeparators(1.2E-1_)
+        handleExpressionStatement(1.2E-1_, ;)
+      endBlockFunctionBody(16, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(ExpectedHexDigit))
+  handleRecoverableError(ExpectedHexDigit, UnterminatedToken(ExpectedHexDigit), UnterminatedToken(ExpectedHexDigit))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(MissingExponent))
+  handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+  handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/numbers.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/numbers.dart.intertwined.expect
new file mode 100644
index 0000000..7bfa8bc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/numbers.dart.intertwined.expect
@@ -0,0 +1,334 @@
+parseUnit(UnterminatedToken(UnexpectedSeparatorInNumber))
+  skipErrorTokens(UnterminatedToken(UnexpectedSeparatorInNumber))
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(UnterminatedToken(UnexpectedSeparatorInNumber), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnterminatedToken(UnexpectedSeparatorInNumber))
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnterminatedToken(UnexpectedSeparatorInNumber))
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(UnterminatedToken(UnexpectedSeparatorInNumber), null, null, UnterminatedToken(UnexpectedSeparatorInNumber), VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(UnterminatedToken(UnexpectedSeparatorInNumber), null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, 12_e0)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, null)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null)
+                  looksLikeLocalFunction(12_e0)
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression({, true, ConstantPatternContext.none)
+                          parsePrimary({, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators({)
+                              listener: handleLiteralDoubleWithSeparators(12_e0)
+                    ensureSemicolon(12_e0)
+                    listener: handleExpressionStatement(12_e0, ;)
+          notEofOrValue(}, 12_E0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(12_E0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(12_E0)
+                    ensureSemicolon(12_E0)
+                    listener: handleExpressionStatement(12_E0, ;)
+          notEofOrValue(}, 12_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(12_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralIntWithSeparators(;)
+                              listener: handleLiteralIntWithSeparators(12_)
+                        parsePrimary(., expressionContinuation, ConstantPatternContext.none)
+                          parseSend(., expressionContinuation, ConstantPatternContext.none)
+                            isNextIdentifier(.)
+                            ensureIdentifier(., expressionContinuation)
+                              reportRecoverableErrorWithToken(;, Template(ExpectedIdentifier))
+                                listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ';'., Try inserting an identifier before ';'., {lexeme: ;}], ;, ;)
+                              rewriter()
+                              listener: handleIdentifier(, expressionContinuation)
+                            listener: handleNoTypeArguments(;)
+                            parseArgumentsOpt()
+                              listener: handleNoArguments(;)
+                            listener: handleSend(, )
+                        listener: handleEndingBinaryExpression(., )
+                    ensureSemicolon()
+                    listener: handleExpressionStatement(12_, ;)
+          notEofOrValue(}, 12_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(12_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralIntWithSeparators(;)
+                              listener: handleLiteralIntWithSeparators(12_)
+                    ensureSemicolon(12_)
+                    listener: handleExpressionStatement(12_, ;)
+          notEofOrValue(}, 0x_0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(0x_0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralInt(;)
+                              listener: handleLiteralInt(0x_0)
+                    ensureSemicolon(0x_0)
+                    listener: handleExpressionStatement(0x_0, ;)
+          notEofOrValue(}, 0xA_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(0xA_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralIntWithSeparators(;)
+                              listener: handleLiteralIntWithSeparators(0xA_)
+                    ensureSemicolon(0xA_)
+                    listener: handleExpressionStatement(0xA_, ;)
+          notEofOrValue(}, .1)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(.1)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDouble(;)
+                              listener: handleLiteralDouble(.1)
+                    ensureSemicolon(.1)
+                    listener: handleExpressionStatement(.1, ;)
+          notEofOrValue(}, 1.2_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2_)
+                    ensureSemicolon(1.2_)
+                    listener: handleExpressionStatement(1.2_, ;)
+          notEofOrValue(}, 1.2_e0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2_e0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2_e0)
+                    ensureSemicolon(1.2_e0)
+                    listener: handleExpressionStatement(1.2_e0, ;)
+          notEofOrValue(}, 1.2_E0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2_E0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2_E0)
+                    ensureSemicolon(1.2_E0)
+                    listener: handleExpressionStatement(1.2_E0, ;)
+          notEofOrValue(}, 1.2e_0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2e_0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2e_0)
+                    ensureSemicolon(1.2e_0)
+                    listener: handleExpressionStatement(1.2e_0, ;)
+          notEofOrValue(}, 1.2E_0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2E_0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2E_0)
+                    ensureSemicolon(1.2E_0)
+                    listener: handleExpressionStatement(1.2E_0, ;)
+          notEofOrValue(}, 1.2e-_0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2e-_0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2e-_0)
+                    ensureSemicolon(1.2e-_0)
+                    listener: handleExpressionStatement(1.2e-_0, ;)
+          notEofOrValue(}, 1.2E-_0)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2E-_0)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2E-_0)
+                    ensureSemicolon(1.2E-_0)
+                    listener: handleExpressionStatement(1.2E-_0, ;)
+          notEofOrValue(}, 1.2e-1_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2e-1_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2e-1_)
+                    ensureSemicolon(1.2e-1_)
+                    listener: handleExpressionStatement(1.2e-1_, ;)
+          notEofOrValue(}, 1.2E-1_)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, null)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
+                  looksLikeLocalFunction(1.2E-1_)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
+                        parseUnaryExpression(;, true, ConstantPatternContext.none)
+                          parsePrimary(;, expression, ConstantPatternContext.none)
+                            parseLiteralDoubleWithSeparators(;)
+                              listener: handleLiteralDoubleWithSeparators(1.2E-1_)
+                    ensureSemicolon(1.2E-1_)
+                    listener: handleExpressionStatement(1.2E-1_, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(16, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(ExpectedHexDigit))
+    listener: handleRecoverableError(ExpectedHexDigit, UnterminatedToken(ExpectedHexDigit), UnterminatedToken(ExpectedHexDigit))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(MissingExponent))
+    listener: handleRecoverableError(MissingExponent, UnterminatedToken(MissingExponent), UnterminatedToken(MissingExponent))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedSeparatorInNumber))
+    listener: handleRecoverableError(UnexpectedSeparatorInNumber, UnterminatedToken(UnexpectedSeparatorInNumber), UnterminatedToken(UnexpectedSeparatorInNumber))
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/numbers.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/numbers.dart.parser.expect
new file mode 100644
index 0000000..c38266d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/numbers.dart.parser.expect
@@ -0,0 +1,54 @@
+NOTICE: Stream was rewritten by parser!
+
+void foo() {
+12_e0;
+12_E0;
+12_.*synthetic*;
+12_;
+0x_0;
+0xA_;
+.1;
+1.2_;
+1.2_e0;
+1.2_E0;
+1.2e_0;
+1.2E_0;
+1.2e-_0;
+1.2E-_0;
+1.2e-1_;
+1.2E-1_;
+}
+
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+
+[UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+12_e0[SyntheticStringToken];[SimpleToken]
+12_E0[SyntheticStringToken];[SimpleToken]
+12_[StringToken].[SimpleToken][SyntheticStringToken];[SimpleToken]
+12_[StringToken];[SimpleToken]
+0x_0[SyntheticStringToken];[SimpleToken]
+0xA_[StringToken];[SimpleToken]
+.1[StringToken];[SimpleToken]
+1.2_[StringToken];[SimpleToken]
+1.2_e0[SyntheticStringToken];[SimpleToken]
+1.2_E0[SyntheticStringToken];[SimpleToken]
+1.2e_0[SyntheticStringToken];[SimpleToken]
+1.2E_0[SyntheticStringToken];[SimpleToken]
+1.2e-_0[SyntheticStringToken];[SimpleToken]
+1.2E-_0[SyntheticStringToken];[SimpleToken]
+1.2e-1_[StringToken];[SimpleToken]
+1.2E-1_[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/numbers.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/numbers.dart.scanner.expect
new file mode 100644
index 0000000..3eaf6b9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/numbers.dart.scanner.expect
@@ -0,0 +1,52 @@
+void foo() {
+12_e0;
+12_E0;
+12_.;
+12_;
+0x_0;
+0xA_;
+.1;
+1.2_;
+1.2_e0;
+1.2_E0;
+1.2e_0;
+1.2E_0;
+1.2e-_0;
+1.2E-_0;
+1.2e-1_;
+1.2E-1_;
+}
+
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+
+[UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken][UnterminatedToken]
+[UnterminatedToken]
+[UnterminatedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+12_e0[SyntheticStringToken];[SimpleToken]
+12_E0[SyntheticStringToken];[SimpleToken]
+12_[StringToken].[SimpleToken];[SimpleToken]
+12_[StringToken];[SimpleToken]
+0x_0[SyntheticStringToken];[SimpleToken]
+0xA_[StringToken];[SimpleToken]
+.1[StringToken];[SimpleToken]
+1.2_[StringToken];[SimpleToken]
+1.2_e0[SyntheticStringToken];[SimpleToken]
+1.2_E0[SyntheticStringToken];[SimpleToken]
+1.2e_0[SyntheticStringToken];[SimpleToken]
+1.2E_0[SyntheticStringToken];[SimpleToken]
+1.2e-_0[SyntheticStringToken];[SimpleToken]
+1.2E-_0[SyntheticStringToken];[SimpleToken]
+1.2e-1_[StringToken];[SimpleToken]
+1.2E-1_[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/slash_eq.dart b/pkg/front_end/parser_testcases/coverage/slash_eq.dart
new file mode 100644
index 0000000..2f8e291
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/slash_eq.dart
@@ -0,0 +1,3 @@
+dynamic foo(dynamic bar) {
+  return bar /= 2;
+}
diff --git a/pkg/front_end/parser_testcases/coverage/slash_eq.dart.expect b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.expect
new file mode 100644
index 0000000..18d5b64
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.expect
@@ -0,0 +1,35 @@
+beginCompilationUnit(dynamic)
+  beginMetadataStar(dynamic)
+  endMetadataStar(0)
+  beginTopLevelMember(dynamic)
+    beginTopLevelMethod(, null, null)
+      handleIdentifier(dynamic, typeReference)
+      handleNoTypeArguments(foo)
+      handleType(dynamic, null)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(dynamic)
+        endMetadataStar(0)
+        beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(dynamic, typeReference)
+          handleNoTypeArguments(bar)
+          handleType(dynamic, null)
+          handleIdentifier(bar, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          handleIdentifier(bar, expression)
+          handleNoTypeArguments(/=)
+          handleNoArguments(/=)
+          handleSend(bar, bar)
+          handleLiteralInt(2)
+          handleAssignmentExpression(/=, 2)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(dynamic, null, })
+  endTopLevelDeclaration(})
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/slash_eq.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.intertwined.expect
new file mode 100644
index 0000000..6b1c40a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.intertwined.expect
@@ -0,0 +1,74 @@
+parseUnit(dynamic)
+  skipErrorTokens(dynamic)
+  listener: beginCompilationUnit(dynamic)
+  syntheticPreviousToken(dynamic)
+  parseTopLevelDeclarationImpl(, DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar()
+      listener: beginMetadataStar(dynamic)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(dynamic)
+      parseTopLevelMethod(, null, null, , SimpleType(), null, foo, false)
+        listener: beginTopLevelMethod(, null, null)
+        listener: handleIdentifier(dynamic, typeReference)
+        listener: handleNoTypeArguments(foo)
+        listener: handleType(dynamic, null)
+        ensureIdentifierPotentiallyRecovered(dynamic, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(dynamic)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(dynamic, typeReference)
+                listener: handleNoTypeArguments(bar)
+                listener: handleType(dynamic, null)
+                ensureIdentifier(dynamic, formalParameterDeclaration)
+                  listener: handleIdentifier(bar, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseSendOrFunctionLiteral(return, expression, ConstantPatternContext.none)
+                          parseSend(return, expression, ConstantPatternContext.none)
+                            isNextIdentifier(return)
+                            ensureIdentifier(return, expression)
+                              listener: handleIdentifier(bar, expression)
+                            listener: handleNoTypeArguments(/=)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(/=)
+                            listener: handleSend(bar, bar)
+                    parsePrecedenceExpression(/=, 1, true, ConstantPatternContext.none)
+                      parseUnaryExpression(/=, true, ConstantPatternContext.none)
+                        parsePrimary(/=, expression, ConstantPatternContext.none)
+                          parseLiteralInt(/=)
+                            listener: handleLiteralInt(2)
+                    listener: handleAssignmentExpression(/=, 2)
+                ensureSemicolon(2)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(dynamic, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(dynamic)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/slash_eq.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.parser.expect
new file mode 100644
index 0000000..5c7236e7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.parser.expect
@@ -0,0 +1,9 @@
+dynamic foo(dynamic bar) {
+return bar /= 2;
+}
+
+
+dynamic[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] bar[StringToken] /=[SimpleToken] 2[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/slash_eq.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.scanner.expect
new file mode 100644
index 0000000..5c7236e7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/slash_eq.dart.scanner.expect
@@ -0,0 +1,9 @@
+dynamic foo(dynamic bar) {
+return bar /= 2;
+}
+
+
+dynamic[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] bar[StringToken] /=[SimpleToken] 2[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string1.dart b/pkg/front_end/parser_testcases/coverage/string1.dart
new file mode 100644
index 0000000..bcaa924
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string1.dart
@@ -0,0 +1,23 @@
+String foo(dynamic bar) {
+  return "æble $bar";
+}
+
+String bar() {
+  return "æble
+}
+
+String baz() {
+  return "$1"
+}
+
+String qux() {
+  return r"æble$"
+}
+
+String quux() {
+  return r"æble$
+}
+
+String corge() {
+  // Ends in eof.
+  return r"æble
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/string1.dart.expect b/pkg/front_end/parser_testcases/coverage/string1.dart.expect
new file mode 100644
index 0000000..ef05571
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string1.dart.expect
@@ -0,0 +1,200 @@
+Problems reported:
+
+parser/coverage/string1:6:10: Expected ';' after this.
+  return "æble
+         ^^^^^
+
+parser/coverage/string1:10:12: Expected ';' after this.
+  return "$1"
+           ^^
+
+parser/coverage/string1:14:10: Expected ';' after this.
+  return r"æble$"
+         ^^^^^^^^
+
+parser/coverage/string1:18:10: Expected ';' after this.
+  return r"æble$
+         ^^^^^^^
+
+parser/coverage/string1:23:10: Expected ';' after this.
+  return r"æble
+         ^^^^^^
+
+parser/coverage/string1:6:10: String starting with " must end with ".
+  return "æble
+         ^^^^^
+
+parser/coverage/string1:10:12: A '$' has special meaning inside a string, and must be followed by an identifier or an expression in curly braces ({}).
+  return "$1"
+           ^
+
+parser/coverage/string1:18:10: String starting with r" must end with ".
+  return r"æble$
+         ^^^^^^^
+
+parser/coverage/string1:23:10: String starting with r" must end with ".
+  return r"æble
+         ^^^^^^
+
+parser/coverage/string1:21:16: Can't find '}' to match '{'.
+String corge() {
+               ^
+
+beginCompilationUnit(String)
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(UnmatchedToken({), null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(foo)
+      handleType(String, null)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(dynamic)
+        endMetadataStar(0)
+        beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(dynamic, typeReference)
+          handleNoTypeArguments(bar)
+          handleType(dynamic, null)
+          handleIdentifier(bar, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("æble )
+            handleIdentifier(bar, expression)
+            handleNoTypeArguments(")
+            handleNoArguments(")
+            handleSend(bar, bar)
+            handleInterpolationExpression($, null)
+            handleStringPart(")
+          endLiteralString(1, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(bar)
+      handleType(String, null)
+      handleIdentifier(bar, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("æble")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], "æble", "æble")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(baz)
+      handleType(String, null)
+      handleIdentifier(baz, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(")
+            handleIdentifier(, expression)
+            handleNoTypeArguments(1")
+            handleNoArguments(1")
+            handleSend(, )
+            handleInterpolationExpression($, null)
+            handleStringPart(1")
+          endLiteralString(1, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1", 1")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(qux)
+      handleType(String, null)
+      handleIdentifier(qux, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"æble$")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble$", r"æble$")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(quux)
+      handleType(String, null)
+      handleIdentifier(quux, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"æble$")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble$", r"æble$")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(String)
+  endMetadataStar(0)
+  beginTopLevelMember(String)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(String, typeReference)
+      handleNoTypeArguments(corge)
+      handleType(String, null)
+      handleIdentifier(corge, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"æble")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble", r"æble")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(String, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnterminatedString("))
+  handleRecoverableError(Message[UnterminatedString, String starting with " must end with "., null, {string: ", string2: "}], UnterminatedString("), UnterminatedString("))
+  handleErrorToken(UnterminatedToken(UnexpectedDollarInString))
+  handleRecoverableError(UnexpectedDollarInString, UnterminatedToken(UnexpectedDollarInString), UnterminatedToken(UnexpectedDollarInString))
+  handleErrorToken(UnterminatedString(r"))
+  handleRecoverableError(Message[UnterminatedString, String starting with r" must end with "., null, {string: r", string2: "}], UnterminatedString(r"), UnterminatedString(r"))
+  handleErrorToken(UnterminatedString(r"))
+  handleRecoverableError(Message[UnterminatedString, String starting with r" must end with "., null, {string: r", string2: "}], UnterminatedString(r"), UnterminatedString(r"))
+  handleErrorToken(UnmatchedToken({))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+endCompilationUnit(6, )
diff --git a/pkg/front_end/parser_testcases/coverage/string1.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/string1.dart.intertwined.expect
new file mode 100644
index 0000000..a95c137
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string1.dart.intertwined.expect
@@ -0,0 +1,337 @@
+parseUnit(UnterminatedString("))
+  skipErrorTokens(UnterminatedString("))
+  listener: beginCompilationUnit(String)
+  syntheticPreviousToken(String)
+  parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnmatchedToken({))
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken({))
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), SimpleType(), null, foo, false)
+        listener: beginTopLevelMethod(UnmatchedToken({), null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(foo)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(dynamic)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(dynamic, typeReference)
+                listener: handleNoTypeArguments(bar)
+                listener: handleType(dynamic, null)
+                ensureIdentifier(dynamic, formalParameterDeclaration)
+                  listener: handleIdentifier(bar, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("æble )
+                            parseIdentifierExpression($)
+                              parseSend($, expression, ConstantPatternContext.none)
+                                isNextIdentifier($)
+                                ensureIdentifier($, expression)
+                                  listener: handleIdentifier(bar, expression)
+                                listener: handleNoTypeArguments(")
+                                parseArgumentsOpt(bar)
+                                  listener: handleNoArguments(")
+                                listener: handleSend(bar, bar)
+                            listener: handleInterpolationExpression($, null)
+                            parseStringPart(bar)
+                              listener: handleStringPart(")
+                            listener: endLiteralString(1, ;)
+                ensureSemicolon(")
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(}, null, null, }, SimpleType(), null, bar, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(bar)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(bar, topLevelFunctionDeclaration)
+        parseMethodTypeVar(bar)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(bar, bar, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(bar, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("æble")
+                            listener: endLiteralString(0, })
+                ensureSemicolon("æble")
+                  reportRecoverableError("æble", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], "æble", "æble")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(}, null, null, }, SimpleType(), null, baz, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(baz)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(baz, topLevelFunctionDeclaration)
+        parseMethodTypeVar(baz)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(baz, baz, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(baz, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(")
+                            parseIdentifierExpression($)
+                              parseSend($, expression, ConstantPatternContext.none)
+                                isNextIdentifier($)
+                                ensureIdentifier($, expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(1")
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(1")
+                                listener: handleSend(, )
+                            listener: handleInterpolationExpression($, null)
+                            parseStringPart()
+                              listener: handleStringPart(1")
+                            listener: endLiteralString(1, })
+                ensureSemicolon(1")
+                  reportRecoverableError(1", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1", 1")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(}, null, null, }, SimpleType(), null, qux, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(qux)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(qux, topLevelFunctionDeclaration)
+        parseMethodTypeVar(qux)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(qux, qux, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(qux, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"æble$")
+                            listener: endLiteralString(0, })
+                ensureSemicolon(r"æble$")
+                  reportRecoverableError(r"æble$", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble$", r"æble$")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(}, null, null, }, SimpleType(), null, quux, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(quux)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(quux, topLevelFunctionDeclaration)
+        parseMethodTypeVar(quux)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(quux, quux, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(quux, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"æble$")
+                            listener: endLiteralString(0, })
+                ensureSemicolon(r"æble$")
+                  reportRecoverableError(r"æble$", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble$", r"æble$")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(String)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(String)
+      parseTopLevelMethod(}, null, null, }, SimpleType(), null, corge, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(String, typeReference)
+        listener: handleNoTypeArguments(corge)
+        listener: handleType(String, null)
+        ensureIdentifierPotentiallyRecovered(String, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(corge, topLevelFunctionDeclaration)
+        parseMethodTypeVar(corge)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(corge, corge, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(corge, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"æble")
+                            listener: endLiteralString(0, })
+                ensureSemicolon(r"æble")
+                  reportRecoverableError(r"æble", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"æble", r"æble")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(String, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnterminatedString("))
+    listener: handleErrorToken(UnterminatedString("))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with " must end with "., null, {string: ", string2: "}], UnterminatedString("), UnterminatedString("))
+    listener: handleErrorToken(UnterminatedToken(UnexpectedDollarInString))
+    listener: handleRecoverableError(UnexpectedDollarInString, UnterminatedToken(UnexpectedDollarInString), UnterminatedToken(UnexpectedDollarInString))
+    listener: handleErrorToken(UnterminatedString(r"))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with r" must end with "., null, {string: r", string2: "}], UnterminatedString(r"), UnterminatedString(r"))
+    listener: handleErrorToken(UnterminatedString(r"))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with r" must end with "., null, {string: r", string2: "}], UnterminatedString(r"), UnterminatedString(r"))
+    listener: handleErrorToken(UnmatchedToken({))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+  listener: endCompilationUnit(6, )
diff --git a/pkg/front_end/parser_testcases/coverage/string1.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/string1.dart.parser.expect
new file mode 100644
index 0000000..45a487e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string1.dart.parser.expect
@@ -0,0 +1,66 @@
+NOTICE: Stream was rewritten by parser!
+
+String foo(dynamic bar) {
+return "æble $bar";
+}
+
+String bar() {
+return "æble"
+;}
+
+String baz() {
+return "$*synthetic*1"
+;}
+
+String qux() {
+return r"æble$"
+;}
+
+String quux() {
+return r"æble$"
+;}
+
+String corge() {
+
+return r"æble";}
+
+[UnterminatedString]
+
+
+
+[UnterminatedToken]
+
+
+
+
+
+
+
+[UnterminatedString]
+
+
+
+
+[UnterminatedString][UnmatchedToken]String[StringToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "æble [StringToken]$[SimpleToken]bar[StringToken]"[StringToken];[SimpleToken]
+}[SimpleToken]
+
+String[StringToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "æble"[SyntheticStringToken]
+;[SyntheticToken]}[SimpleToken]
+
+String[StringToken] baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "[StringToken]$[SimpleToken][SyntheticStringToken]1"[StringToken]
+;[SyntheticToken]}[SimpleToken]
+
+String[StringToken] qux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"æble$"[StringToken]
+;[SyntheticToken]}[SimpleToken]
+
+String[StringToken] quux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"æble$"[SyntheticStringToken]
+;[SyntheticToken]}[SimpleToken]
+
+String[StringToken] corge[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+return[KeywordToken] r"æble"[SyntheticStringToken];[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string1.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/string1.dart.scanner.expect
new file mode 100644
index 0000000..5abb9123
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string1.dart.scanner.expect
@@ -0,0 +1,64 @@
+String foo(dynamic bar) {
+return "æble $bar";
+}
+
+String bar() {
+return "æble"
+}
+
+String baz() {
+return "$*synthetic*1"
+}
+
+String qux() {
+return r"æble$"
+}
+
+String quux() {
+return r"æble$"
+}
+
+String corge() {
+
+return r"æble"}
+
+[UnterminatedString]
+
+
+
+[UnterminatedToken]
+
+
+
+
+
+
+
+[UnterminatedString]
+
+
+
+
+[UnterminatedString][UnmatchedToken]String[StringToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "æble [StringToken]$[SimpleToken]bar[StringToken]"[StringToken];[SimpleToken]
+}[SimpleToken]
+
+String[StringToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "æble"[SyntheticStringToken]
+}[SimpleToken]
+
+String[StringToken] baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] "[StringToken]$[SimpleToken][SyntheticStringToken]1"[StringToken]
+}[SimpleToken]
+
+String[StringToken] qux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"æble$"[StringToken]
+}[SimpleToken]
+
+String[StringToken] quux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"æble$"[SyntheticStringToken]
+}[SimpleToken]
+
+String[StringToken] corge[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+return[KeywordToken] r"æble"[SyntheticStringToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string2.dart b/pkg/front_end/parser_testcases/coverage/string2.dart
new file mode 100644
index 0000000..ba300c9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string2.dart
@@ -0,0 +1,21 @@
+void foo(dynamic bar) {
+  return """æbler$bar"""
+}
+
+void bar() {
+  return """æbler"""
+}
+
+void baz() {
+  return r"""hello"""
+}
+
+void qux() {
+  return """
+æbler
+"""
+}
+
+void quux() {
+  // ends in eof.
+  return """æbler\
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/string2.dart.expect b/pkg/front_end/parser_testcases/coverage/string2.dart.expect
new file mode 100644
index 0000000..7aff919
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string2.dart.expect
@@ -0,0 +1,152 @@
+Problems reported:
+
+parser/coverage/string2:2:22: Expected ';' after this.
+  return """æbler$bar"""
+                     ^^^
+
+parser/coverage/string2:6:10: Expected ';' after this.
+  return """æbler"""
+         ^^^^^^^^^^^
+
+parser/coverage/string2:10:10: Expected ';' after this.
+  return r"""hello"""
+         ^^^^^^^^^^^^
+
+parser/coverage/string2:14:10: Expected ';' after this.
+  return """
+         ^^^^...
+
+parser/coverage/string2:21:10: Expected ';' after this.
+  return """æbler\
+         ^^^^^^^^^
+
+parser/coverage/string2:21:10: String starting with """ must end with """.
+  return """æbler\
+         ^^^^^^^^^
+
+parser/coverage/string2:19:13: Can't find '}' to match '{'.
+void quux() {
+            ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(UnmatchedToken({), null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(dynamic)
+        endMetadataStar(0)
+        beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(dynamic, typeReference)
+          handleNoTypeArguments(bar)
+          handleType(dynamic, null)
+          handleIdentifier(bar, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("""æbler)
+            handleIdentifier(bar, expression)
+            handleNoTypeArguments(""")
+            handleNoArguments(""")
+            handleSend(bar, bar)
+            handleInterpolationExpression($, null)
+            handleStringPart(""")
+          endLiteralString(1, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """, """)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(bar, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("""æbler""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """æbler""", """æbler""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(baz, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"""hello""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"""hello""", r"""hello""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(qux, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("""
+æbler
+""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """
+æbler
+""", """
+æbler
+""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(quux, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("""æbler\""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """æbler\""", """æbler\""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnterminatedString("""))
+  handleRecoverableError(Message[UnterminatedString, String starting with """ must end with """., null, {string: """, string2: """}], UnterminatedString("""), UnterminatedString("""))
+  handleErrorToken(UnmatchedToken({))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/coverage/string2.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/string2.dart.intertwined.expect
new file mode 100644
index 0000000..3eaaaa7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string2.dart.intertwined.expect
@@ -0,0 +1,274 @@
+parseUnit(UnterminatedString("""))
+  skipErrorTokens(UnterminatedString("""))
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnmatchedToken({))
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken({))
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(UnmatchedToken({), null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(dynamic)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(dynamic, typeReference)
+                listener: handleNoTypeArguments(bar)
+                listener: handleType(dynamic, null)
+                ensureIdentifier(dynamic, formalParameterDeclaration)
+                  listener: handleIdentifier(bar, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("""æbler)
+                            parseIdentifierExpression($)
+                              parseSend($, expression, ConstantPatternContext.none)
+                                isNextIdentifier($)
+                                ensureIdentifier($, expression)
+                                  listener: handleIdentifier(bar, expression)
+                                listener: handleNoTypeArguments(""")
+                                parseArgumentsOpt(bar)
+                                  listener: handleNoArguments(""")
+                                listener: handleSend(bar, bar)
+                            listener: handleInterpolationExpression($, null)
+                            parseStringPart(bar)
+                              listener: handleStringPart(""")
+                            listener: endLiteralString(1, })
+                ensureSemicolon(""")
+                  reportRecoverableError(""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """, """)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, VoidType(), null, bar, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(bar, topLevelFunctionDeclaration)
+        parseMethodTypeVar(bar)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(bar, bar, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(bar, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("""æbler""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon("""æbler""")
+                  reportRecoverableError("""æbler""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """æbler""", """æbler""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, VoidType(), null, baz, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(baz, topLevelFunctionDeclaration)
+        parseMethodTypeVar(baz)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(baz, baz, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(baz, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"""hello""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon(r"""hello""")
+                  reportRecoverableError(r"""hello""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"""hello""", r"""hello""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, VoidType(), null, qux, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(qux, topLevelFunctionDeclaration)
+        parseMethodTypeVar(qux)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(qux, qux, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(qux, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("""
+æbler
+""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon("""
+æbler
+""")
+                  reportRecoverableError("""
+æbler
+""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """
+æbler
+""", """
+æbler
+""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, VoidType(), null, quux, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(quux, topLevelFunctionDeclaration)
+        parseMethodTypeVar(quux)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(quux, quux, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(quux, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("""æbler\""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon("""æbler\""")
+                  reportRecoverableError("""æbler\""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """æbler\""", """æbler\""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnterminatedString("""))
+    listener: handleErrorToken(UnterminatedString("""))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with """ must end with """., null, {string: """, string2: """}], UnterminatedString("""), UnterminatedString("""))
+    listener: handleErrorToken(UnmatchedToken({))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+  listener: endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/coverage/string2.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/string2.dart.parser.expect
new file mode 100644
index 0000000..279aefe
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string2.dart.parser.expect
@@ -0,0 +1,49 @@
+NOTICE: Stream was rewritten by parser!
+
+void foo(dynamic bar) {
+return """æbler$bar"""
+;}
+
+void bar() {
+return """æbler"""
+;}
+
+void baz() {
+return r"""hello"""
+;}
+
+void qux() {
+return """
+æbler
+"""
+
+
+;}
+
+void quux() {
+
+return """æbler\""";}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """æbler[StringToken]$[SimpleToken]bar[StringToken]"""[StringToken]
+;[SyntheticToken]}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """æbler"""[StringToken]
+;[SyntheticToken]}[SimpleToken]
+
+void[KeywordToken] baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""hello"""[StringToken]
+;[SyntheticToken]}[SimpleToken]
+
+void[KeywordToken] qux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """
+æbler
+"""[StringToken]
+
+
+;[SyntheticToken]}[SimpleToken]
+
+void[KeywordToken] quux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+return[KeywordToken] """æbler\"""[SyntheticStringToken];[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string2.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/string2.dart.scanner.expect
new file mode 100644
index 0000000..ac3f693
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string2.dart.scanner.expect
@@ -0,0 +1,47 @@
+void foo(dynamic bar) {
+return """æbler$bar"""
+}
+
+void bar() {
+return """æbler"""
+}
+
+void baz() {
+return r"""hello"""
+}
+
+void qux() {
+return """
+æbler
+"""
+
+
+}
+
+void quux() {
+
+return """æbler\"""}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken]dynamic[KeywordToken] bar[StringToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """æbler[StringToken]$[SimpleToken]bar[StringToken]"""[StringToken]
+}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """æbler"""[StringToken]
+}[SimpleToken]
+
+void[KeywordToken] baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""hello"""[StringToken]
+}[SimpleToken]
+
+void[KeywordToken] qux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """
+æbler
+"""[StringToken]
+
+
+}[SimpleToken]
+
+void[KeywordToken] quux[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+return[KeywordToken] """æbler\"""[SyntheticStringToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string3.dart b/pkg/front_end/parser_testcases/coverage/string3.dart
new file mode 100644
index 0000000..aae8ddc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string3.dart
@@ -0,0 +1,3 @@
+void foo() {
+  return """
+æbler
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/string3.dart.expect b/pkg/front_end/parser_testcases/coverage/string3.dart.expect
new file mode 100644
index 0000000..24c2c20
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string3.dart.expect
@@ -0,0 +1,42 @@
+Problems reported:
+
+parser/coverage/string3:2:10: Expected ';' after this.
+  return """
+         ^^^^...
+
+parser/coverage/string3:2:10: String starting with """ must end with """.
+  return """
+         ^^^^...
+
+parser/coverage/string3:1:12: Can't find '}' to match '{'.
+void foo() {
+           ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(UnmatchedToken({), null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString("""
+æbler""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """
+æbler""", """
+æbler""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnterminatedString("""))
+  handleRecoverableError(Message[UnterminatedString, String starting with """ must end with """., null, {string: """, string2: """}], UnterminatedString("""), UnterminatedString("""))
+  handleErrorToken(UnmatchedToken({))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/string3.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/string3.dart.intertwined.expect
new file mode 100644
index 0000000..77b1af7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string3.dart.intertwined.expect
@@ -0,0 +1,61 @@
+parseUnit(UnterminatedString("""))
+  skipErrorTokens(UnterminatedString("""))
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnmatchedToken({))
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken({))
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(UnmatchedToken({), null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString("""
+æbler""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon("""
+æbler""")
+                  reportRecoverableError("""
+æbler""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], """
+æbler""", """
+æbler""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnterminatedString("""))
+    listener: handleErrorToken(UnterminatedString("""))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with """ must end with """., null, {string: """, string2: """}], UnterminatedString("""), UnterminatedString("""))
+    listener: handleErrorToken(UnmatchedToken({))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/string3.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/string3.dart.parser.expect
new file mode 100644
index 0000000..7821cd72
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string3.dart.parser.expect
@@ -0,0 +1,11 @@
+NOTICE: Stream was rewritten by parser!
+
+void foo() {
+return """
+æbler"""
+;}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """
+æbler"""[SyntheticStringToken]
+;[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string3.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/string3.dart.scanner.expect
new file mode 100644
index 0000000..58d82d2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string3.dart.scanner.expect
@@ -0,0 +1,9 @@
+void foo() {
+return """
+æbler"""
+}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] """
+æbler"""[SyntheticStringToken]
+}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string4.dart b/pkg/front_end/parser_testcases/coverage/string4.dart
new file mode 100644
index 0000000..58d46e9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string4.dart
@@ -0,0 +1,9 @@
+void foo() {
+  return r"""
+æbler
+æbler""";
+}
+
+void bar() {
+  return r"""
+æbler
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/string4.dart.expect b/pkg/front_end/parser_testcases/coverage/string4.dart.expect
new file mode 100644
index 0000000..12ffe07
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string4.dart.expect
@@ -0,0 +1,62 @@
+Problems reported:
+
+parser/coverage/string4:8:10: Expected ';' after this.
+  return r"""
+         ^^^^^...
+
+parser/coverage/string4:8:10: String starting with r""" must end with """.
+  return r"""
+         ^^^^^...
+
+parser/coverage/string4:7:12: Can't find '}' to match '{'.
+void bar() {
+           ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(UnmatchedToken({), null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"""
+æbler
+æbler""")
+          endLiteralString(0, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(bar, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginReturnStatement(return)
+          beginLiteralString(r"""
+æbler""")
+          endLiteralString(0, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"""
+æbler""", r"""
+æbler""")
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+  handleErrorToken(UnterminatedString(r"""))
+  handleRecoverableError(Message[UnterminatedString, String starting with r""" must end with """., null, {string: r""", string2: """}], UnterminatedString(r"""), UnterminatedString(r"""))
+  handleErrorToken(UnmatchedToken({))
+  handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/coverage/string4.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/string4.dart.intertwined.expect
new file mode 100644
index 0000000..f13e979
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string4.dart.intertwined.expect
@@ -0,0 +1,108 @@
+parseUnit(UnterminatedString(r"""))
+  skipErrorTokens(UnterminatedString(r"""))
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown))
+    parseMetadataStar(UnmatchedToken({))
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken({))
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(UnmatchedToken({), null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"""
+æbler
+æbler""")
+                            listener: endLiteralString(0, ;)
+                ensureSemicolon(r"""
+æbler
+æbler""")
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations))
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, VoidType(), null, bar, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(bar, topLevelFunctionDeclaration)
+        parseMethodTypeVar(bar)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(bar, bar, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(bar, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, return)
+          parseStatement({)
+            parseStatementX({)
+              parseReturnStatement({)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true, ConstantPatternContext.none)
+                    parseUnaryExpression(return, true, ConstantPatternContext.none)
+                      parsePrimary(return, expression, ConstantPatternContext.none)
+                        parseLiteralString(return)
+                          parseSingleLiteralString(return)
+                            listener: beginLiteralString(r"""
+æbler""")
+                            listener: endLiteralString(0, })
+                ensureSemicolon(r"""
+æbler""")
+                  reportRecoverableError(r"""
+æbler""", Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r"""
+æbler""", r"""
+æbler""")
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(UnterminatedString(r"""))
+    listener: handleErrorToken(UnterminatedString(r"""))
+    listener: handleRecoverableError(Message[UnterminatedString, String starting with r""" must end with """., null, {string: r""", string2: """}], UnterminatedString(r"""), UnterminatedString(r"""))
+    listener: handleErrorToken(UnmatchedToken({))
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({))
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/coverage/string4.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/string4.dart.parser.expect
new file mode 100644
index 0000000..5e78a58
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string4.dart.parser.expect
@@ -0,0 +1,27 @@
+NOTICE: Stream was rewritten by parser!
+
+void foo() {
+return r"""
+æbler
+æbler"""
+
+;
+}
+
+void bar() {
+return r"""
+æbler"""
+;}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""
+æbler
+æbler"""[StringToken]
+
+;[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""
+æbler"""[SyntheticStringToken]
+;[SyntheticToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/string4.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/string4.dart.scanner.expect
new file mode 100644
index 0000000..712679c6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/string4.dart.scanner.expect
@@ -0,0 +1,25 @@
+void foo() {
+return r"""
+æbler
+æbler"""
+
+;
+}
+
+void bar() {
+return r"""
+æbler"""
+}
+
+[UnterminatedString][UnmatchedToken]void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""
+æbler
+æbler"""[StringToken]
+
+;[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+return[KeywordToken] r"""
+æbler"""[SyntheticStringToken]
+}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart
new file mode 100644
index 0000000..6f5ad7c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart
@@ -0,0 +1,2 @@
+#!æbler
+void foo() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.expect b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.expect
new file mode 100644
index 0000000..c788842
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.expect
@@ -0,0 +1,17 @@
+beginCompilationUnit(#!æbler)
+  handleScript(#!æbler)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(#!æbler, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(})
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.intertwined.expect b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.intertwined.expect
new file mode 100644
index 0000000..a7e308a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.intertwined.expect
@@ -0,0 +1,35 @@
+parseUnit(#!æbler)
+  skipErrorTokens(#!æbler)
+  listener: beginCompilationUnit(#!æbler)
+  syntheticPreviousToken(#!æbler)
+  parseScript()
+    listener: handleScript(#!æbler)
+  parseTopLevelDeclarationImpl(#!æbler, DirectiveContext(DirectiveState.Script))
+    parseMetadataStar(#!æbler)
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(#!æbler)
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(#!æbler, null, null, #!æbler, VoidType(), null, foo, false)
+        listener: beginTopLevelMethod(#!æbler, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(})
+  reportAllErrorTokens(#!æbler)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.parser.expect b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.parser.expect
new file mode 100644
index 0000000..7369ebf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.parser.expect
@@ -0,0 +1,5 @@
+#!æbler
+void foo() {}
+
+#!æbler[StringToken]
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.scanner.expect b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.scanner.expect
new file mode 100644
index 0000000..7369ebf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/coverage/tag_non_ascii.dart.scanner.expect
@@ -0,0 +1,5 @@
+#!æbler
+void foo() {}
+
+#!æbler[StringToken]
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/test/coverage_suite.dart b/pkg/front_end/test/coverage_suite.dart
index d6343f2..db2f375 100644
--- a/pkg/front_end/test/coverage_suite.dart
+++ b/pkg/front_end/test/coverage_suite.dart
@@ -57,6 +57,12 @@
       "--coverage=${coverageTmpDir.path}/",
     ]));
   }
+  futures.add(Process.run(Platform.resolvedExecutable, [
+    "--enable-asserts",
+    "--deterministic",
+    "pkg/front_end/test/parser_suite.dart",
+    "--coverage=${coverageTmpDir.path}/",
+  ]));
 
   // Wait for isolates to terminate and clean up.
   Iterable<ProcessResult> runResults = await Future.wait(futures);
diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart
index ebf6c05b..66cfeed 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -9,6 +9,11 @@
 // difference for compute_platform_binaries_location.dart).
 const Map<String, ({int hitCount, int missCount})> _expect = {
   // 100.0%.
+  "package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart": (
+    hitCount: 1227,
+    missCount: 0,
+  ),
+  // 100.0%.
   "package:front_end/src/api_prototype/compiler_options.dart": (
     hitCount: 43,
     missCount: 0,
@@ -1171,7 +1176,7 @@
   ),
   // 100.0%.
   "package:front_end/src/util/parser_ast.dart": (
-    hitCount: 73,
+    hitCount: 119,
     missCount: 0,
   ),
   // 100.0%.
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 8c151f8..2d7f649 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -100,6 +100,7 @@
 bkonyi
 bla
 blah
+bler
 blorp
 bold
 boo
@@ -211,6 +212,7 @@
 dacoharkes
 dadd
 daemon
+dar
 dart$doc$test$tester
 dart\$doc\$test\$tester
 dartanalyzer
diff --git a/pkg/front_end/tool/coverage_merger.dart b/pkg/front_end/tool/coverage_merger.dart
index 14aa17b..c07d024 100644
--- a/pkg/front_end/tool/coverage_merger.dart
+++ b/pkg/front_end/tool/coverage_merger.dart
@@ -737,9 +737,17 @@
     Coverage coverage, Map<Uri, Set<int>> misses, Map<Uri, Hit> hits) {
   for (FileCoverage fileCoverage in coverage.getAllFileCoverages()) {
     if (fileCoverage.uri.isScheme("package") &&
-        fileCoverage.uri.pathSegments.first != "front_end") {
+        fileCoverage.uri.pathSegments.first != "front_end" &&
+        fileCoverage.uri.pathSegments.first != "_fe_analyzer_shared") {
       continue;
     }
+
+    if (fileCoverage.uri.isScheme("package") &&
+        fileCoverage.uri.pathSegments.first == "_fe_analyzer_shared" &&
+        fileCoverage.uri.pathSegments.last != "abstract_scanner.dart") {
+      continue;
+    }
+
     if (fileCoverage.misses.isNotEmpty) {
       Set<int> miss = misses[fileCoverage.uri] ??= {};
       miss.addAll(fileCoverage.misses);