private void parseFormattedStringNode() {
    final SyntaxTreeBuilder builder = myContext.getBuilder();
    if (atToken(PyTokenTypes.FSTRING_START)) {
      final String prefixThenQuotes = builder.getTokenText();
      assert prefixThenQuotes != null;
      final String openingQuotes = prefixThenQuotes.replaceFirst("^[UuBbCcRrFf]*", "");
      final SyntaxTreeBuilder.Marker marker = builder.mark();
      nextToken();
      while (true) {
        if (atAnyOfTokens(PyTokenTypes.FSTRING_TEXT_TOKENS)) {
          nextToken();
        }
        else if (atToken(PyTokenTypes.FSTRING_FRAGMENT_START)) {
          parseFStringFragment();
        }
        else if (atToken(PyTokenTypes.FSTRING_END)) {
          if (builder.getTokenText().equals(openingQuotes)) {
            nextToken();
          }
          // Can be the end of an enclosing f-string, so leave it in the stream
          else {
            builder.mark().error(message("PARSE.expected.fstring.quote", openingQuotes));
          }
          break;
        }
        else if (atToken(PyTokenTypes.STATEMENT_BREAK)) {
          builder.mark().error(message("PARSE.expected.fstring.quote", openingQuotes));
          break;
        }
        else {
          builder.error(message("unexpected.f.string.token"));
          break;
        }
      }
      marker.done(PyElementTypes.FSTRING_NODE);
    }
  }
private void parseFormattedStringNode()