Parses the given rule text.

    :param name: The name of the rule.  Used when emitting log
                 messages regarding a failure to parse the rule.
    :param rule_text: The text of the rule to parse.
    :param do_raise: If ``False`` and the rule fails to parse, a log
                     message is emitted to the "policies" logger at
                     level WARN, and a rule that always evaluates to
                     ``False`` will be returned.  If ``True``, a
                     ``pyparsing.ParseException`` will be raised.

    :returns: An instance of ``policies.instructions.Instructions``,
              containing the instructions necessary to evaluate the
              authorization rule.

def parse_rule(name, rule_text, do_raise=False):
    """
    Parses the given rule text.

    :param name: The name of the rule.  Used when emitting log
                 messages regarding a failure to parse the rule.
    :param rule_text: The text of the rule to parse.
    :param do_raise: If ``False`` and the rule fails to parse, a log
                     message is emitted to the "policies" logger at
                     level WARN, and a rule that always evaluates to
                     ``False`` will be returned.  If ``True``, a
                     ``pyparsing.ParseException`` will be raised.

    :returns: An instance of ``policies.instructions.Instructions``,
              containing the instructions necessary to evaluate the
              authorization rule.
    """

    try:
        return rule.parseString(rule_text, parseAll=True)[0]
    except pyparsing.ParseException as exc:
        # Allow for debugging
        if do_raise:
            raise

        # Get the logger and emit our log messages
        log = logging.getLogger('policies')
        log.warn("Failed to parse rule %r: %s" % (name, exc))
        log.warn("Rule line: %s" % exc.line)
        log.warn("Location : %s^" % (" " * (exc.col - 1)))

        # Construct and return a fail-closed instruction
        return Instructions([Constant(False), set_authz])