code: def noun_chunks(
      doclike: Union[Doc, Span]
  ) -> Iterator[Tuple[int, int, int]]:
      """
      Detect base noun phrases from a dependency parse. Works on both Doc and Span.
      """
      labels = [
          "oprd",
          "nsubj",
          "dobj",
          "nsubjpass",
          "pcomp",
          "pobj",
          "dative",
          "appos",
          "attr",
          "ROOT",
      ]
      doc = doclike.doc  # Ensure works on both Doc and Span.
      if not doc.has_annotation("DEP"):
          raise ValueError(Errors.E029)
      np_deps = [doc.vocab.strings.add(label) for label in labels]
      conj = doc.vocab.strings.add("conj")
      np_label = doc.vocab.strings.add("NP")
      prev_end = -1
      for i, word in enumerate(doclike):
          if word.pos not in (NOUN, PROPN, PRON):
              continue
          # Prevent nested chunks from being produced
          if word.left_edge.i <= prev_end:
              continue
          if word.dep in np_deps:
              prev_end = word.i
              yield word.left_edge.i, word.i + 1, np_label
          elif word.dep == conj:
              head = word.head
              while head.dep == conj and head.head.i < head.i:
                  head = head.head
              # If the head is an NP, and we're coordinated to it, we're an NP
              if head.dep in np_deps:
                  prev_end = word.i
                  yield word.left_edge.i, word.i + 1, np_label
  
imports: from typing import Iterator, Tuple, Union
  from ...errors import Errors
  from ...symbols import NOUN, PRON, PROPN
  from ...tokens import Doc, Span
label_desc: Use image node_id 1 for calling a global function with example usage: noun_chunks(doclike) without return types