def update_list(self, lst): """ Update a list's content loaded in this grammar. **Internal:** this method is normally *not* called directly by the user, but instead automatically when the list itself is modified by the user. """ self._log_load.debug("Grammar %s: updating list %s.", self._name, lst.name) # Check for correct type and valid list instance. # assert self._loaded if lst not in self._lists: raise GrammarError("List '%s' not loaded in this grammar." % lst.name) elif [ True for w in lst.get_list_items() if not isinstance(w, string_types) ]: raise GrammarError("List '%s' contains objects other than" "strings." % lst.name) self._engine.update_list(lst, self)
def add_list(self, lst): """ Add a list to this grammar. Lists **cannot** be added to grammars that are currently loaded. :param lst: Dragonfly list :type lst: ListBase """ self._log_load.debug("Grammar %s: adding list %s.", self._name, lst.name) # Make sure that the list can be loaded and is not a duplicate. if self._loaded: raise GrammarError("Cannot add list while loaded.") elif not isinstance(lst, ListBase): raise GrammarError("Invalid list object: %s" % lst) for l in self._lists: if l.name == lst.name: if l is lst: # This list was already added previously, so ignore. return raise GrammarError("Two lists with the same name '%s' not" " allowed." % lst.name) # Append the list to this grammar object's internal list. self._lists.append(lst) lst.grammar = self
def decode_rollback(self, element): frame = self._get_frame_from_depth() if not frame or frame.actor != element: raise GrammarError("Recognition decoding stack broken") if frame is self._stack[-1]: # Last parser on the stack, rollback. self._index = frame.begin else: raise GrammarError("Recognition decoding stack broken") self._log_step(element, "rollback")
def decode_success(self, element): self._log_step(element, "success") frame = self._get_frame_from_depth() if not frame or frame.actor != element: raise GrammarError("Recognition decoding stack broken.") frame.end = self._index self._depth -= 1
def add_rule(self, rule): """ Add a rule to this grammar. The following rules apply when adding rules into grammars: #. Rules **cannot** be added to grammars that are currently loaded. #. Two or more rules with the same name are **not** allowed. .. warning:: Note that while adding the same ``Rule`` object to more than one grammar is allowed, it is **not** recommended! This is because the context and active/enabled states of these rules will not function correctly if used. It is better to use *separate* ``Rule`` instances for each grammar instead. :param rule: Dragonfly rule :type rule: Rule """ self._log_load.debug("Grammar %s: adding rule %s.", self._name, rule.name) # Check for correct type and duplicate rules or rule names. if self._loaded: raise GrammarError("Cannot add rule while loaded.") elif not isinstance(rule, Rule): raise GrammarError("Invalid rule object: %s" % rule) elif rule in self._rules: return elif rule.imported: return elif [True for r in self._rules if r.name == rule.name]: raise GrammarError("Two rules with the same name '%s' not" " allowed." % rule.name) elif rule.grammar is not None and rule.exported: self._log_load.warning( "Exported rule %s is already in grammar " "%s, adding it to grammar %s is not " "recommended.", rule.name, rule.grammar.name, self._name) # Append the rule to this grammar object's internal list. self._rules.append(rule) rule.grammar = self
def deactivate(self): if not self._grammar: raise GrammarError("A Dragonfly rule cannot be deactivated " "before it is bound to a grammar.") if self._active: try: self._grammar.deactivate_rule(self) except Exception as e: self._log.warning("Failed to deactivate rule: %s (%s)", self, e) self._active = False
def activate(self, force=False): if not self._grammar: raise GrammarError("A Dragonfly rule cannot be activated " "before it is bound to a grammar.") if not self._enabled: if self._active: self.deactivate() return if not self._active or force: self._grammar.activate_rule(self) self._active = True
def remove_list(self, lst): """ Remove a list from this grammar. Lists **cannot** be removed from grammars that are currently loaded. :param lst: Dragonfly list :type lst: ListBase """ self._log_load.debug("Grammar %s: removing list %s.", self._name, lst.name) # Check for correct type. if self._loaded: raise GrammarError("Cannot remove list while loaded.") elif not isinstance(lst, ListBase): raise GrammarError("Invalid list object: %s" % lst) elif lst.name not in [l.name for l in self._lists]: return # Remove the list from this grammar object's internal list. self._lists.remove(lst) lst.grammar = None
def remove_rule(self, rule): """ Remove a rule from this grammar. Rules **cannot** be removed from grammars that are currently loaded. :param rule: Dragonfly rule :type rule: Rule """ self._log_load.debug("Grammar %s: removing rule %s.", self._name, rule.name) # Check for correct type. if self._loaded: raise GrammarError("Cannot remove rule while loaded.") elif not isinstance(rule, Rule): raise GrammarError("Invalid rule object: %s" % rule) elif rule not in self._rules: return # Remove the rule from this grammar object's internal list. self._rules.remove(rule) rule.grammar = None
def add_dependency(self, dep): """ Add a rule or list dependency to this grammar. **Internal:** this method is normally *not* called by the user, but instead automatically during grammar compilation. """ if isinstance(dep, Rule): self.add_rule(dep) elif isinstance(dep, ListBase): self.add_list(dep) else: raise GrammarError("Unknown dependency type %s." % dep)
def rule(self, delta=0): i = self._index + delta if 0 <= i < len(self._results): rule_id = self._results[i][1] if 0 <= rule_id < len(self._rule_names): return self._rule_names[rule_id] elif rule_id == 1000000: return "dgndictation" elif rule_id == 1000001: return "dgnletters" else: word = self._results[i][0] raise GrammarError("Malformed recognition data:" " word %r, rule id %d." % (word, rule_id)) else: return None
def process_begin(self, executable, title, handle): """ Start of phrase callback. This method is called when the speech recognition engine detects that the user has begun to speak a phrase. It is called by the rule's containing grammar if the grammar and this rule are active. The default implementation of this method checks whether this rule's context matches, and if it does this method calls :meth:`._process_begin`. Arguments: - *executable* -- the full path to the module whose window is currently in the foreground - *title* -- window title of the foreground window - *handle* -- window handle to the foreground window """ if not self.grammar: raise GrammarError("A Dragonfly rule cannot be processed " "before it is bound to a grammar.") if not self._enabled: if self._active: self.deactivate() return if self._context: if self._context.matches(executable, title, handle): if not self._active: self.activate() self._process_begin() else: if self._active: self.deactivate() else: if not self._active: self.activate() self._process_begin()
def deactivate_rule(self, rule): """ Deactivate a rule loaded in this grammar. **Internal:** this method is normally *not* called directly by the user, but instead automatically when the rule itself is deactivated by the user. """ self._log_load.debug("Grammar %s: deactivating rule %s.", self._name, rule.name) # Check for correct type and valid rule instance. assert self._loaded assert isinstance(rule, Rule), \ "Dragonfly rule objects must be of the type dragonfly.rule.Rule" if rule not in self._rules: raise GrammarError("Rule '%s' not loaded in this grammar." % rule.name) if not rule.exported: return # Deactivate the given rule. self._engine.deactivate_rule(rule, self)
def _set_engine(self, engine): if self._loaded: raise GrammarError(" Grammar %s: Cannot set engine while " "loaded." % self) self._engine = engine