def set_attrib(self, attrib_name, attrib_value): if attrib_name != 'index': raise ParserException("Invalid attribute name [%s] for this node" % (attrib_name)) if isinstance(attrib_value, int): int_val = attrib_value self._sentence = int_val else: splits = attrib_value.split(",") if len(splits) == 1: try: self._sentence = int(splits[0]) except Exception as excep: YLogger.exception(self, "Failed to split string", excep) raise ParserException("None numeric format [%s] for this node [%s], either 'x' or 'x,y'", attrib_value, attrib_name) elif len(splits) == 2: try: self._question = int(splits[0]) if splits[1] == '*': self._sentence = -1 else: self._sentence = int(splits[1]) except Exception as excep: YLogger.exception(self, "Failed to split string", excep) raise ParserException("None numeric format [%s] for this node [%s], either 'x', 'x,y', or 'x,*'", attrib_value, attrib_name) if self._sentence == 0: raise ParserException("Sentence values are 1 based, cannot be 0") if self._question == 0: raise ParserException("Question values are 1 based, cannot be 0")
def parse_topic(self, topic_element, namespace): if 'name' in topic_element.attrib: name = topic_element.attrib['name'] if name is None or not name: raise ParserException("Topic name empty or null", xml_element=topic_element) xml = "<topic>%s</topic>" % name YLogger.info(self, "Topic attrib converted to %s", xml) topic_pattern = ET.fromstring(xml) else: raise ParserException("Missing name attribute for topic", xml_element=topic_element) category_found = False num_category = 0 for child in topic_element: tag_name, _ = self.tag_and_namespace_from_text(child.tag) if tag_name == 'category': self.parse_category(child, namespace, topic_pattern) category_found = True num_category += 1 else: raise ParserException("Unknown child node of topic, %s" % child.tag, xml_element=topic_element) if category_found is False: raise ParserException("No categories in topic", xml_element=topic_element) return num_category
def get_condition_name(self, condition): if 'name' in condition.attrib: return condition.attrib['name'], TemplateConditionVariable.GLOBAL elif 'var' in condition.attrib: return condition.attrib['var'], TemplateConditionVariable.LOCAL elif 'bot' in condition.attrib: return condition.attrib['bot'], TemplateConditionVariable.BOT else: names = condition.findall('name') if names: if len(names) > 1: raise ParserException("Condition element has multiple name elements", xml_element=condition) name_text = self.get_text_from_element(condition.find('name')) return name_text, TemplateConditionVariable.GLOBAL vars = condition.findall('var') if vars: if len(vars) > 1: raise ParserException("Condition element has multiple var elements", xml_element=condition) var_text = self.get_text_from_element(condition.find('var')) return var_text, TemplateConditionVariable.LOCAL bots = condition.findall('bot') if bots: if len(bots) > 1: raise ParserException("Condition element has multiple bot elements", xml_element=condition) bot_text = self.get_text_from_element(condition.find('bot')) return bot_text, TemplateConditionVariable.BOT return None, TemplateConditionVariable.DEFAULT
def can_add(self, new_node): if new_node.is_root(): raise ParserException("Cannot add root node to topic node") if new_node.is_topic(): raise ParserException("Cannot add topic node to topic node") if new_node.is_that(): raise ParserException("Cannot add that node to topic node")
def can_add(self, new_node: PatternNode): if new_node.is_root(): raise ParserException("Cannot add root node to existing root node") if new_node.is_topic(): raise ParserException("Cannot add topic node to root node") if new_node.is_that(): raise ParserException("Cannot add that node to root node") if new_node.is_template(): raise ParserException("Cannot add template node to root node")
def get_pattern(self, category_xml, namespace): patterns = self.find_all(category_xml, "pattern", namespace) if not patterns: raise ParserException("No pattern node found in category", xml_element=category_xml) elif len(patterns) > 1: raise ParserException("Multiple <pattern> nodes found in category", xml_element=category_xml) else: return patterns[0]
def set_attrib(self, attrib_name, attrib_value): if attrib_name != 'level' and attrib_name != 'output': raise ParserException("Invalid attribute name %s for this node", attrib_name) if attrib_value not in ['debug', 'info', 'warning', 'error'] and \ attrib_value not in ["logging", "print"]: raise ParserException( "Invalid attribute value %s for this node %s", attrib_value, attrib_name) self._level = attrib_value
def parse_expression(self, graph, expression): super(TemplateAddTripleNode, self).parse_expression(graph, expression) if self._subj is None: raise ParserException("<%s> node missing subject attribue/element"%self.node_name) if self._pred is None: raise ParserException("<%s> node missing predicate attribue/element"%self.node_name) if self._obj is None: raise ParserException("<%s> node missing object attribue/element"%self.node_name)
def set_attrib(self, attrib_name, attrib_value): if attrib_name != 'index': raise ParserException("Invalid attribute name [%s] for this node" % (attrib_name)) if isinstance(attrib_value, int): self._index = attrib_value else: try: self._index = int(attrib_value) except: raise ParserException("None numeric format [%s] for this node [%s]", attrib_value, attrib_name)
def check_aiml_tag(self, aiml, filename=None): # Null check just to be sure if aiml is None: raise ParserException("Null root tag", filename=filename) tag_name, namespace = self.tag_and_namespace_from_text(aiml.tag) # Then if check is just <aiml>, thats OK if tag_name != 'aiml': raise ParserException("Root tag is not <aiml>", filename=filename) return tag_name, namespace
def get_template(self, category_xml, namespace): templates = self.find_all(category_xml, "template", namespace) if not templates: raise ParserException("No template node found in category", xml_element=category_xml) elif len(templates) > 1: raise ParserException( "Multiple <template> nodes found in category", xml_element=category_xml) else: return self._template_parser.parse_template_expression( templates[0])
def parse_query(self, graph, query_name, query): for child in query: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'subj': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) subj = self.parse_children_as_word_node(graph, child) elif tag_name == 'pred': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) pred = self.parse_children_as_word_node(graph, child) elif tag_name == 'obj': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) obj = self.parse_children_as_word_node(graph, child) else: YLogger.warning(self, "Unknown tag name [%s] in select query", tag_name) if subj is None: raise ParserException("<subj> element missing from select query") if pred is None: raise ParserException("<pred> element missing from select query") if obj is None: raise ParserException("<obj> element missing from select query") if query_name == "q": self._queries.append(Query(subj, pred, obj)) else: self._queries.append(NotQuery(subj, pred, obj))
def __init__(self, wildcard, userid='*'): PatternNode.__init__(self, userid) if wildcard not in self.matching_wildcards(): raise ParserException( "%s not in valid wildcards %s" % (wildcard, ", ".join(self.matching_wildcards()))) self._wildcard = wildcard
def parse_type3_condition(self, graph, expression): for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name in ['name', 'var', 'bot']: pass elif tag_name == 'li': list_item = TemplateConditionListItemNode() name, var_type = self.get_condition_name(child) list_item._name = name list_item._var_type = var_type list_item._value = self.get_condition_value(graph, child) self.children.append(list_item) list_item.parse_text(graph, self.get_text_from_element(child)) for sub_pattern in child: if sub_pattern.tag in ['name', 'var', 'bot', 'value']: pass elif sub_pattern.tag == 'loop': list_item.loop = True else: graph.parse_tag_expression(sub_pattern, list_item) tail_text = self.get_tail_from_element(sub_pattern) list_item.parse_text(graph, tail_text) else: raise ParserException("Invalid element <%s> in condition element" % (tag_name), xml_element=expression)
def add_that_to_node(self, that_element, base_node, userid="*"): try: current_node = self._pattern_factory.new_node_class('that')(userid) current_node = base_node.add_that(current_node) head_text = self.get_text_from_element(that_element) if head_text is not None: current_node = self._parse_text(TextUtils.strip_whitespace(head_text), current_node) added_child = False for sub_element in that_element: new_node = self.node_from_element(sub_element) current_node = current_node.add_child(new_node) tail_text = self.get_tail_from_element(sub_element) if tail_text is not None: current_node = self._parse_text(tail_text, current_node) added_child = True if head_text is None: if added_child is False: raise ParserException("That node text is empty", xml_element=that_element) return current_node except ParserException as parser_excep: parser_excep.xml_element = that_element raise parser_excep
def parse_expression(self, graph, expression): name_found = False if 'name' in expression.attrib: self.name = self.parse_attrib_value_as_word_node( graph, expression, 'name') name_found = True self.parse_text(graph, self.get_text_from_element(expression)) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'name': self.name = self.parse_children_as_word_node(graph, child) self.local = False name_found = True else: graph.parse_tag_expression(child, self) self.parse_text(graph, self.get_tail_from_element(child)) if name_found is False: raise ParserException("Name not found in bot", xml_element=expression)
def parse_expression(self, graph, expression): li_found = False for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'li': li_found = True li_node = graph.get_base_node() self.children.append(li_node) li_node.parse_template_node(graph, child) else: raise ParserException("Unsupported random child tag: %s" % (tag_name), xml_element=expression) if li_found is False: raise ParserException("No li children of random element!", xml_element=expression)
def __init__(self, attribs, text, userid='*'): PatternNode.__init__(self, userid) if 'name' in attribs: self._set_name = attribs['name'].upper() elif text: self._set_name = text.upper() else: raise ParserException( "Invalid set node, no name specified as attribute or text")
def find_that(self, category_xml, namespace): thats = self.find_all(category_xml, "that", namespace) if len(thats) > 1: raise ParserException("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>") return that_element
def find_topic(self, category_xml, namespace, topic_element=None): topics = self.find_all(category_xml, "topic", namespace) if topic_element is not None: if topics: raise ParserException( "Topic exists in category AND as parent node", xml_element=category_xml) else: if len(topics) > 1: raise ParserException( "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>") return topic_element
def parse_expression(self, graph, expression): for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'category': parsed = graph.aiml_parser.parse_category(child, namespace=None, topic_element=None, add_to_graph=False) learn_category = LearnCategory(parsed[0], parsed[1], parsed[2], parsed[3]) self.children.append(learn_category) elif tag_name == 'topic': raise ParserException("Not supported yet") else: raise ParserException("Invalid tag [%s] found in <learn>" % tag_name)
def __init__(self, aiml_parser, root_node=None): self._aiml_parser = aiml_parser self.load_pattern_node_factory() if root_node is None: YLogger.debug(self, "Defaulting root to PatternRootNode") self._root_node = self._pattern_factory.get_root_node() else: if root_node.is_root() is False: raise ParserException("Root node needs to be of base type PatternRootNode") self._root_node = root_node
def __init__(self, attribs, text, userid='*'): PatternNode.__init__(self, userid) if 'name' in attribs: self._property = attribs['name'] elif 'property' in attribs: self._property = attribs['property'] elif text: self._property = text else: raise ParserException( "Invalid bot node, neither name or property specified as attribute or text" )
def test_parser_exception_xml_as_string(self): element = ET.fromstring("<template />") exception = ParserException("message", filename="test.xml", xml_exception="xml_exception_error", xml_element=element) self.assertEqual("message", exception.message) self.assertEqual("test.xml", exception.filename) self.assertEqual("xml_exception_error", exception.xml_exception) self.assertEqual(element, exception._xml_element) self.assertEqual("message in [test.xml] : xml_exception_error", exception.format_message())
def parse_type1_condition(self, graph, expression): self.parse_text(graph, self.get_text_from_element(expression)) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name in ['name', 'var', 'bot', 'value']: pass elif tag_name == 'li': raise ParserException("li element not allowed as child of condition element", xml_element=expression) elif tag_name == 'loop': raise ParserException("This type of condition cannot have <loop /> element", xml_element=expression) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def node_from_element(self, element, userid="*"): node_name = TextUtils.tag_from_text(element.tag) if self._pattern_factory.exists(node_name) is False: raise ParserException("Unknown node name [%s]"%node_name) text = None if element.text is not None: text = TextUtils.strip_whitespace(element.text) node_class_instance = self._pattern_factory.new_node_class(node_name) node_instance = node_class_instance(element.attrib, text, userid) return node_instance
def get_condition_value(self, graph, condition): if 'value' in condition.attrib: value_node = graph.get_base_node() value_node.append(graph.get_word_node(condition.attrib['value'])) return value_node else: values = condition.findall('value') if not values: return None elif len(values) > 1: raise ParserException("Element has multiple value elements", xml_element=condition) value_node = graph.get_base_node() value_node.parse_template_node(graph, values[0]) return value_node
def parse_expression(self, graph, expression): name_found = False var_found = False if 'name' in expression.attrib: self.name = self.parse_attrib_value_as_word_node(graph, expression, 'name') self.local = False name_found = True if 'var' in expression.attrib: self.name = self.parse_attrib_value_as_word_node(graph, expression, 'var') self.local = True var_found = True for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'name': self.name = self.parse_children_as_word_node(graph, child) self.local = False name_found = True elif tag_name == 'var': self.name = self.parse_children_as_word_node(graph, child) self.local = True var_found = True elif tag_name == "tuple": self._tuples = self.parse_children_as_word_node(graph, child) if name_found is False and var_found is False: raise ParserException("Invalid get, missing either name or var", xml_element=expression) if name_found is True and var_found is True: raise ParserException("Get node has both name AND var values", xml_element=expression)
def __init__(self, attribs, text, userid='*'): PatternNode.__init__(self, userid) self._words = [] if 'words' in attribs: words = attribs['words'].upper() elif text: words = text.upper() else: raise ParserException( "Invalid iset node, no words specified as attribute or text") self._parse_words(words) self._iset_name = "iset_%d" % (PatternISetNode.iset_count) PatternISetNode.iset_count += 1
def test_duplicate_grammar_exception_xml(self): element = ET.fromstring("<template />") xml_exception = ET.ParseError() xml_exception.position = [] xml_exception.position.append(1) xml_exception.position.append(2) exception = ParserException("message", filename="test.xml", xml_exception=xml_exception, xml_element=element) self.assertEqual("message", exception.message) self.assertEqual("test.xml", exception.filename) self.assertEqual(xml_exception, exception.xml_exception) self.assertEqual(element, exception._xml_element) self.assertEqual("message in [test.xml] at [line(1), column(2)]", exception.format_message())