class_docstr: This class is used to parse a Python file, it then divides them into a
  class structure of different scopes.
  
  :param pgen_grammar: The grammar object of pgen2. Loaded by load_grammar.
class_docstr_tok: ["This","class","is","used","to","parse","a","Python","file",",","it","then","divides","them","into","a","class","structure","of","different","scopes",".",":","param","pgen_grammar",":","The","grammar","object","of","pgen2",".","Loaded","by","load_grammar","."]
code: def error_recovery(self, token):
      tos_nodes = self.stack[-1].nodes
      if tos_nodes:
          last_leaf = tos_nodes[-1].get_last_leaf()
      else:
          last_leaf = None
  
      if self._start_nonterminal == "file_input" and (
          token.type == PythonTokenTypes.ENDMARKER
          or token.type == DEDENT
          and not last_leaf.value.endswith("\n")
          and not last_leaf.value.endswith("\r")
      ):
          # In Python statements need to end with a newline. But since it's
          # possible (and valid in Python) that there's no newline at the
          # end of a file, we have to recover even if the user doesn't want
          # error recovery.
          if self.stack[-1].dfa.from_rule == "simple_stmt":
              try:
                  plan = self.stack[-1].dfa.transitions[
                      PythonTokenTypes.NEWLINE
                  ]
              except KeyError:
                  pass
              else:
                  if plan.next_dfa.is_final and not plan.dfa_pushes:
                      # We are ignoring here that the newline would be
                      # required for a simple_stmt.
                      self.stack[-1].dfa = plan.next_dfa
                      self._add_token(token)
                      return
  
      if not self._error_recovery:
          return super().error_recovery(token)
  
      def current_suite(stack):
          # For now just discard everything that is not a suite or
          # file_input, if we detect an error.
          for until_index, stack_node in reversed(
              list(enumerate(stack))
          ):
              # `suite` can sometimes be only simple_stmt, not stmt.
              if stack_node.nonterminal == "file_input":
                  break
              elif stack_node.nonterminal == "suite":
                  # In the case where we just have a newline we don't want to
                  # do error recovery here. In all other cases, we want to do
                  # error recovery.
                  if len(stack_node.nodes) != 1:
                      break
          return until_index
  
      until_index = current_suite(self.stack)
  
      if self._stack_removal(until_index + 1):
          self._add_token(token)
      else:
          typ, value, start_pos, prefix = token
          if typ == INDENT:
              # For every deleted INDENT we have to delete a DEDENT as well.
              # Otherwise the parser will get into trouble and DEDENT too early.
              self._omit_dedent_list.append(self._indent_counter)
  
          error_leaf = tree.PythonErrorLeaf(
              typ.name, value, start_pos, prefix
          )
          self.stack[-1].nodes.append(error_leaf)
  
      tos = self.stack[-1]
      if tos.nonterminal == "suite":
          # Need at least one statement in the suite. This happend with the
          # error recovery above.
          try:
              tos.dfa = tos.dfa.arcs["stmt"]
          except KeyError:
              # We're already in a final state.
              pass
  
file_path: catboost/contrib/python/parso/py3/parso/python/parser.py
imports: from parso.python import tree
  from parso.python.token import PythonTokenTypes
  from parso.parser import BaseParser
label_desc: Use image node_id 5 for calling the Parser obj's underlying member method code with example usage: obj.error_recovery(token) and returns: super, until_index