示例#1
0
 def test_match_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, "Hello")
     self.assertEquals(Match.TOPIC, match.match_type)
     self.assertEquals(topic, match.matched_node)
     self.assertEquals(["Hello"], match.matched_words)
     self.assertEquals("Match=(Topic) Node=(ONEORMORE [*]) Matched=(Hello)", match.to_string())
示例#2
0
 def test_match_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, "Hello")
     self.assertEqual(Match.TOPIC, match.match_type)
     self.assertEqual(topic, match.matched_node)
     self.assertEqual(["Hello"], match.matched_words)
     self.assertEqual("Match=(Topic) Node=(ONEORMORE [*]) Matched=(Hello)", match.to_string(self._client_context.brain.tokenizer))
示例#3
0
 def test_match_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, "Hello")
     self.assertEquals(Match.TOPIC, match.match_type)
     self.assertEquals(topic, match.matched_node)
     self.assertEquals(["Hello"], match.matched_words)
     self.assertEquals("Match=(Topic) Node=(ONEORMORE [*]) Matched=(Hello)", match.to_string(self._bot.brain.tokenizer))
示例#4
0
 def test_match_multi_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, None)
     match.add_word("Hello")
     match.add_word("World")
     self.assertEquals(["Hello", "World"], match.matched_words)
     self.assertEquals("Hello World", match.joined_words(self._bot.brain.tokenizer))
     self.assertEquals("Match=(Topic) Node=(ONEORMORE [*]) Matched=(Hello World)", match.to_string(self._bot.brain.tokenizer))
示例#5
0
 def test_match_no_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, None)
     self.assertEquals(Match.TOPIC, match.match_type)
     self.assertEquals(topic, match.matched_node)
     self.assertEquals([], match.matched_words)
     self.assertEquals("Match=(Topic) Node=(ONEORMORE [*]) Matched=()",
                       match.to_string(self._bot.brain.tokenizer))
示例#6
0
 def test_match_multi_word(self):
     topic = PatternOneOrMoreWildCardNode("*")
     match = Match(Match.TOPIC, topic, None)
     match.add_word("Hello")
     match.add_word("World")
     self.assertEquals(["Hello", "World"], match.matched_words)
     self.assertEquals("Hello World", match.joined_words())
     self.assertEquals("Match=(Topic) Node=(ONEORMORE [*]) Matched=(Hello World)", match.to_string())
    def setUp(self):
        self.parser = TemplateGraph(AIMLParser())
        self.assertIsNotNone(self.parser)

        self.test_brain = None
        self.test_sentence = Sentence("test sentence")

        test_node = PatternOneOrMoreWildCardNode("*")

        self.test_sentence._matched_context = MatchContext(max_search_depth=100, max_search_timeout=-1)
        self.test_sentence._matched_context._matched_nodes = [Match(Match.WORD, test_node, 'one'),
                                                             Match(Match.WORD, test_node, 'two'),
                                                             Match(Match.WORD, test_node, 'three'),
                                                             Match(Match.WORD, test_node, 'four'),
                                                             Match(Match.WORD, test_node, 'five'),
                                                             Match(Match.WORD, test_node, 'six'),
                                                             Match(Match.TOPIC, test_node, '*'),
                                                             Match(Match.THAT, test_node, '*')]

        test_config = ProgramyConfiguration(self.get_client_config(),
                                            brain_config=self.get_brain_config(),
                                            bot_config=self.get_bot_config())

        self.test_bot = Bot(Brain(self.get_brain_config()), config=test_config.bot_configuration)
        self.test_clientid = "testid"

        conversation = self.test_bot.get_conversation(self.test_clientid)
        question = Question.create_from_sentence(self.test_sentence)
        conversation._questions.append(question)
示例#8
0
    def setUp(self):

        self._client = TemplateGraphClient()
        self._client_context = self._client.create_client_context("testid")

        self._graph = self._client_context.bot.brain.aiml_parser.template_parser

        self.test_sentence = Sentence(self._client_context.brain.tokenizer,
                                      "test sentence")

        test_node = PatternOneOrMoreWildCardNode("*")

        self.test_sentence._matched_context = MatchContext(
            max_search_depth=100,
            max_search_timeout=-1,
            tokenizer=self._client_context.brain.tokenizer)
        self.test_sentence._matched_context._matched_nodes = [
            Match(Match.WORD, test_node, 'one'),
            Match(Match.WORD, test_node, 'two'),
            Match(Match.WORD, test_node, 'three'),
            Match(Match.WORD, test_node, 'four'),
            Match(Match.WORD, test_node, 'five'),
            Match(Match.WORD, test_node, 'six'),
            Match(Match.TOPIC, test_node, '*'),
            Match(Match.THAT, test_node, '*')
        ]

        conversation = self._client_context.bot.get_conversation(
            self._client_context)
        question = Question.create_from_sentence(self.test_sentence)
        conversation._questions.append(question)
示例#9
0
    def match_children(self, bot, clientid, children, child_type, words,
                       word_no, context, type, depth):

        if bot.configuration.tab_parse_output is True:
            tabs = TextUtils.get_tabs(depth)
        else:
            tabs = ""

        for child in children:

            result = child.equals(bot, clientid, words, word_no)
            if result.matched is True:
                word_no = result.word_no
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug("%s%s matched %s" %
                                  (tabs, child_type, result.matched_phrase))

                match_node = Match(type, child, result.matched_phrase)

                context.add_match(match_node)

                match = child.consume(bot, clientid, context, words,
                                      word_no + 1, type, depth + 1)
                if match is not None:
                    if logging.getLogger().isEnabledFor(logging.DEBUG):
                        logging.debug("%sMatched %s child, success!" %
                                      (tabs, child_type))
                    return match, word_no
                else:
                    context.pop_match()

        return None, word_no
示例#10
0
    def test_resolve_no_defaults_inside_topic(self):
        root = TemplateNode()
        self.assertIsNotNone(root)
        self.assertIsNotNone(root.children)
        self.assertEqual(len(root.children), 0)

        node = TemplateTopicStarNode(index=1)
        self.assertIsNotNone(node)
        self.assertEqual(1, node.index)

        root.append(node)
        self.assertEqual(len(root.children), 1)

        conversation = Conversation("testid", self.bot)

        question = Question.create_from_text("Hello world")
        question.current_sentence()._response = "Hello matey"
        conversation.record_dialog(question)

        question = Question.create_from_text("How are you")
        question.current_sentence()._response = "Very well thanks"
        conversation.record_dialog(question)

        match = PatternOneOrMoreWildCardNode("*")
        context = MatchContext(max_search_depth=100, max_search_timeout=-1)
        context.add_match(Match(Match.TOPIC, match, "Matched"))
        question.current_sentence()._matched_context = context
        conversation.record_dialog(question)

        self.bot._conversations["testid"] = conversation

        self.assertEqual("Matched", node.resolve(self.bot, "testid"))
示例#11
0
    def match_children(self, bot, clientid, children, child_type, words,
                       word_no, context, match_type, depth):

        tabs = self.get_tabs(bot, depth)

        for child in children:

            result = child.equals(bot, clientid, words, word_no)
            if result.matched is True:
                word_no = result.word_no
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug("%s%s matched %s", tabs, child_type,
                                  result.matched_phrase)

                match_node = Match(match_type, child, result.matched_phrase)

                context.add_match(match_node)

                match = child.consume(bot, clientid, context, words,
                                      word_no + 1, match_type, depth + 1)
                if match is not None:
                    if logging.getLogger().isEnabledFor(logging.DEBUG):
                        logging.debug("%sMatched %s child, success!", tabs,
                                      child_type)
                    return match, word_no
                else:
                    context.pop_match()

        return None, word_no
示例#12
0
    def match_children(self, client_context, children, child_type, words,
                       word_no, context, match_type, depth):

        tabs = self.get_tabs(client_context, depth)

        for child in children:

            result = child.equals(client_context, words, word_no)
            if result.matched is True:
                word_no = result.word_no
                YLogger.debug(client_context, "%s%s matched %s", tabs,
                              child_type, result.matched_phrase)

                match_node = Match(match_type, child, result.matched_phrase)

                context.add_match(match_node)

                match = child.consume(client_context, context, words,
                                      word_no + 1, match_type, depth + 1)
                if match is not None:
                    YLogger.debug(client_context,
                                  "%sMatched %s child, success!", tabs,
                                  child_type)
                    return match, word_no
                else:
                    context.pop_match()

        return None, word_no
示例#13
0
    def test_node_with_star(self):
        root = TemplateNode()
        node = TemplateStarNode()
        root.append(node)

        conversation = Conversation(self._client_context)
        question = Question.create_from_text(
            self._client_context, "Hello world",
            self._client_context.bot.sentence_splitter)
        question.current_sentence()._response = "Hello matey"
        conversation.record_dialog(question)
        question = Question.create_from_text(
            self._client_context, "How are you",
            self._client_context.bot.sentence_splitter)
        question.current_sentence()._response = "Very well thanks"
        conversation.record_dialog(question)
        match = PatternOneOrMoreWildCardNode("*")
        context = MatchContext(max_search_depth=100,
                               max_search_timeout=-1,
                               tokenizer=self._client_context.brain.tokenizer)
        context.add_match(Match(Match.WORD, match, "Matched"))
        question.current_sentence()._matched_context = context

        conversation.record_dialog(question)
        self._client_context.bot._conversation_mgr._conversations[
            "testid"] = conversation

        self.assertEqual("Matched", root.resolve(self._client_context))
示例#14
0
 def test_match_context_pop_push(self):
     topic = PatternOneOrMoreWildCardNode("*")
     context = MatchContext(max_search_depth=100, max_search_timeout=60)
     context.add_match(Match(Match.TOPIC, topic, None))
     self.assertEquals(1, len(context.matched_nodes))
     context.add_match(Match(Match.TOPIC, topic, None))
     self.assertEquals(2, len(context.matched_nodes))
     context.add_match(Match(Match.TOPIC, topic, None))
     self.assertEquals(3, len(context.matched_nodes))
     context.pop_match()
     self.assertEquals(2, len(context.matched_nodes))
     context.pop_match()
     self.assertEquals(1, len(context.matched_nodes))
     context.pop_match()
     self.assertEquals(0, len(context.matched_nodes))
     context.pop_match()
     self.assertEquals(0, len(context.matched_nodes))
示例#15
0
    def match_children(self, client_context, children, child_type, words, word_no, context, match_type, depth):

        tabs = self.get_tabs(client_context, depth)

        client_context.match_type = match_type
        if client_context.match_nlu is False:
            for child in children:

                if depth == 0:
                    words.check_words()

                result = child.equals(client_context, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    YLogger.debug(client_context, "%s%s matched %s", tabs, child_type, result.matched_phrase)

                    match_node = Match(match_type, child, result.matched_phrase)

                    context.add_match(match_node)

                    match = child.consume(client_context, context, words, word_no + 1, match_type, depth+1)
                    if match is not None:
                        YLogger.debug(client_context, "%sMatched %s child, success!", tabs, child_type)
                        return match, word_no
                    else:
                        context.pop_match()
        else:
            for child in reversed(children):  # for NLU matching.

                result = child.equals(client_context, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    YLogger.debug(client_context, "%s%s matched %s", tabs, child_type, result.matched_phrase)

                    match_node = Match(match_type, child, result.matched_phrase)

                    context.add_match(match_node)

                    match = child.consume(client_context, context, words, word_no + 1, match_type, depth+1)
                    if match is not None:
                        YLogger.debug(client_context, "%sMatched %s child, success!", tabs, child_type)
                        return match, word_no
                    else:
                        context.pop_match()

        return None, word_no
示例#16
0
    def test_match_context_star(self):
        word = PatternOneOrMoreWildCardNode("*")
        topic = PatternOneOrMoreWildCardNode("*")
        that = PatternOneOrMoreWildCardNode("*")

        context = MatchContext(max_search_depth=100, max_search_timeout=60)

        context.add_match(Match(Match.WORD, word, "Hello"))
        context.add_match(Match(Match.TOPIC, topic, "Hello Topic"))
        context.add_match(Match(Match.THAT, that, "Hello That"))
        self.assertEquals(3, len(context.matched_nodes))

        self.assertEqual("Hello", context.star(1))
        self.assertIsNone(context.star(2))
        self.assertEqual("Hello Topic", context.topicstar(1))
        self.assertIsNone(context.topicstar(2))
        self.assertEqual("Hello That", context.thatstar(1))
        self.assertIsNone(context.thatstar(2))
示例#17
0
    def test_node_with_star(self):
        root = TemplateNode()
        node = TemplateStarNode()
        root.append(node)

        conversation = Conversation("testid", self.bot)
        question = Question.create_from_text("Hello world")
        question.current_sentence()._response = "Hello matey"
        conversation.record_dialog(question)
        question = Question.create_from_text("How are you")
        question.current_sentence()._response = "Very well thanks"
        conversation.record_dialog(question)
        match = PatternOneOrMoreWildCardNode("*")
        context = MatchContext()
        context.add_match(Match(Match.WORD, match, "Matched"))
        question.current_sentence()._matched_context = context

        conversation.record_dialog(question)
        self.bot._conversations["testid"] = conversation

        self.assertEqual("Matched", root.resolve(self.bot, self.clientid))
示例#18
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        tabs = TextUtils.get_tabs(word_no)

        if depth > context.max_search_depth:
            logging.error("%sMax search depth [%d]exceeded" % (tabs, context.max_search_depth))
            return None

        context_match = Match(type, self, None)
        context.add_match(context_match)
        matches_added = 1

        if self._0ormore_hash is not None:
            logging.debug("%sWildcard is next node, moving on!"%(tabs))
            match = self._0ormore_hash.consume(bot, clientid, context, words, word_no+1, type, depth+1)
            if match is not None:
                return match

        if self._1ormore_underline is not None:
            logging.debug("%sWildcard is next node, moving on!"%(tabs))
            match = self._1ormore_underline.consume(bot, clientid, context, words, word_no+1, type, depth+1)
            if match is not None:
                return match

        if self._0ormore_arrow is not None:
            logging.debug("%sWildcard is next node, moving on!"%(tabs))
            match = self._0ormore_arrow.consume(bot, clientid, context, words, word_no+1, type, depth+1)
            if match is not None:
                return match

        if self._1ormore_star is not None:
            logging.debug("%sWildcard is next node, moving on!"%(tabs))
            match = self._1ormore_star.consume(bot, clientid, context, words, word_no+1, type, depth+1)
            if match is not None:
                return match

        # TODO Add priority words first

        word = words.word(word_no)

        if len(self._children) > 0:
            for child in self._children:
                if child.equals(bot, clientid, word):
                    logging.debug ("%sWildcard child %s matched %s"%(tabs, child._word, word))

                    logging.debug("%s*MATCH -> %s" % (tabs, word))
                    context_match2 = Match(Match.WORD, child, word)
                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(bot, clientid, context, words, word_no+1, type, depth+1)
                    if match is not None:
                        return match

                    if word == PatternTopicNode.TOPIC or word == PatternThatNode.THAT:
                        logging.debug ("Found a topic or that ar the wrong place....")
                        context.pop_matches(matches_added)
                        return None

            logging.debug("%sWildcard %s consumed %s" % (tabs, self._wildcard, word))

            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode, self).consume(bot, clientid, context, words, word_no + 1, type, depth+1)
            if match is not None:
                return match

            word_no += 1
            word = words.word(word_no)

            if word == PatternTopicNode.TOPIC or word == PatternThatNode.THAT:
                logging.debug("Found a topic or that ar the wrong place....")
                context.pop_matches(matches_added)
                return None

            logging.debug("%sWildcard %s consumed %s" % (tabs, self._wildcard, word))
            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode, self).consume(bot, clientid, context, words, word_no + 1, type, depth+1)
            if match is not None:
                return match

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        logging.debug("%sNo children, consume words until next break point" % (tabs))
        while word_no < words.num_words() - 1:
            match = super(PatternZeroOrMoreWildCardNode, self).consume(bot, clientid, context, words, word_no, type, depth+1)
            if match is not None:
                return match

            if word == PatternTopicNode.TOPIC or word == PatternThatNode.THAT:
                logging.debug("Found a topic or that ar the wrong place....")
                context.pop_matches(matches_added)
                return None

            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)
            logging.debug("%sWildcard %s consumed %s" % (tabs, self._wildcard, word))

        logging.debug("%sWildcard %s consumed %s" % (tabs, self._wildcard, word))

        match = super(PatternZeroOrMoreWildCardNode, self).consume(bot, clientid, context, words, word_no, type, depth+1)

        if match is not None:
            return match
        else:
            context.pop_matches(matches_added)
            return None
示例#19
0
 def test_type_to_string(self):
     self.assertEquals("Word", Match.type_to_string(Match.WORD))
     self.assertEquals("Topic", Match.type_to_string(Match.TOPIC))
     self.assertEquals("That", Match.type_to_string(Match.THAT))
     self.assertEquals("Unknown", Match.type_to_string(999))
示例#20
0
    def consume(self, client_context, context, words, word_no, match_type,
                depth):

        tabs = self.get_tabs(client_context, depth)

        if context.search_time_exceeded() is True:
            YLogger.error(client_context,
                          "%sMax search time [%d]secs exceeded", tabs,
                          context.max_search_timeout)
            return None

        if context.search_depth_exceeded(depth) is True:
            YLogger.error(client_context, "%sMax search depth [%d] exceeded",
                          tabs, context.max_search_depth)
            return None

        if word_no >= words.num_words():
            return None

        word = words.word(word_no)
        YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                      self._wildcard, word)
        context_match = Match(match_type, self, word)
        context.add_match(context_match)
        matches_added = 1

        match = self.check_child_is_wildcard(tabs, client_context, context,
                                             words, word_no, match_type, depth)
        if match is not None:
            return match

        if self._topic is not None:
            match = self._topic.consume(client_context, context, words,
                                        word_no + 1, Match.TOPIC, depth + 1)
            if match is not None:
                YLogger.debug(client_context, "%sMatched topic, success!",
                              tabs)
                return match
            if words.word(word_no) == PatternNode.TOPIC:
                YLogger.debug(
                    client_context,
                    "%s Looking for a %s, none give, no match found!", tabs,
                    PatternNode.TOPIC)
                return None

        if self._that is not None:
            match = self._that.consume(client_context, context, words,
                                       word_no + 1, Match.THAT, depth + 1)
            if match is not None:
                YLogger.debug(client_context, "%sMatched that, success!", tabs)
                return match
            if words.word(word_no) == PatternNode.THAT:
                YLogger.debug(
                    client_context,
                    "%s Looking for a %s, none give, no match found!", tabs,
                    PatternNode.THAT)
                return None

        word_no += 1
        if word_no >= words.num_words():
            YLogger.debug(client_context, "%sNo more words", tabs)
            return super(PatternOneOrMoreWildCardNode,
                         self).consume(client_context, context, words, word_no,
                                       match_type, depth + 1)
        word = words.word(word_no)

        if self._children:
            for child in self._children:

                result = child.equals(client_context, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    YLogger.debug(client_context,
                                  "%sWildcard child matched %s", tabs,
                                  result.matched_phrase)

                    context_match2 = Match(Match.WORD, child,
                                           result.matched_phrase)

                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(client_context, context, words,
                                          word_no + 1, match_type, depth + 1)
                    if match is not None:
                        return match

            if self.invalid_topic_or_that(tabs, client_context, word, context,
                                          matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                          self._wildcard, word)
            context_match.add_word(word)

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        YLogger.debug(client_context,
                      "%sNo children, consume words until next break point",
                      tabs)

        while word_no < words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no, match_type, depth + 1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, client_context, word, context,
                                          matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                          self._wildcard, word)
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                      self._wildcard, word)
        context_match.add_word(word)

        if word_no == words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no + 1, match_type, depth + 1)
        else:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no, match_type, depth + 1)

        if match is not None:
            return match
        context.pop_matches(matches_added)
        return None
示例#21
0
    def test_attrib_with_html(self):
        template = ET.fromstring("""
            <template>
                <a target="_new" href="http://www.google.com/search?q=&lt;star /&gt;"> Google Search </a>
            </template>
            """)

        conversation = Conversation(self._client_context)
        question = Question.create_from_text(
            self._client_context, "GOOGLE AIML",
            self._client_context.bot.sentence_splitter)
        question.current_sentence()._response = "OK"
        conversation.record_dialog(question)
        match = PatternOneOrMoreWildCardNode("*")
        context = MatchContext(max_search_depth=100,
                               max_search_timeout=-1,
                               tokenizer=self._client_context.brain.tokenizer)
        context.add_match(Match(Match.WORD, match, "AIML"))
        question.current_sentence()._matched_context = context
        self._client_context.bot._conversation_mgr._conversations[
            "testid"] = conversation

        ast = self._graph.parse_template_expression(template)
        self.assertIsNotNone(ast)
        self.assertIsInstance(ast, TemplateNode)
        self.assertIsNotNone(ast.children)
        self.assertEqual(len(ast.children), 1)

        xml_node = ast.children[0]
        self.assertIsNotNone(xml_node)
        self.assertIsInstance(xml_node, TemplateXMLNode)

        attribs = xml_node.attribs
        self.assertEquals(2, len(attribs))

        self.assertIsInstance(attribs['target'], TemplateWordNode)
        target = attribs['target']
        self.assertEquals(len(target.children), 0)
        self.assertEquals("_new", target.word)

        self.assertIsInstance(attribs['href'], TemplateNode)
        href = attribs['href']
        self.assertEquals(len(href.children), 3)

        self.assertIsInstance(href.children[0], TemplateWordNode)
        self.assertEquals('http://www.google.com/search?q=',
                          href.children[0].word)

        self.assertIsInstance(href.children[1], TemplateNode)
        self.assertEquals(1, len(href.children[1].children))
        star = href.children[1].children[0]
        self.assertIsInstance(star, TemplateStarNode)

        self.assertIsInstance(href.children[2], TemplateWordNode)
        self.assertEquals('', href.children[2].word)

        result = xml_node.resolve(self._client_context)
        self.assertIsNotNone(result)
        self.assertEquals(
            result,
            '<a target="_new" href="http://www.google.com/search?q=AIML">Google Search</a>'
        )
示例#22
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        tabs = TextUtils.get_tabs(word_no)

        if depth > context.max_search_depth:
            logging.error("%sMax search depth [%d]exceeded" %
                          (tabs, context.max_search_depth))
            return None

        if word_no >= words.num_words():
            return None

        word = words.word(word_no)
        logging.debug("%sWildcard %s matched %s" %
                      (tabs, self._wildcard, word))
        context_match = Match(type, self, word)
        context.add_match(context_match)
        matches_add = 1

        match = self.check_child_is_wildcard(tabs, bot, clientid, context,
                                             words, word_no, type, depth)
        if match is not None:
            return match

        if self._topic is not None:
            match = self._topic.consume(bot, clientid, context, words,
                                        word_no + 1, Match.TOPIC, depth + 1)
            if match is not None:
                logging.debug("%sMatched topic, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.TOPIC:
                logging.debug(
                    "%s Looking for a %s, none give, no match found!" %
                    (tabs, PatternNode.TOPIC))
                return None

        if self._that is not None:
            match = self._that.consume(bot, clientid, context, words,
                                       word_no + 1, Match.THAT, depth + 1)
            if match is not None:
                logging.debug("%sMatched that, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.THAT:
                logging.debug(
                    "%s Looking for a %s, none give, no match found!" %
                    (tabs, PatternNode.THAT))
                return None

        # TODO Add priority words first

        word_no += 1
        if word_no >= words.num_words():
            logging.debug("%sNo more words" % (tabs))
            return super(PatternOneOrMoreWildCardNode,
                         self).consume(bot, clientid, context, words, word_no,
                                       type, depth + 1)
        word = words.word(word_no)

        if len(self._children) > 0:
            for child in self._children:
                if child.equals(bot, clientid, word):
                    logging.debug("%sWildcard child %s matched %s" %
                                  (tabs, child._word, word))
                    context_match2 = Match(Match.WORD, child, word)
                    context.add_match(context_match2)
                    matches_add += 1
                    skip_to = self.consume_set_phrase(bot, clientid, context,
                                                      child, context_match2,
                                                      words, word_no)
                    if skip_to is None:
                        continue
                    else:
                        word_no = skip_to
                    match = child.consume(bot, clientid, context, words,
                                          word_no + 1, type, depth + 1)
                    if match is not None:
                        return match

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_add) is True:
                return None

            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
            context_match.add_word(word)

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_add)
                return None
            word = words.word(word_no)

        logging.debug("%sNo children, consume words until next break point" %
                      (tabs))
        while word_no < words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_add) is True:
                return None

            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        logging.debug("%sWildcard %s matched %s" %
                      (tabs, self._wildcard, word))
        context_match.add_word(word)

        if word_no == words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
        else:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)

        if match is not None:
            return match
        else:
            context.pop_matches(matches_add)
            return None
示例#23
0
    def consume(self, client_context, context, words, word_no, match_type,
                depth):

        tabs = self.get_tabs(client_context, depth)

        #TODO uncomment this section
        # if context.search_time_exceeded() is True:
        #     YLogger.error(client_context, "%sMax search time [%d]secs exceeded", tabs, context.max_search_timeout)
        #     return None

        if context.search_depth_exceeded(depth) is True:
            YLogger.error(client_context, "%sMax search depth [%d] exceeded",
                          tabs, context.max_search_depth)
            return None

        context_match = Match(match_type, self, None)
        context.add_match(context_match)
        matches_added = 1

        match = self.check_child_is_wildcard(tabs, client_context, context,
                                             words, word_no, match_type, depth)
        if match is not None:
            return match

        word = words.word(word_no)

        if self._children:
            for child in self._children:

                result = child.equals(client_context, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    YLogger.debug(client_context,
                                  "%sWildcard child matched %s", tabs,
                                  result.matched_phrase)

                    context_match2 = Match(Match.WORD, child,
                                           result.matched_phrase)

                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(client_context, context, words,
                                          word_no + 1, match_type, depth + 1)
                    if match is not None:
                        return match

                    if self.invalid_topic_or_that(tabs, client_context, word,
                                                  context,
                                                  matches_added) is True:
                        return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                          self._wildcard, word)
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no + 1, match_type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            word = words.word(word_no)

            if self.invalid_topic_or_that(tabs, client_context, word, context,
                                          matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                          self._wildcard, word)
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no + 1, match_type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        YLogger.debug(client_context,
                      "%sNo children, consume words until next break point",
                      tabs)
        while word_no < words.num_words() - 1:
            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(client_context, context, words,
                                        word_no, match_type, depth + 1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, client_context, word, context,
                                          matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs,
                          self._wildcard, word)
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        match = super(PatternZeroOrMoreWildCardNode,
                      self).consume(client_context, context, words, word_no,
                                    match_type, depth + 1)

        if match is not None:
            return match
        context.pop_matches(matches_added)
        return None
示例#24
0
    def consume(self, client_context, context, words, word_no, match_type, depth):

        tabs = self.get_tabs(client_context, depth)

        if context.search_time_exceeded() is True:
            YLogger.error(client_context, "%sMax search time [%d]secs exceeded", tabs, context.max_search_timeout)
            return None

        if context.search_depth_exceeded(depth) is True:
            YLogger.error(client_context, "%sMax search depth [%d] exceeded", tabs, context.max_search_depth)
            return None

        if word_no >= words.num_words():
            return None

        word = words.word(word_no)
        YLogger.debug(client_context, "%sWildcard %s matched %s", tabs, self._wildcard, word)
        context_match = Match(match_type, self, word)
        context.add_match(context_match)
        matches_added = 1

        match = self.check_child_is_wildcard(tabs, client_context, context, words, word_no, match_type, depth)
        if match is not None:
            return match

        if self._topic is not None:
            match = self._topic.consume(client_context, context, words, word_no+1, Match.TOPIC, depth+1)
            if match is not None:
                YLogger.debug(client_context, "%sMatched topic, success!", tabs)
                return match
            if words.word(word_no) == PatternNode.TOPIC:
                YLogger.debug(client_context, "%s Looking for a %s, none give, no match found!", tabs, PatternNode.TOPIC)
                return None

        if self._that is not None:
            match = self._that.consume(client_context, context, words, word_no+1, Match.THAT, depth+1)
            if match is not None:
                YLogger.debug(client_context, "%sMatched that, success!", tabs)
                return match
            if words.word(word_no) == PatternNode.THAT:
                YLogger.debug(client_context, "%s Looking for a %s, none give, no match found!", tabs, PatternNode.THAT)
                return None

        word_no += 1
        if word_no >= words.num_words():
            YLogger.debug(client_context, "%sNo more words", tabs)
            return super(PatternOneOrMoreWildCardNode, self).consume(client_context, context, words, word_no, match_type, depth+1)
        word = words.word(word_no)

        if self._children:
            for child in self._children:

                result = child.equals(client_context, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    YLogger.debug(client_context, "%sWildcard child matched %s", tabs, result.matched_phrase)

                    context_match2 = Match(Match.WORD, child, result.matched_phrase)

                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(client_context, context, words, word_no+1, match_type, depth+1)
                    if match is not None:
                        return match

            if self.invalid_topic_or_that(tabs, client_context,  word, context, matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs, self._wildcard, word)
            context_match.add_word(word)

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        YLogger.debug(client_context, "%sNo children, consume words until next break point", tabs)

        while word_no < words.num_words()-1:
            match = super(PatternOneOrMoreWildCardNode, self).consume(client_context, context, words, word_no, match_type, depth+1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, client_context, word, context, matches_added) is True:
                return None

            YLogger.debug(client_context, "%sWildcard %s matched %s", tabs, self._wildcard, word)
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        YLogger.debug(client_context, "%sWildcard %s matched %s", tabs, self._wildcard, word)
        context_match.add_word(word)

        if word_no == words.num_words()-1:
            match = super(PatternOneOrMoreWildCardNode, self).consume(client_context, context, words, word_no+1, match_type, depth+1)
        else:
            match = super(PatternOneOrMoreWildCardNode, self).consume(client_context, context, words, word_no, match_type, depth+1)

        if match is not None:
            return match
        context.pop_matches(matches_added)
        return None
示例#25
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        tabs = TextUtils.get_tabs(word_no)

        if depth > context.max_search_depth:
            logging.error("%sMax search depth [%d]exceeded" %
                          (tabs, context.max_search_depth))
            return None

        if word_no >= words.num_words():
            if self._template is not None:
                logging.debug("%sFound a template, success!" % (tabs))
                return self._template
            else:
                logging.debug(
                    "%sNo more words and no template, no match found!" %
                    (tabs))
                #context.pop_match()
                return None

        if self._topic is not None:
            match = self._topic.consume(bot, clientid, context, words, word_no,
                                        Match.TOPIC, depth + 1)
            if match is not None:
                logging.debug("%sMatched topic, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.TOPIC:
                logging.debug(
                    "%s Looking for a %s, none give, no match found!" %
                    (tabs, PatternNode.TOPIC))
                return None

        if self._that is not None:
            match = self._that.consume(bot, clientid, context, words, word_no,
                                       Match.THAT, depth + 1)
            if match is not None:
                logging.debug("%sMatched that, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.THAT:
                logging.debug(
                    "%s Looking for a %s, none give, no match found!" %
                    (tabs, PatternNode.THAT))
                return None

        for child in self._priority_words:
            if child.equals(bot, clientid, words.word(word_no)):
                logging.debug("%sPriority %s matched %s" %
                              (tabs, child._word, words.word(word_no)))
                match_node = Match(type, child, words.word(word_no))
                context.add_match(match_node)

                match = child.consume(bot, clientid, context, words,
                                      word_no + 1, type, depth + 1)
                if match is not None:
                    logging.debug("%sMatched child, success!" % (tabs))
                    return match
                else:
                    context.pop_match()

        if self._0ormore_hash is not None:
            match = self._0ormore_hash.consume(bot, clientid, context, words,
                                               word_no, type, depth + 1)
            if match is not None:
                logging.debug("%sMatched 0 or more hash, success!" % (tabs))
                return match

        if self._1ormore_underline is not None:
            match = self._1ormore_underline.consume(bot, clientid, context,
                                                    words, word_no, type,
                                                    depth + 1)
            if match is not None:
                logging.debug("%sMatched 1 or more underline, success!" %
                              (tabs))
                return match

        for child in self._children:
            if child.equals(bot, clientid, words.word(word_no)):
                logging.debug("%sChild %s matched %s" %
                              (tabs, child._word, words.word(word_no)))
                match_node = Match(type, child, words.word(word_no))
                context.add_match(match_node)

                skip_to = self.consume_set_phrase(bot, clientid, context,
                                                  child, match_node, words,
                                                  word_no)
                if skip_to is None:
                    continue
                else:
                    word_no = skip_to

                match = child.consume(bot, clientid, context, words,
                                      word_no + 1, type, depth + 1)
                if match is not None:
                    logging.debug("%sMatched child, success!" % (tabs))
                    return match
                else:
                    context.pop_match()

        if self._0ormore_arrow is not None:
            match = self._0ormore_arrow.consume(bot, clientid, context, words,
                                                word_no, type, depth + 1)
            if match is not None:
                logging.debug("%sMatched 0 or more arrow, success!" % (tabs))
                return match

        if self._1ormore_star is not None:
            match = self._1ormore_star.consume(bot, clientid, context, words,
                                               word_no, type, depth + 1)
            if match is not None:
                logging.debug("%sMatched 1 or more star, success!" % (tabs))
                return match

        logging.debug("%sNo match for %s, trying another path" %
                      (tabs, words.word(word_no)))
        return None
示例#26
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        if bot.configuration.tab_parse_output is True:
            tabs = TextUtils.get_tabs(depth)
        else:
            tabs = ""

        if context.search_time_exceeded() is True:
            if logging.getLogger().isEnabledFor(logging.ERROR):
                logging.error("%sMax search time [%d]secs exceeded" %
                              (tabs, context.max_search_timeout))
            return None

        if context.search_depth_exceeded(depth) is True:
            if logging.getLogger().isEnabledFor(logging.ERROR):
                logging.error("%sMax search depth [%d] exceeded" %
                              (tabs, context.max_search_depth))
            return None

        if word_no >= words.num_words():
            return None

        word = words.word(word_no)
        if logging.getLogger().isEnabledFor(logging.DEBUG):
            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
        context_match = Match(type, self, word)
        context.add_match(context_match)
        matches_added = 1

        match = self.check_child_is_wildcard(tabs, bot, clientid, context,
                                             words, word_no, type, depth)
        if match is not None:
            return match

        if self._topic is not None:
            match = self._topic.consume(bot, clientid, context, words,
                                        word_no + 1, Match.TOPIC, depth + 1)
            if match is not None:
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug("%sMatched topic, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.TOPIC:
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug(
                        "%s Looking for a %s, none give, no match found!" %
                        (tabs, PatternNode.TOPIC))
                return None

        if self._that is not None:
            match = self._that.consume(bot, clientid, context, words,
                                       word_no + 1, Match.THAT, depth + 1)
            if match is not None:
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug("%sMatched that, success!" % (tabs))
                return match
            if words.word(word_no) == PatternNode.THAT:
                if logging.getLogger().isEnabledFor(logging.DEBUG):
                    logging.debug(
                        "%s Looking for a %s, none give, no match found!" %
                        (tabs, PatternNode.THAT))
                return None

        # TODO Add priority words first

        word_no += 1
        if word_no >= words.num_words():
            if logging.getLogger().isEnabledFor(logging.DEBUG):
                logging.debug("%sNo more words" % (tabs))
            return super(PatternOneOrMoreWildCardNode,
                         self).consume(bot, clientid, context, words, word_no,
                                       type, depth + 1)
        word = words.word(word_no)

        if len(self._children) > 0:
            for child in self._children:

                result = child.equals(bot, clientid, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    if logging.getLogger().isEnabledFor(logging.DEBUG):
                        logging.debug("%sWildcard child matched %s" %
                                      (tabs, result.matched_phrase))

                    context_match2 = Match(Match.WORD, child,
                                           result.matched_phrase)

                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(bot, clientid, context, words,
                                          word_no + 1, type, depth + 1)
                    if match is not None:
                        return match

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_added) is True:
                return None

            if logging.getLogger().isEnabledFor(logging.DEBUG):
                logging.debug("%sWildcard %s matched %s" %
                              (tabs, self._wildcard, word))
            context_match.add_word(word)

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        if logging.getLogger().isEnabledFor(logging.DEBUG):
            logging.debug(
                "%sNo children, consume words until next break point" % (tabs))
        while word_no < words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_added) is True:
                return None

            if logging.getLogger().isEnabledFor(logging.DEBUG):
                logging.debug("%sWildcard %s matched %s" %
                              (tabs, self._wildcard, word))
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        if logging.getLogger().isEnabledFor(logging.DEBUG):
            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
        context_match.add_word(word)

        if word_no == words.num_words() - 1:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
        else:
            match = super(PatternOneOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)

        if match is not None:
            return match
        else:
            context.pop_matches(matches_added)
            return None
示例#27
0
 def test_type_to_string(self):
     self.assertEquals("Word", Match.type_to_string(Match.WORD))
     self.assertEquals("Topic", Match.type_to_string(Match.TOPIC))
     self.assertEquals("That", Match.type_to_string(Match.THAT))
     self.assertEquals("Unknown", Match.type_to_string(999))
示例#28
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        tabs = TextUtils.get_tabs(word_no)

        if depth > context.max_search_depth:
            logging.error("%sMax search depth [%d]exceeded" %
                          (tabs, context.max_search_depth))
            return None

        context_match = Match(type, self, None)
        context.add_match(context_match)
        matches_added = 1

        if self._0ormore_hash is not None:
            logging.debug("%sWildcard is next node, moving on!" % (tabs))
            match = self._0ormore_hash.consume(bot, clientid, context, words,
                                               word_no + 1, type, depth + 1)
            if match is not None:
                return match

        if self._1ormore_underline is not None:
            logging.debug("%sWildcard is next node, moving on!" % (tabs))
            match = self._1ormore_underline.consume(bot, clientid, context,
                                                    words, word_no + 1, type,
                                                    depth + 1)
            if match is not None:
                return match

        if self._0ormore_arrow is not None:
            logging.debug("%sWildcard is next node, moving on!" % (tabs))
            match = self._0ormore_arrow.consume(bot, clientid, context, words,
                                                word_no + 1, type, depth + 1)
            if match is not None:
                return match

        if self._1ormore_star is not None:
            logging.debug("%sWildcard is next node, moving on!" % (tabs))
            match = self._1ormore_star.consume(bot, clientid, context, words,
                                               word_no + 1, type, depth + 1)
            if match is not None:
                return match

        # TODO Add priority words first

        word = words.word(word_no)

        if len(self._children) > 0:
            for child in self._children:
                if child.equals(bot, clientid, word):
                    logging.debug("%sWildcard child %s matched %s" %
                                  (tabs, child._word, word))

                    logging.debug("%s*MATCH -> %s" % (tabs, word))
                    context_match2 = Match(Match.WORD, child, word)
                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(bot, clientid, context, words,
                                          word_no + 1, type, depth + 1)
                    if match is not None:
                        return match

                    if word == PatternTopicNode.TOPIC:
                        logging.debug("1 Found a topic at the wrong place....")
                        context.pop_matches(matches_added)
                        return None

                    if word == PatternThatNode.THAT:
                        logging.debug("Found a that at the wrong place....")
                        context.pop_matches(matches_added)
                        return None

            logging.debug("%sWildcard %s consumed %s" %
                          (tabs, self._wildcard, word))

            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            word = words.word(word_no)

            if word == PatternTopicNode.TOPIC:
                logging.debug("2 Found a topic at the wrong place....")
                context.pop_matches(matches_added)
                return None

            if word == PatternThatNode.THAT:
                logging.debug("Found a that at the wrong place....")
                context.pop_matches(matches_added)
                return None

            logging.debug("%sWildcard %s consumed %s" %
                          (tabs, self._wildcard, word))
            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        logging.debug("%sNo children, consume words until next break point" %
                      (tabs))
        while word_no < words.num_words() - 1:
            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)
            if match is not None:
                return match

            if word == PatternTopicNode.TOPIC:
                logging.debug("3 Found a topic at the wrong place....")
                context.pop_matches(matches_added)
                return None

            if word == PatternThatNode.THAT:
                logging.debug("Found a that at the wrong place....")
                context.pop_matches(matches_added)
                return None

            logging.debug("%s*MATCH -> %s" % (tabs, word))
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)
            logging.debug("%sWildcard %s consumed %s" %
                          (tabs, self._wildcard, word))

        logging.debug("%sWildcard %s consumed %s" %
                      (tabs, self._wildcard, word))

        match = super(PatternZeroOrMoreWildCardNode,
                      self).consume(bot, clientid, context, words, word_no,
                                    type, depth + 1)

        if match is not None:
            return match
        else:
            context.pop_matches(matches_added)
            return None
示例#29
0
    def consume(self, bot, clientid, context, words, word_no, type, depth):

        tabs = TextUtils.get_tabs(depth)

        if depth > context.max_search_depth:
            logging.error("%sMax search depth [%d] exceeded" %
                          (tabs, context.max_search_depth))
            return None

        context_match = Match(type, self, None)
        context.add_match(context_match)
        matches_added = 1

        match = self.check_child_is_wildcard(tabs, bot, clientid, context,
                                             words, word_no, type, depth)
        if match is not None:
            return match

        # TODO Add priority words first

        word = words.word(word_no)

        if len(self._children) > 0:
            for child in self._children:

                result = child.equals(bot, clientid, words, word_no)
                if result.matched is True:
                    word_no = result.word_no
                    logging.debug("%sWildcard child matched %s" %
                                  (tabs, result.matched_phrase))

                    context_match2 = Match(Match.WORD, child,
                                           result.matched_phrase)

                    context.add_match(context_match2)
                    matches_added += 1

                    match = child.consume(bot, clientid, context, words,
                                          word_no + 1, type, depth + 1)
                    if match is not None:
                        return match

                    if self.invalid_topic_or_that(tabs, word, context,
                                                  matches_added) is True:
                        return None

            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            word = words.word(word_no)

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_added) is True:
                return None

            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
            context_match.add_word(word)

            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
            if match is not None:
                return match

            word_no += 1
            if word_no >= words.num_words():
                context.pop_matches(matches_added)
                return None
            word = words.word(word_no)

        logging.debug("%sNo children, consume words until next break point" %
                      (tabs))
        while word_no < words.num_words() - 1:
            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)
            if match is not None:
                return match

            if self.invalid_topic_or_that(tabs, word, context,
                                          matches_added) is True:
                return None

            logging.debug("%sWildcard %s matched %s" %
                          (tabs, self._wildcard, word))
            context_match.add_word(word)

            word_no += 1
            word = words.word(word_no)

        if word_no == words.num_words() - 1:
            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words,
                                        word_no + 1, type, depth + 1)
        else:
            match = super(PatternZeroOrMoreWildCardNode,
                          self).consume(bot, clientid, context, words, word_no,
                                        type, depth + 1)

        if match is not None:
            return match
        else:
            context.pop_matches(matches_added)
            return None