code: def _process_constraint_expressions(self, expr_list, conflict_check=True, rev=True):
          
          # process expressions, grouping by field
          groups = {}
          for expr in expr_list:
              field, raw_op, val = parse_expr(expr)
              op = ConstraintOperator(raw_op)
              if field not in groups:
                  groups[field] = ConstraintGroup(Field(field, self._aliases))
              groups[field].add_constraint(op, val)
  
          # add existence constraints
          for cgroup in groups.values():
              cgroup.add_existence(rev)
  
          # optionally check for conflicts
          if conflict_check:
              # check for conflicts in each group
              for field_name, group in groups.items():
                  conflicts = group.get_conflicts()
                  if conflicts:
                      raise ValueError('Conflicts for field {}: {}'.format(field_name, conflicts))
          return groups
docs: Create and return constraints from expressions in expr_list.
  
          :param expr_list: The expressions
          :conflict_check: If True, check for conflicting expressions within each field
          :return: Constraints grouped by field (the key is the field name)
          :rtype: dict