code: def test_parse_expression(self, *mocks: mock.MagicMock) -> None:
      parsed = ParsedExpression("a1  b1   c1    d1")
      self.assertSetEqual(parsed.identifiers, {"a1", "b1", "c1", "d1"})
      self.assertListEqual(
          parsed.composition, [["a1"], ["b1"], ["c1"], ["d1"]]
      )
      self.assertFalse(parsed.has_non_unitary_anonymous_axes)
      self.assertFalse(parsed.has_ellipsis)
  
      parsed = ParsedExpression("() () () ()")
      self.assertSetEqual(parsed.identifiers, set())
      self.assertListEqual(parsed.composition, [[], [], [], []])
      self.assertFalse(parsed.has_non_unitary_anonymous_axes)
      self.assertFalse(parsed.has_ellipsis)
  
      parsed = ParsedExpression("1 1 1 ()")
      self.assertSetEqual(parsed.identifiers, set())
      self.assertListEqual(parsed.composition, [[], [], [], []])
      self.assertFalse(parsed.has_non_unitary_anonymous_axes)
      self.assertFalse(parsed.has_ellipsis)
  
      parsed = ParsedExpression("5 (3 4)")
      self.assertEqual(len(parsed.identifiers), 3)
      self.assertSetEqual(
          {
              i.value if isinstance(i, AnonymousAxis) else i
              for i in parsed.identifiers
          },
          {3, 4, 5},
      )
      self.assertListEqual(
          parsed.composition,
          [
              [AnonymousAxis("5")],
              [AnonymousAxis("3"), AnonymousAxis("4")],
          ],
      )
      self.assertTrue(parsed.has_non_unitary_anonymous_axes)
      self.assertFalse(parsed.has_ellipsis)
  
      parsed = ParsedExpression("5 1 (1 4) 1")
      self.assertEqual(len(parsed.identifiers), 2)
      self.assertSetEqual(
          {
              i.value if isinstance(i, AnonymousAxis) else i
              for i in parsed.identifiers
          },
          {4, 5},
      )
      self.assertListEqual(
          parsed.composition,
          [[AnonymousAxis("5")], [], [AnonymousAxis("4")], []],
      )
  
      parsed = ParsedExpression("name1 ... a1 12 (name2 14)")
      self.assertEqual(len(parsed.identifiers), 6)
      self.assertEqual(
          len(parsed.identifiers - {"name1", _ellipsis, "a1", "name2"}),
          2,
      )
      self.assertListEqual(
          parsed.composition,
          [
              ["name1"],
              _ellipsis,
              ["a1"],
              [AnonymousAxis("12")],
              ["name2", AnonymousAxis("14")],
          ],
      )
      self.assertTrue(parsed.has_non_unitary_anonymous_axes)
      self.assertTrue(parsed.has_ellipsis)
      self.assertFalse(parsed.has_ellipsis_parenthesized)
  
      parsed = ParsedExpression("(name1 ... a1 12) name2 14")
      self.assertEqual(len(parsed.identifiers), 6)
      self.assertEqual(
          len(parsed.identifiers - {"name1", _ellipsis, "a1", "name2"}),
          2,
      )
      self.assertListEqual(
          parsed.composition,
          [
              ["name1", _ellipsis, "a1", AnonymousAxis("12")],
              ["name2"],
              [AnonymousAxis("14")],
          ],
      )
      self.assertTrue(parsed.has_non_unitary_anonymous_axes)
      self.assertTrue(parsed.has_ellipsis)
      self.assertTrue(parsed.has_ellipsis_parenthesized)
  
imports: from typing import Any, Callable, Dict
  from unittest import mock
  from functorch.einops._parsing import AnonymousAxis, ParsedExpression, parse_pattern, validate_rearrange_expressions, _ellipsis
  from torch.testing._internal.common_utils import TestCase, run_tests
label_desc: Use image node_id 3 for calling the TestParsedExpression obj's underlying member method code with example usage: obj.test_parse_expression() without return types