puppetdb.py 文件源码

python
阅读 22 收藏 0 点赞 0 评论 0

项目:cumin 作者: wikimedia 项目源码 文件源码
def grammar():
    """Define the query grammar.

    Backus-Naur form (BNF) of the grammar::

            <grammar> ::= <item> | <item> <and_or> <grammar>
               <item> ::= [<neg>] <query-token> | [<neg>] "(" <grammar> ")"
        <query-token> ::= <token> | <hosts>
              <token> ::= <category>:<key> [<operator> <value>]

    Given that the pyparsing library defines the grammar in a BNF-like style, for the details of the tokens not
    specified above check directly the source code.

    Returns:
        pyparsing.ParserElement: the grammar parser.

    """
    # Boolean operators
    and_or = (pp.CaselessKeyword('and') | pp.CaselessKeyword('or'))('bool')
    # 'neg' is used as label to allow the use of dot notation, 'not' is a reserved word in Python
    neg = pp.CaselessKeyword('not')('neg')

    operator = pp.oneOf(OPERATORS, caseless=True)('operator')  # Comparison operators
    quoted_string = pp.quotedString.copy().addParseAction(pp.removeQuotes)  # Both single and double quotes are allowed

    # Parentheses
    lpar = pp.Literal('(')('open_subgroup')
    rpar = pp.Literal(')')('close_subgroup')

    # Hosts selection: glob (*) and clustershell (,!&^[]) syntaxes are allowed:
    # i.e. host10[10-42].*.domain
    hosts = quoted_string | (~(and_or | neg) + pp.Word(pp.alphanums + '-_.*,!&^[]'))

    # Key-value token for allowed categories using the available comparison operators
    # i.e. F:key = value
    category = pp.oneOf(CATEGORIES, caseless=True)('category')
    key = pp.Word(pp.alphanums + '-_.%@:')('key')
    selector = pp.Combine(category + ':' + key)  # i.e. F:key
    # All printables characters except the parentheses that are part of this or the global grammar
    all_but_par = ''.join([c for c in pp.printables if c not in ('(', ')', '{', '}')])
    value = (quoted_string | pp.Word(all_but_par))('value')
    token = selector + pp.Optional(operator + value)

    # Final grammar, see the docstring for its BNF based on the tokens defined above
    # Groups are used to split the parsed results for an easy access
    full_grammar = pp.Forward()
    item = pp.Group(pp.Optional(neg) + (token | hosts('hosts'))) | pp.Group(
        pp.Optional(neg) + lpar + full_grammar + rpar)
    full_grammar << item + pp.ZeroOrMore(pp.Group(and_or) + full_grammar)  # pylint: disable=expression-not-assigned

    return full_grammar
评论列表
文章目录


问题


面经


文章

微信
公众号

扫码关注公众号