# Path: epitran/exceptions.py
# class DatafileError(Exception):
#     pass


import io
import logging
import unicodedata
import regex as re
from epitran.exceptions import DatafileError
            for i, line in enumerate(f):
                # Normalize the line to decomposed form
                line = line.strip()
                line = unicodedata.normalize('NFD', line)
                if not re.match('\s*%', line):
                    rules.append(self._read_rule(i, line))
        return [rule for rule in rules if rule is not None]

    def _sub_symbols(self, line):
        while re.search(r'::\w+::', line):
            s = re.search(r'::\w+::', line).group(0)
            if s in self.symbols:
                line = line.replace(s, self.symbols[s])
            else:
                raise RuleFileError('Undefined symbol: {}'.format(s))
        return line

    def _read_rule(self, i, line):
        line = line.strip()
        if line:
            line = unicodedata.normalize('NFD', line)
            s = re.match(r'(?P<symbol>::\w+::)\s*=\s*(?P<value>.+)', line)
            if s:
                self.symbols[s.group('symbol')] = s.group('value')
            else:
                line = self._sub_symbols(line)
                r = re.match(r'(\S+)\s*->\s*(\S+)\s*/\s*(\S*)\s*[_]\s*(\S*)', line)
                try:
                    a, b, X, Y = r.groups()
                except AttributeError:

# Path: epitran/exceptions.py
# class DatafileError(Exception):
#     pass


# Path: epitran/rules.py
import io
import logging
import unicodedata
import regex as re
from epitran.exceptions import DatafileError

            for i, line in enumerate(f):
                # Normalize the line to decomposed form
                line = line.strip()
                line = unicodedata.normalize('NFD', line)
                if not re.match('\s*%', line):
                    rules.append(self._read_rule(i, line))
        return [rule for rule in rules if rule is not None]

    def _sub_symbols(self, line):
        while re.search(r'::\w+::', line):
            s = re.search(r'::\w+::', line).group(0)
            if s in self.symbols:
                line = line.replace(s, self.symbols[s])
            else:
                raise RuleFileError('Undefined symbol: {}'.format(s))
        return line

    def _read_rule(self, i, line):
        line = line.strip()
        if line:
            line = unicodedata.normalize('NFD', line)
            s = re.match(r'(?P<symbol>::\w+::)\s*=\s*(?P<value>.+)', line)
            if s:
                self.symbols[s.group('symbol')] = s.group('value')
            else:
                line = self._sub_symbols(line)
                r = re.match(r'(\S+)\s*->\s*(\S+)\s*/\s*(\S*)\s*[_]\s*(\S*)', line)
                try:
                    a, b, X, Y = r.groups()
                except AttributeError:

                    raise DatafileError('Line {}: "{}" cannot be parsed.'.format(i + 1, line))