code: def iob1_tags_to_spans(
      tag_sequence: List[str], classes_to_ignore: List[str] = None
  ) -> List[TypedStringSpan]:
      """
      Given a sequence corresponding to IOB1 tags, extracts spans.
      Spans are inclusive and can be of zero length, representing a single word span.
      Ill-formed spans are also included (i.e., those where "B-LABEL" is not preceded
      by "I-LABEL" or "B-LABEL").
  
      # Parameters
  
      tag_sequence : `List[str]`, required.
          The integer class labels for a sequence.
      classes_to_ignore : `List[str]`, optional (default = `None`).
          A list of string class labels `excluding` the bio tag
          which should be ignored when extracting spans.
  
      # Returns
  
      spans : `List[TypedStringSpan]`
          The typed, extracted spans from the sequence, in the format (label, (span_start, span_end)).
          Note that the label `does not` contain any BIO tag prefixes.
      """
      classes_to_ignore = classes_to_ignore or []
      spans: Set[Tuple[str, Tuple[int, int]]] = set()
      span_start = 0
      span_end = 0
      active_conll_tag = None
      prev_bio_tag = None
      prev_conll_tag = None
      for index, string_tag in enumerate(tag_sequence):
          curr_bio_tag = string_tag[0]
          curr_conll_tag = string_tag[2:]
  
          if curr_bio_tag not in ["B", "I", "O"]:
              raise InvalidTagSequence(tag_sequence)
          if curr_bio_tag == "O" or curr_conll_tag in classes_to_ignore:
              # The span has ended.
              if active_conll_tag is not None:
                  spans.add((active_conll_tag, (span_start, span_end)))
              active_conll_tag = None
          elif _iob1_start_of_chunk(
              prev_bio_tag, prev_conll_tag, curr_bio_tag, curr_conll_tag
          ):
              # We are entering a new span; reset indices
              # and active tag to new span.
              if active_conll_tag is not None:
                  spans.add((active_conll_tag, (span_start, span_end)))
              active_conll_tag = curr_conll_tag
              span_start = index
              span_end = index
          else:
              # bio_tag == "I" and curr_conll_tag == active_conll_tag
              # We're continuing a span.
              span_end += 1
  
          prev_bio_tag = string_tag[0]
          prev_conll_tag = string_tag[2:]
      # Last token might have been a part of a valid span.
      if active_conll_tag is not None:
          spans.add((active_conll_tag, (span_start, span_end)))
      return list(spans)
  
file_path: allennlp/allennlp/data/dataset_readers/dataset_utils/span_utils.py
imports: from typing import Callable, List, Set, Tuple, TypeVar, Optional
  import warnings
  from allennlp.common.checks import ConfigurationError
  from allennlp.data.tokenizers import Token
label_desc: Use image node_id 3 for calling a global function with example usage: iob1_tags_to_spans(tag_sequence, classes_to_ignore) and returns: list