def test_add_pattern_to_graph_basic_zero_or_more_with_patterns(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') element = ET.fromstring('<pattern># HELLO</pattern>') template_graph_root = TemplateWordNode("RESPONSE1") graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) element = ET.fromstring('<pattern>WELL HI THERE</pattern>') template_graph_root = TemplateWordNode("RESPONSE2") graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) matcher = PatternMatcher(graph) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence(""), [], Sentence("*"), [], Sentence("*"), [])) template = matcher.match(self.bot, self.clientid, Sentence("HELLO"), [], Sentence("*"), [], Sentence("*"), []) self.assertIsNotNone(template) self.assertIsInstance(template, PatternTemplateNode) self.assertEqual(template.template.resolve(None, None), "RESPONSE1") template = matcher.match(self.bot, self.clientid, Sentence("WELL HI THERE"), [], Sentence("*"), [], Sentence("*"), []) self.assertIsNotNone(template) self.assertIsInstance(template, PatternTemplateNode) self.assertEqual(template.template.resolve(None, None), "RESPONSE2")
def test_add_pattern_to_graph_basic_one_or_more(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None element = ET.fromstring('<pattern>*</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root._1ormore_star) self.assertIsInstance(graph.root._1ormore_star, PatternOneOrMoreWildCardNode) self.assertEqual(graph.root._1ormore_star.wildcard, "*") self.assertEqual(len(graph.root._priority_words), 0) self.assertIsNone(graph.root._0ormore_arrow) self.assertIsNone(graph.root._0ormore_hash) self.assertIsNone(graph.root._1ormore_underline) matcher = PatternMatcher(graph) self.assertIsNone( matcher.match(self.bot, self.clientid, Sentence(""), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("test1"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("test1 test2"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("test1 test2 test3"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_basic(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None element = ET.fromstring("<pattern>test1</pattern>") graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 1) self.assertIsInstance(graph.root.children[0], PatternWordNode) self.assertEqual(graph.root.children[0].word, "test1") element = ET.fromstring("<pattern>test2</pattern>") graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 2) self.assertIsInstance(graph.root.children[0], PatternWordNode) self.assertEqual(graph.root.children[0].word, "test1") self.assertIsInstance(graph.root.children[0], PatternWordNode) self.assertEqual(graph.root.children[1].word, "test2") matcher = PatternMatcher(graph) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test1"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test2"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence("test1 test2"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence("test2 test1"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_basic_set_name_attrib(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None self.bot.brain.sets._sets["SET1"] = ["val1", "val2", "val3", "val5"] element = ET.fromstring('<pattern><set name="set1" /></pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 1) self.assertIsInstance(graph.root.children[0], PatternSetNode) self.assertEqual(graph.root.children[0].word, "SET1") matcher = PatternMatcher(graph) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("val1"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("val2"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("val3"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNone( matcher.match(self.bot, self.clientid, Sentence("val4"), [], Sentence("*"), [], Sentence("*"), []))
def test_mixed_priorty_and_star(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A $B C</pattern>") pattern_element2 = ET.fromstring("<pattern>A * C</pattern>") pattern_element3 = ET.fromstring("<pattern>A D C</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node1 = TemplateNode() template_node2 = TemplateNode() template_node3 = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node1) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node2) graph.add_pattern_to_graph(pattern_element3, topic_element, that_element, template_node3) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node1) self.assertEqual(len(pattern_stars), 0) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A F C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node2) self.assertEqual(len(pattern_stars), 1) self.assertEqual("F", pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A D C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node3) self.assertEqual(len(pattern_stars), 0) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_add_pattern_to_graph_basic_bot_name_attrib(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None self.bot.brain.properties._properties['bot1'] = 'val1' element = ET.fromstring('<pattern><bot name="bot1" /></pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 1) self.assertIsInstance(graph.root.children[0], PatternBotNode) self.assertEqual(graph.root.children[0].word, "bot1") matcher = PatternMatcher(graph) self.assertIsNotNone( matcher.match(self.bot, self.clientid, Sentence("val1"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNone( matcher.match(self.bot, self.clientid, Sentence("val2"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_one_or_more_last(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None element = ET.fromstring('<pattern>XXX *</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) matcher = PatternMatcher(graph) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence(""), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("XXX HELLO THERE YYY"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_zero_or_more_multiple(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None element = ET.fromstring('<pattern>XXX # YYY # ZZZ</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) matcher = PatternMatcher(graph) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence(""), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("XXX Hello YYY There ZZZ"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_basic_zero_or_more(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None element = ET.fromstring('<pattern>#</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) matcher = PatternMatcher(graph) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence(""), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test1"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test1 test2"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test1 test2 test3"), [], Sentence("*"), [], Sentence("*"), []))
def test_multiple_hashes_with_star_and_that(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A # # D</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>THAT</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C C2 D"), pattern_stars, Sentence("THIS"), topic_stars, Sentence("THAT"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(len(pattern_stars), 2) self.assertEqual('B', pattern_stars[0]) self.assertEqual('C C2', pattern_stars[1]) self.assertEqual(len(topic_stars), 1) self.assertEqual("THIS", topic_stars[0]) self.assertEqual(len(that_stars), 0)
def test_simple_arrow_and_hash_at_end(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A ^</pattern>") pattern_element2 = ET.fromstring("<pattern>A #</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node1 = TemplateNode() template_node2 = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node1) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node2) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node2) self.assertEqual(1, len(pattern_stars)) self.assertEqual('C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_multi_star_multi_branch_star(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A * B * C</pattern>") pattern_element2 = ET.fromstring("<pattern>A * C * D</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A X B Y C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(2, len(pattern_stars)) self.assertEqual('X', pattern_stars[0]) self.assertEqual('Y', pattern_stars[1]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_simple_topic_and_star(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A * D</pattern>") topic_element = ET.fromstring("<topic>TOPIC1</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C D"), pattern_stars, Sentence("TOPIC1"), topic_stars, Sentence("THAT1"), that_stars) self.assertIsNotNone(result) self.assertEqual(len(pattern_stars), 1) self.assertEqual('B C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 1) self.assertEqual('THAT1', that_stars[0])
def test_simple_star_at_end(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A B *</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(len(pattern_stars), 1) self.assertEqual('C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_add_pattern_to_graph_basic_set_text(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None self.bot.brain.sets._sets["SET1"] = ["VAL1", "VAL2", "VAL3", "VAL5"] element = ET.fromstring('<pattern><set>set1</set> IS A VALUE</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 1) self.assertIsInstance(graph.root.children[0], PatternSetNode) self.assertEqual(graph.root.children[0].word, "SET1") matcher = PatternMatcher(graph) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("VAL1 IS A VALUE"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("VAL2 IS A VALUE"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("VAL3 IS A VALUE"), [], Sentence("*"), [], Sentence("*"), [])) self.assertIsNone(matcher.match(self.bot, self.clientid, Sentence("VAL4 IS A VALUE"), [], Sentence("*"), [], Sentence("*"), []))
def test_add_pattern_to_graph_word_set_bot(self): graph = PatternGraph() topic_element = ET.fromstring('<topic>*</topic>') that_element = ET.fromstring('<that>*</that>') template_graph_root = None self.bot.brain.sets._sets["SET1"] = ["val1", "val2", "val3", "val5"] self.bot.brain.properties._properties['bot1'] = 'val1' element = ET.fromstring('<pattern>test1 test2 <set name="SET1" /> test4 <bot name="bot1" /> test6</pattern>') graph.add_pattern_to_graph(element, topic_element, that_element, template_graph_root) self.assertIsNotNone(graph.root) self.assertIsNotNone(graph.root.children) self.assertEqual(len(graph.root.children), 1) self.assertIsInstance(graph.root.children[0], PatternWordNode) self.assertEqual(graph.root.children[0].word, "test1") self.assertIsNotNone(graph.root.children[0].children) self.assertEqual(len(graph.root.children[0].children), 1) self.assertIsInstance(graph.root.children[0].children[0], PatternWordNode) self.assertEqual(graph.root.children[0].children[0].word, "test2") self.assertIsNotNone(graph.root.children[0].children[0].children) self.assertEqual(len(graph.root.children[0].children[0].children), 1) self.assertIsInstance(graph.root.children[0].children[0].children[0], PatternSetNode) self.assertEqual(graph.root.children[0].children[0].children[0].word, "SET1") self.assertIsNotNone(graph.root.children[0].children[0].children[0].children) self.assertEqual(len(graph.root.children[0].children[0].children[0].children), 1) self.assertIsInstance(graph.root.children[0].children[0].children[0].children[0], PatternWordNode) self.assertEqual(graph.root.children[0].children[0].children[0].children[0].word, "test4") self.assertIsNotNone(graph.root.children[0].children[0].children[0].children[0].children) self.assertEqual(len(graph.root.children[0].children[0].children[0].children[0].children), 1) self.assertIsInstance(graph.root.children[0].children[0].children[0].children[0].children[0], PatternBotNode) self.assertEqual(graph.root.children[0].children[0].children[0].children[0].children[0].word, "bot1") self.assertIsNotNone(graph.root.children[0].children[0].children[0].children[0].children[0].children) self.assertEqual(len(graph.root.children[0].children[0].children[0].children[0].children[0].children), 1) self.assertIsInstance(graph.root.children[0].children[0].children[0].children[0].children[0].children[0], PatternWordNode) self.assertEqual(graph.root.children[0].children[0].children[0].children[0].children[0].children[0].word, "test6") matcher = PatternMatcher(graph) self.assertIsNotNone(matcher.match(self.bot, self.clientid, Sentence("test1 test2 val1 test4 val1 test6"), [], Sentence("*"), [], Sentence("*"), []))
class AIMLParser(object): def __init__(self, supress_warnings=False, stop_on_invalid=False): self._supress_warnings = supress_warnings self.stop_on_invalid = stop_on_invalid self.pattern_parser = PatternGraph() self.pattern_matcher = PatternMatcher(self.pattern_parser) self.template_parser = TemplateGraph(self) self.template_evaluator = TemplateEvaluator() self._filename = "Unknown" self._version = "Unknown" self._aiml_loader = AIMLLoader(self) self._num_categories = 0 @property def supress_warnings(self): return self._supress_warnings @property def num_categories(self): return self._num_categories def load_aiml(self, brain_configuration: BrainConfiguration): self._supress_warnings = brain_configuration.supress_warnings if brain_configuration.aiml_files is not None: aimls_loaded = self._aiml_loader.load_dir_contents(brain_configuration.aiml_files.files, brain_configuration.aiml_files.directories, brain_configuration.aiml_files.extension) logging.info("Loaded a total of %d aiml files", len(aimls_loaded)) else: logging.info("No AIML files defined in configuration to load") def parse_from_file(self, filename): """ Parse an AIML file and return all the cateogeries found in the file :param filename: Name of file to parse :return list of categories parsed from file: """ self._filename = filename logging.info("Loading aiml file file: " + self._filename) tree = ET.parse(filename, parser=LineNumberingParser()) aiml = tree.getroot() if aiml is None or aiml.tag != 'aiml': raise ParserException("Error, root tag is not <aiml>", filename=filename) else: try: self.parse_aiml(aiml, filename) except ParserException as parser_excep: parser_excep.filename = filename raise parser_excep except ET.ParseError as xmlpe: xmlpe.filename = filename xmlpe.xml_exception = xmlpe def parse_from_text(self, text): """ Parse an AIML text version of an aiml file and return all the cateogeries found in the file :param text: Fully validated AIML snippet :return list of categories parsed from file: """ aiml = ET.fromstring(text) if aiml is None or aiml.tag != 'aiml': ParserException("Error, root tag is not <aiml>", filename="text") else: self.parse_aiml(aiml, "text") ######################################################################################### # # <?xml version = "1.0" encoding = "UTF-8"?> # <aiml> # <category> # : # </category> # <topic> # <category> # : # </category> # </topic> # </aiml> # def parse_aiml(self, aiml_xml, filename): self.parse_version(aiml_xml) categories_found = False for expression in aiml_xml: if expression.tag == 'topic': try: self.parse_topic(expression) categories_found = True except ParserException as parser_excep: parser_excep.filename = filename logging.error(parser_excep.format_message()) if self.stop_on_invalid is True: raise parser_excep elif expression.tag == 'category': try: self.parse_category(expression) categories_found = True except ParserException as parser_excep: parser_excep.filename = filename logging.error(parser_excep.format_message()) if self.stop_on_invalid is True: raise parser_excep else: raise ParserException("Error, unknown top level tag, %s" % expression.tag, xml_element=expression) if categories_found is False: logging.warning("no categories in aiml file") if self.stop_on_invalid is True: raise ParserException("Error, no categories in aiml file", filename=filename) ######################################################################################### # # AIML_VERSION ::== 0.9 | 1.0 | 1.1 | 2.0 # def parse_version(self, aiml): if 'version' in aiml.attrib: self._version = aiml.attrib['version'] if self._version not in ['0.9', '1.0', '1.1', '2.0']: if self._supress_warnings is False: logging.warning("Version number not a supported version: %s", self._version) else: if self._supress_warnings is False: logging.warning("No version info, defaulting to 2.0") self._version = "2.0" ######################################################################################### # # TOPIC_EXPRESSION:: == <topic name = "PATTERN_EXPRESSION" > (CATEGORY_EXPRESSION) + < / topic > # # PATTERN_EXPRESSION:: == WORD | PRIORITY_WORD | WILDCARD | SET_STATEMENT | PATTERN_SIDE_BOT_PROPERTY_EXPRESSION # PATTERN_EXPRESSION:: == PATTERN_EXPRESSION PATTERN_EXPRESSION # # This means both topic and that can also be a set of words, stars, hash, sets and bots # # CATEGORY_EXPRESSION:: == <category> # <pattern> PATTERN_EXPRESSION </pattern> # (<that> PATTERN_EXPRESSION </that>) # (<topic> PATTERN_EXPRESSION </topic>) # < template > TEMPLATE_EXPRESSION < / template > # </category> def parse_topic(self, topic_element): if 'name' in topic_element.attrib: name = topic_element.attrib['name'] if name is None or len(name) == 0: raise ParserException("Topic name empty or null", xml_element=topic_element) xml = "<topic>%s</topic>" % name logging.info("Topic attrib converted to %s", xml) topic_pattern = ET.fromstring(xml) else: raise ParserException("Error, missing name attribute for topic", xml_element=topic_element) category_found = False for child in topic_element: logging.debug(child.tag) if child.tag == 'category': self.parse_category(child, topic_pattern) category_found = True else: raise ParserException("Error unknown child node of topic, %s" % child.tag, xml_element=topic_element) if category_found is False: raise ParserException("Error, no categories in topic", xml_element=topic_element) def parse_category(self, category_xml, topic_element=None, add_to_graph=True): topics = category_xml.findall('topic') if topic_element is not None: if len(topics) > 0: raise ParserException("Error, topic exists in category AND as parent node", xml_element=category_xml) else: if len(topics) > 1: raise ParserException("Error, multiple <topic> nodes found in category", xml_element=category_xml) elif len(topics) == 1: topic_element = topics[0] else: topic_element = ET.fromstring("<topic>*</topic>") thats = category_xml.findall('that') if len(thats) > 1: raise ParserException("Error, multiple <that> nodes found in category", xml_element=category_xml) elif len(thats) == 1: that_element = thats[0] else: that_element = ET.fromstring("<that>*</that>") templates = category_xml.findall('template') if len(templates) == 0: raise ParserException("Error, no template node found in category", xml_element=category_xml) elif len(templates) > 1: raise ParserException("Error, multiple <template> nodes found in category", xml_element=category_xml) else: template_graph_root = self.template_parser.parse_template_expression(templates[0]) patterns = category_xml.findall('pattern') if len(patterns) == 0: raise ParserException("Error, no pattern node found in category", xml_element=category_xml) elif len(patterns) > 1: raise ParserException("Error, multiple <pattern> nodes found in category", xml_element=category_xml) else: if add_to_graph is True: self.pattern_parser.add_pattern_to_graph(patterns[0], topic_element, that_element, template_graph_root) self._num_categories += 1 return (patterns[0], topic_element, that_element, template_graph_root) def match_sentence(self, bot, clientid, sentence, parent_question, topic_pattern, that_pattern): logging.debug("Matching sentence [%s], topic=[%s], that=[%s] ", sentence.text(), topic_pattern, that_pattern) if parent_question is not None: pattern_stars = parent_question.current_sentence()._stars topic_stars = parent_question.current_sentence()._topicstars that_stars = parent_question.current_sentence()._thatstars else: pattern_stars = sentence._stars topic_stars = sentence._topicstars that_stars = sentence._thatstars matched = self.pattern_matcher.match(bot, clientid, sentence, pattern_stars, Sentence(topic_pattern),topic_stars, Sentence(that_pattern), that_stars) if matched is not None: return self.template_evaluator.evaluate(bot, clientid, matched.template) # pattern_stars = [] # topic_stars = [] # that_stars = [] # matched = self.pattern_matcher.match(bot, clientid, sentence, pattern_stars, Sentence(topic_pattern), # topic_stars, Sentence(that_pattern), that_stars) # if matched is not None: # if parent_question is not None: # parent_question.current_sentence().stars = pattern_stars # parent_question.current_sentence().topicstars = topic_stars # parent_question.current_sentence().thatstars = that_stars # else: # sentence.stars = pattern_stars # sentence.topicstars = topic_stars # sentence.thatstars = that_stars # # return self.template_evaluator.evaluate(bot, clientid, matched.template) return None