def parse(<EOL>self,<EOL>assertion: Union[str, Mapping[str, str]],<EOL>strict: bool = False,<EOL>parseinfo: bool = False,<EOL>rule_name: str = "<STR_LIT:start>",<EOL>error_level: str = "<STR_LIT>",<EOL>) -> "<STR_LIT>":
self.ast = None<EOL>self.parse_valid = False<EOL>self.parse_visualize_error = "<STR_LIT>"<EOL>self.validation_messages = []  <EOL>if isinstance(assertion, dict):<EOL><INDENT>if assertion.get("<STR_LIT>", False) and assertion.get("<STR_LIT:object>", False):<EOL><INDENT>statement = f"<STR_LIT>"<EOL><DEDENT>elif assertion.get("<STR_LIT>"):<EOL><INDENT>statement = f"<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>statement = "<STR_LIT>"<EOL><DEDENT><DEDENT>else:<EOL><INDENT>statement = assertion<EOL><DEDENT>self.original_bel_stmt = statement<EOL>self.bel_stmt = bel_utils.preprocess_bel_stmt(statement)<EOL>if len(self.bel_stmt) == <NUM_LIT:0>:<EOL><INDENT>self.validation_messages.append(<EOL>("<STR_LIT>", "<STR_LIT>")<EOL>)<EOL>return self<EOL><DEDENT>try:<EOL><INDENT>ast_dict = self.parser.parse(<EOL>self.bel_stmt, rule_name=rule_name, trace=False, parseinfo=parseinfo<EOL>)<EOL>self.ast = lang_ast.ast_dict_to_objects(ast_dict, self)<EOL>self.parse_valid = True<EOL><DEDENT>except FailedParse as e:<EOL><INDENT>error, visualize_error = bel_utils.handle_parser_syntax_error(e)<EOL>self.parse_visualize_error = visualize_error<EOL>if visualize_error:<EOL><INDENT>self.validation_messages.append(<EOL>("<STR_LIT>", f"<STR_LIT>")<EOL>)<EOL><DEDENT>else:<EOL><INDENT>self.validation_messages.append(<EOL>("<STR_LIT>", f"<STR_LIT>")<EOL>)<EOL><DEDENT>self.ast = None<EOL><DEDENT>except Exception as e:<EOL><INDENT>log.error("<STR_LIT>".format(e, type(e)))<EOL>self.validation_messages.append(<EOL>("<STR_LIT>", "<STR_LIT>".format(e, type(e)))<EOL>)<EOL><DEDENT>return self<EOL>
Parse and semantically validate BEL statement

        Parses a BEL statement given as a string and returns an AST, Abstract Syntax Tree (defined in ast.py)
        if the statement is valid, self.parse_valid. Else, the AST attribute is None and there will be validation error messages
        in self.validation_messages.  self.validation_messages will contain WARNINGS if
        warranted even if the statement parses correctly.

        Error Levels are similar to log levels - selecting WARNING includes both
        WARNING and ERROR, selecting ERROR just includes ERROR

        Args:
            assertion: BEL statement (if str -> 'S R O', if dict {'subject': S, 'relation': R, 'object': O})
            strict: specify to use strict or loose parsing; defaults to loose
            parseinfo: specify whether or not to include Tatsu parse information in AST
            rule_name: starting point in parser - defaults to 'start'
            error_level: return ERRORs only or also WARNINGs

        Returns:
            ParseObject: The ParseObject which contain either an AST or error messages.