gramfuzz/gramfuzz/__init__.py
def gen(self, num, cat=None, cat_group=None, preferred=None, preferred_ratio=0.5, max_recursion=None, auto_process=True):
        """Generate ``num`` rules from category ``cat``, optionally specifying
        preferred category groups ``preferred`` that should be preferred at
        probability ``preferred_ratio`` over other randomly-chosen rule definitions.

        :param int num: The number of rules to generate
        :param str cat: The name of the category to generate ``num`` rules from
        :param str cat_group: The category group (ie python file) to generate rules from. This
            was added specifically to make it easier to generate data based on the name
            of the file the grammar was defined in, and is intended to work with the
            ``TOP_CAT`` values that may be defined in a loaded grammar file.
        :param list preferred: A list of preferred category groups to generate rules from
        :param float preferred_ratio: The percent probability that the preferred
            groups will be chosen over randomly choosen rule definitions from category ``cat``.
        :param int max_recursion: The maximum amount to allow references to recurse
        :param bool auto_process: Whether rules should be automatically pruned and
            shortest reference paths determined. See :any:`gramfuzz.GramFuzzer.preprocess_rules`
            for what would automatically be done.
        """
        import gramfuzz.fields
        gramfuzz.fields.REF_LEVEL = 1

        if cat is None and cat_group is None:
            raise gramfuzz.errors.GramFuzzError("cat and cat_group are None, one must be set")

        if cat is None and cat_group is not None:
            if cat_group not in self.cat_group_defaults:
                raise gramfuzz.errors.GramFuzzError(
                    "cat_group {!r} did not define a TOP_CAT variable"
                )
            cat = self.cat_group_defaults[cat_group]
            if not isinstance(cat, basestring):
                raise gramfuzz.errors.GramFuzzError(
                    "cat_group {!r}'s TOP_CAT variable was not a string"
                )

        if auto_process and self._rules_processed == False:
            self.preprocess_rules()

        if max_recursion is not None:
            self.set_max_recursion(max_recursion)

        if preferred is None:
            preferred = []

        res = deque()
        cat_defs = self.defs[cat]

        # optimizations
        _res_append = res.append
        _res_extend = res.extend
        _choice = rand.choice
        _maybe = rand.maybe
        _val = utils.val

        keys = self.defs[cat].keys()

        self._last_pref_keys = self._get_pref_keys(cat, preferred)
        # be sure to set this *after* fetching the pref keys (above^)
        self._last_prefs = preferred

        total_errors = deque()
        total_gend = 0
        while total_gend < num:
            # use a rule definition from one of the preferred category
            # groups
            if len(self._last_pref_keys) > 0 and _maybe(preferred_ratio):
                rand_key = _choice(self._last_pref_keys)
                if rand_key not in cat_defs:
                    # TODO this means it was removed / pruned b/c it was unreachable??
                    # TODO look into this more
                    rand_key = _choice(list(keys))

            # else just choose a key at random from the category
            else:
                rand_key = _choice(list(keys))

            # pruning failed, this rule is not defined/reachable
            if rand_key not in cat_defs:
                continue

            v = _choice(cat_defs[rand_key])

            # not used directly by GramFuzzer, but could be useful
            # to subclasses of GramFuzzer
            info = {}

            pre = deque()
            self.pre_revert(info)
            val_res = None

            try:
                val_res = _val(v, pre)
            except errors.GramFuzzError as e:
                raise
                #total_errors.append(e)
                #self.revert(info)
                #continue
            except RuntimeError as e:
                print("RUNTIME ERROR")
                self.revert(info)
                continue

            if val_res is not None:
                _res_extend(pre)
                _res_append(val_res)

                total_gend += 1
                self.post_revert(cat, res, total_gend, num, info)

        return res
def gen(self, num, cat=None, cat_group=None, preferred=None, preferred_ratio=0.5, max_recursion=None, auto_process=True):
        """Generate ``num`` rules from category ``cat``, optionally specifying
        preferred category groups ``preferred`` that should be preferred at
        probability ``preferred_ratio`` over other randomly-chosen rule definitions.

        :param int num: The number of rules to generate
        :param str cat: The name of the category to generate ``num`` rules from
        :param str cat_group: The category group (ie python file) to generate rules from. This
            was added specifically to make it easier to generate data based on the name
            of the file the grammar was defined in, and is intended to work with the
            ``TOP_CAT`` values that may be defined in a loaded grammar file.
        :param list preferred: A list of preferred category groups to generate rules from
        :param float preferred_ratio: The percent probability that the preferred
            groups will be chosen over randomly choosen rule definitions from category ``cat``.
        :param int max_recursion: The maximum amount to allow references to recurse
        :param bool auto_process: Whether rules should be automatically pruned and
            shortest reference paths determined. See :any:`gramfuzz.GramFuzzer.preprocess_rules`
            for what would automatically be done.
        """
        import gramfuzz.fields
        gramfuzz.fields.REF_LEVEL = 1

        if cat is None and cat_group is None:
            raise gramfuzz.errors.GramFuzzError("cat and cat_group are None, one must be set")

        if cat is None and cat_group is not None:
            if cat_group not in self.cat_group_defaults:
                raise gramfuzz.errors.GramFuzzError(
                    "cat_group {!r} did not define a TOP_CAT variable"
                )
            cat = self.cat_group_defaults[cat_group]
            if not isinstance(cat, basestring):
                raise gramfuzz.errors.GramFuzzError(
                    "cat_group {!r}'s TOP_CAT variable was not a string"
                )

        if auto_process and self._rules_processed == False:
            self.preprocess_rules()

        if max_recursion is not None:
            self.set_max_recursion(max_recursion)

        if preferred is None:
            preferred = []

        res = deque()
        cat_defs = self.defs[cat]

        # optimizations
        _res_append = res.append
        _res_extend = res.extend
        _choice = rand.choice
        _maybe = rand.maybe
        _val = utils.val

        keys = self.defs[cat].keys()

        self._last_pref_keys = self._get_pref_keys(cat, preferred)
        # be sure to set this *after* fetching the pref keys (above^)
        self._last_prefs = preferred

        total_errors = deque()
        total_gend = 0
        while total_gend < num:
            # use a rule definition from one of the preferred category
            # groups
            if len(self._last_pref_keys) > 0 and _maybe(preferred_ratio):
                rand_key = _choice(self._last_pref_keys)
                if rand_key not in cat_defs:
                    # TODO this means it was removed / pruned b/c it was unreachable??
                    # TODO look into this more
                    rand_key = _choice(list(keys))

            # else just choose a key at random from the category
            else:
                rand_key = _choice(list(keys))

            # pruning failed, this rule is not defined/reachable
            if rand_key not in cat_defs:
                continue

            v = _choice(cat_defs[rand_key])

            # not used directly by GramFuzzer, but could be useful
            # to subclasses of GramFuzzer
            info = {}

            pre = deque()
            self.pre_revert(info)
            val_res = None

            try:
                val_res = _val(v, pre)
            except errors.GramFuzzError as e:
                raise
                #total_errors.append(e)
                #self.revert(info)
                #continue
            except RuntimeError as e:
                print("RUNTIME ERROR")
                self.revert(info)
                continue

            if val_res is not None:
                _res_extend(pre)
                _res_append(val_res)

                total_gend += 1
                self.post_revert(cat, res, total_gend, num, info)

        return res
Generate ``num`` rules from category ``cat``, optionally specifying
        preferred category groups ``preferred`` that should be preferred at
        probability ``preferred_ratio`` over other randomly-chosen rule definitions.

        :param int num: The number of rules to generate
        :param str cat: The name of the category to generate ``num`` rules from
        :param str cat_group: The category group (ie python file) to generate rules from. This
            was added specifically to make it easier to generate data based on the name
            of the file the grammar was defined in, and is intended to work with the
            ``TOP_CAT`` values that may be defined in a loaded grammar file.
        :param list preferred: A list of preferred category groups to generate rules from
        :param float preferred_ratio: The percent probability that the preferred
            groups will be chosen over randomly choosen rule definitions from category ``cat``.
        :param int max_recursion: The maximum amount to allow references to recurse
        :param bool auto_process: Whether rules should be automatically pruned and
            shortest reference paths determined. See :any:`gramfuzz.GramFuzzer.preprocess_rules`
            for what would automatically be done.