def add_complex_rule(self, name, s, f, is_expression=True): self._validate_name(name, is_expression) unslashed_name = _unslash('$' + name) words = s.split(' ') if len(words) < 2: raise ValueError( 'String describing a complex rule must be composed of at least two words, unlike %r.' % s) is_word = [True] * len(words) descs = [] for i, word in enumerate(words): if word == '%f' or word[0] == '$': descs.append(word) else: new_desc = '$%s.%r' % (name, i) self.add_reduce(new_desc, word) descs.append(new_desc) if len(words) == 2: self.add_expand(unslashed_name, descs[0], descs[1], f) else: self.add_expand('$%s.0t1' % name, descs[0], descs[1]) for i in range(2, len(words) - 1): self.add_expand('$%s.0t%r' % (name, i), '$%s.0t%r' % (name, i - 1), descs[i]) self.add_expand(unslashed_name, '$%s.0t%r' % (name, len(words) - 2), descs[-1], f) self.__sphinx_config.add_complex_rule(name, s, is_expression)
def _validate_name(self, name, is_expression): if name in self.__rule_names: raise ValueError('Name %r is already the name of a rule.' % name) else: self.__rule_names.append(name) if is_expression: self.__expression_descriptors.add(_unslash('$' + name))
def add_reduce(self, desc, word, formula=None): unslashed_desc = _unslash(desc) if unslashed_desc in self.__reduces: self.__reduces[unslashed_desc].append((word, formula)) else: self.__reduces[unslashed_desc] = [(word, formula)] self.__descriptors.add(unslashed_desc)
def add_expand(self, desc, l_desc, r_desc, f=None): lr_desc = (l_desc, r_desc) unslashed_desc = _unslash(desc) if unslashed_desc in self.__expands: self.__expands[unslashed_desc].append((lr_desc, f)) else: self.__expands[unslashed_desc] = [(lr_desc, f)] self.__descriptors.add(unslashed_desc)
def add_easy_reduce(self, name, d, f, is_expression=False, no_pregen=False): self._validate_name(name, is_expression) unslashed_name = _unslash('$' + name) k = 0 for key, val in d.items(): words = key.split(' ') if len(words) == 0: raise ValueError( 'String to be recognized by the parser must be non-empty.') elif len(words) == 1: if no_pregen: self.add_reduce(unslashed_name, key, (f, val)) else: self.add_reduce(unslashed_name, key, f(val)) elif len(words) == 2: self.add_reduce('$%s/%r.0' % (name, k), words[0]) self.add_reduce('$%s/%r.1' % (name, k), words[1]) self.add_expand(unslashed_name, '$%s/%r.0' % (name, k), '$%s/%r.1' % (name, k), lambda _, val=val: f(val)) k += 1 else: for i, word in enumerate(words): self.add_reduce('$%s/%r.%r' % (name, k, i), words[i]) self.add_expand('$%s/%r.0t1' % (name, k), '$%s/%r.0' % (name, k), '$%s/%r.1' % (name, k)) for i in range(2, len(words) - 1): self.add_expand('$%s/%r.0t%r' % (name, k, i), '$%s/%r.0t%r' % (name, k, i - 1), '$%s/%r.%r' % (name, k, i)) self.add_expand(unslashed_name, '$%s/%r.0t%r' % (name, k, len(words) - 2), '$%s/%r.%r' % (name, k, len(words) - 1), lambda _, val=val: f(val)) k += 1 self.__sphinx_config.add_simple_rule(name, d.keys(), is_expression)