code: def noun_chunks(
      doclike: Union[Doc, Span]
  ) -> Iterator[Tuple[int, int, int]]:
      """
      Detect base noun phrases from a dependency parse. Works on Doc and Span.
      The definition is inspired by https://www.nltk.org/book/ch07.html
      Consider : [Noun + determinant / adjective] and also [Pronoun]
      """
      # fmt: off
      # labels = ["nsubj", "nsubj:pass", "obj", "iobj", "ROOT", "appos", "nmod", "nmod:poss"]
      # fmt: on
      doc = doclike.doc  # Ensure works on both Doc and Span.
  
      # Check for dependencies: POS, DEP
      if not doc.has_annotation("POS"):
          raise ValueError(Errors.E1019)
      if not doc.has_annotation("DEP"):
          raise ValueError(Errors.E029)
  
      # See UD tags: https://universaldependencies.org/u/dep/index.html
      # amod = adjectival modifier
      # nmod:poss = possessive nominal modifier
      # nummod = numeric modifier
      # det = determiner
      # det:poss = possessive determiner
      noun_deps = [
          doc.vocab.strings[label]
          for label in ["amod", "nmod:poss", "det", "det:poss"]
      ]
  
      # nsubj = nominal subject
      # nsubj:pass = passive nominal subject
      pronoun_deps = [
          doc.vocab.strings[label] for label in ["nsubj", "nsubj:pass"]
      ]
  
      # Label NP for the Span to identify it as Noun-Phrase
      span_label = doc.vocab.strings.add("NP")
  
      # Only NOUNS and PRONOUNS matter
      end_span = -1
      for i, word in enumerate(
          filter(lambda x: x.pos in [PRON, NOUN], doclike)
      ):
          # For NOUNS
          # Pick children from syntactic parse (only those with certain dependencies)
          if word.pos == NOUN:
              # Some debugging. It happens that VERBS are POS-TAGGED as NOUNS
              # We check if the word has a "nsubj", if it's the case, we eliminate it
              nsubjs = filter(
                  lambda x: x.dep == doc.vocab.strings["nsubj"],
                  word.children,
              )
              next_word = next(nsubjs, None)
              if next_word is not None:
                  # We found some nsubj, so we skip this word. Otherwise, consider it a normal NOUN
                  continue
  
              children = filter(
                  lambda x: x.dep in noun_deps, word.children
              )
              children_i = [c.i for c in children] + [word.i]
  
              start_span = min(children_i)
              if start_span >= end_span:
                  end_span = max(children_i) + 1
                  yield start_span, end_span, span_label
  
          # PRONOUNS only if it is the subject of a verb
          elif word.pos == PRON:
              if word.dep in pronoun_deps:
                  start_span = word.i
                  if start_span >= end_span:
                      end_span = word.i + 1
                      yield start_span, end_span, span_label
  
imports: from typing import Iterator, Tuple, Union
  from ...errors import Errors
  from ...symbols import NOUN, PRON
  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