1. # written for python 3
  2. import os
  3.  
  4. def check_balance(characters):
  5.     '''Return -1 if all delimiters are balanced or return
  6.       the char number of the first mismatched delimiter.
  7.  
  8.    '''
  9.     openers = {'(': ')', '{': '}', '[': ']', '“': '”', '‹': '›', '«': '»',
  10.            '【': '】', '〈': '〉', '《': '》', '「': '」', '『': '』'}
  11.     closers = set(openers.values())
  12.     stack = []
  13.     for i, c in enumerate(characters, start=1):
  14.         if c in openers:
  15.             stack.append(openers[c])
  16.         elif c in closers:
  17.             if not stack or c != stack.pop():
  18.                 return i
  19.     return -1
  20.  
  21. def scan(directory, encoding='utf-8'):
  22.     for dirpath, dirnames, filenames in os.walk(directory):
  23.         for filename in filenames:
  24.             fullname = os.path.join(dirpath, filename)
  25.             with open(fullname, 'r', encoding=encoding) as f:
  26.                 try:
  27.                     characters = f.read()
  28.                 except UnicodeDecodeError:
  29.                     continue
  30.             position = check_balance(characters)
  31.             if position >= 0:
  32.                 print('{0!r}: {1}'.format(position, fullname))
  33.  
  34. scan('.')