code: def inst_header(self) -> InstHeader | None:
      # annotation* inst(NAME, (inputs -- outputs))
      # | annotation* op(NAME, (inputs -- outputs))
      annotations = []
      while anno := self.expect(lx.ANNOTATION):
          annotations.append(anno.text)
      tkn = self.expect(lx.INST)
      if not tkn:
          tkn = self.expect(lx.OP)
      if tkn:
          kind = cast(Literal["inst", "op"], tkn.text)
          if self.expect(lx.LPAREN) and (
              tkn := self.expect(lx.IDENTIFIER)
          ):
              name = tkn.text
              if self.expect(lx.COMMA):
                  inp, outp = self.io_effect()
                  if self.expect(lx.RPAREN):
                      if (tkn := self.peek()) and tkn.kind == lx.LBRACE:
                          return InstHeader(
                              annotations, kind, name, inp, outp
                          )
      return None
  
imports: from dataclasses import dataclass, field
  from typing import NamedTuple, Callable, TypeVar, Literal, cast
  import lexer
  from plexer import PLexer
label_desc: Use image node_id 3 for calling the Parser obj's underlying member method code with example usage: obj.inst_header() and returns: None, InstHeader