code: def test_domain_c_ast_expressions():
      def exprCheck(expr, output=None):
          parser = DefinitionParser(
              expr, location=None, config=Config()
          )
          parser.allowFallbackExpressionParsing = False
          ast = parser.parse_expression()
          parser.assert_end()
          # first a simple check of the AST
          if output is None:
              output = expr
          res = str(ast)
          if res != output:
              print("")
              print("Input:    ", input)
              print("Result:   ", res)
              print("Expected: ", output)
              raise DefinitionError
          displayString = ast.get_display_string()
          if res != displayString:
              # note: if the expression contains an anon name then this will trigger a falsely
              print("")
              print("Input:    ", expr)
              print("Result:   ", res)
              print("Display:  ", displayString)
              raise DefinitionError
  
      # type expressions
      exprCheck("int*")
      exprCheck("int *const*")
      exprCheck("int *volatile*")
      exprCheck("int *restrict*")
      exprCheck("int *(*)(double)")
      exprCheck("const int*")
      exprCheck("__int64")
      exprCheck("unsigned __int64")
  
      # actual expressions
  
      # primary
      exprCheck("true")
      exprCheck("false")
      ints = [
          "5",
          "0",
          "075",
          "0x0123456789ABCDEF",
          "0XF",
          "0b1",
          "0B1",
          "0b0'1'0",
          "00'1'2",
          "0x0'1'2",
          "1'2'3",
      ]
      unsignedSuffix = ["", "u", "U"]
      longSuffix = ["", "l", "L", "ll", "LL"]
      for i in ints:
          for u in unsignedSuffix:
              for l in longSuffix:
                  expr = i + u + l
                  exprCheck(expr)
                  expr = i + l + u
                  exprCheck(expr)
      for suffix in ["", "f", "F", "l", "L"]:
          for e in [
              "5e42",
              "5e+42",
              "5e-42",
              "5.",
              "5.e42",
              "5.e+42",
              "5.e-42",
              ".5",
              ".5e42",
              ".5e+42",
              ".5e-42",
              "5.0",
              "5.0e42",
              "5.0e+42",
              "5.0e-42",
              "1'2'3e7'8'9",
              "1'2'3.e7'8'9",
              ".4'5'6e7'8'9",
              "1'2'3.4'5'6e7'8'9",
          ]:
              expr = e + suffix
              exprCheck(expr)
          for e in [
              "ApF",
              "Ap+F",
              "Ap-F",
              "A.",
              "A.pF",
              "A.p+F",
              "A.p-F",
              ".A",
              ".ApF",
              ".Ap+F",
              ".Ap-F",
              "A.B",
              "A.BpF",
              "A.Bp+F",
              "A.Bp-F",
              "A'B'Cp1'2'3",
              "A'B'C.p1'2'3",
              ".D'E'Fp1'2'3",
              "A'B'C.D'E'Fp1'2'3",
          ]:
              expr = "0x" + e + suffix
              exprCheck(expr)
      exprCheck('"abc\\"cba"')  # string
      # character literals
      for p in ["", "u8", "u", "U", "L"]:
          exprCheck(p + "'a'")
          exprCheck(p + "'\\n'")
          exprCheck(p + "'\\012'")
          exprCheck(p + "'\\0'")
          exprCheck(p + "'\\x0a'")
          exprCheck(p + "'\\x0A'")
          exprCheck(p + "'\\u0a42'")
          exprCheck(p + "'\\u0A42'")
          exprCheck(p + "'\\U0001f34c'")
          exprCheck(p + "'\\U0001F34C'")
  
      exprCheck("(5)")
      exprCheck("C")
      # postfix
      exprCheck("A(2)")
      exprCheck("A[2]")
      exprCheck("a.b.c")
      exprCheck("a->b->c")
      exprCheck("i++")
      exprCheck("i--")
      # unary
      exprCheck("++5")
      exprCheck("--5")
      exprCheck("*5")
      exprCheck("&5")
      exprCheck("+5")
      exprCheck("-5")
      exprCheck("!5")
      exprCheck("not 5")
      exprCheck("~5")
      exprCheck("compl 5")
      exprCheck("sizeof(T)")
      exprCheck("sizeof -42")
      exprCheck("alignof(T)")
      # cast
      exprCheck("(int)2")
      # binary op
      exprCheck("5 || 42")
      exprCheck("5 or 42")
      exprCheck("5 && 42")
      exprCheck("5 and 42")
      exprCheck("5 | 42")
      exprCheck("5 bitor 42")
      exprCheck("5 ^ 42")
      exprCheck("5 xor 42")
      exprCheck("5 & 42")
      exprCheck("5 bitand 42")
      # ['==', '!=']
      exprCheck("5 == 42")
      exprCheck("5 != 42")
      exprCheck("5 not_eq 42")
      # ['<=', '>=', '<', '>']
      exprCheck("5 <= 42")
      exprCheck("5 >= 42")
      exprCheck("5 < 42")
      exprCheck("5 > 42")
      # ['<<', '>>']
      exprCheck("5 << 42")
      exprCheck("5 >> 42")
      # ['+', '-']
      exprCheck("5 + 42")
      exprCheck("5 - 42")
      # ['*', '/', '%']
      exprCheck("5 * 42")
      exprCheck("5 / 42")
      exprCheck("5 % 42")
      # ['.*', '->*']
      # conditional
      # TODO
      # assignment
      exprCheck("a = 5")
      exprCheck("a *= 5")
      exprCheck("a /= 5")
      exprCheck("a %= 5")
      exprCheck("a += 5")
      exprCheck("a -= 5")
      exprCheck("a >>= 5")
      exprCheck("a <<= 5")
      exprCheck("a &= 5")
      exprCheck("a and_eq 5")
      exprCheck("a ^= 5")
      exprCheck("a xor_eq 5")
      exprCheck("a |= 5")
      exprCheck("a or_eq 5")
  
imports: import itertools
  import zlib
  from xml.etree import ElementTree
  import pytest
  from sphinx import addnodes
  from sphinx.addnodes import desc, desc_content, desc_name, desc_parameter, desc_parameterlist, desc_sig_name, desc_sig_space, desc_signature, desc_signature_line, pending_xref
  from sphinx.domains.c import DefinitionError, DefinitionParser, Symbol, _id_prefix, _macroKeywords, _max_id
  from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
  from sphinx.testing import restructuredtext
  from sphinx.testing.util import assert_node
  from sphinx.writers.text import STDINDENT
label_desc: Use image node_id 4 for calling a global function with example usage: test_domain_c_ast_expressions() without return types