我们从Python开源项目中,提取了以下15个代码示例,用于说明如何使用pyparsing.Combine()。
def anything_beetween(opener_and_closer): """Builds a (pyparsing) parser for the content inside delimiters. Args: opener_and_closer: a string containing two elements: opener and closer Returns: A (pyparsing) parser for the content inside delimiters. """ opener = pyparsing.Literal(opener_and_closer[0]) closer = pyparsing.Literal(opener_and_closer[1]) char_removal_mapping = dict.fromkeys(map(ord, opener_and_closer)) other_chars = unicode(string.printable).translate(char_removal_mapping) word_without_delimiters = pyparsing.Word(other_chars).setName( "other_chars") anything = pyparsing.Forward() delimited_block = opener + anything + closer # pylint: disable=expression-not-assigned anything << pyparsing.ZeroOrMore( word_without_delimiters.setName("word_without_delimiters") | delimited_block.setName("delimited_block") ) # Combine all the parts into a single string. return pyparsing.Combine(anything)
def expression(self): expression = pyparsing.Forward() # (1 + (2 + 3)) nested_expression = pyparsing.nestedExpr( "(", ")", expression).setParseAction(self._combine_lists) # FOO(2 , 3) function_call = ( _TOKEN().setResultsName("function") + _OPEN_PARENTHESIS() + pyparsing.delimitedList( pyparsing.Combine(expression, adjacent=False, joinString=" "), delim=",").setResultsName("func_args") + _CLOSE_PARENTHESIS() ) expression << pyparsing.OneOrMore( function_call.setParseAction(self._is_known_function) | pyparsing.Group(nested_expression) | _TOKEN() | _NOT_TOKEN() ) return pyparsing.Combine(expression, adjacent=False, joinString=" ")
def parser(self): # Define punctuation as suppressed literals. lparen, rparen, lbrack, rbrack, lbrace, rbrace, colon = \ map(pp.Suppress, "()[]{}:") integer = pp.Combine(pp.Optional(pp.oneOf("+ -")) + pp.Word(pp.nums)) \ .setName("integer") \ .setParseAction(lambda toks: int(toks[0])) real = pp.Combine(pp.Optional(pp.oneOf("+ -")) + pp.Word(pp.nums) + "." + pp.Optional(pp.Word(pp.nums)) + pp.Optional(pp.oneOf("e E") + pp.Optional(pp.oneOf("+ -")) + pp.Word(pp.nums))) \ .setName("real") \ .setParseAction(lambda toks: float(toks[0])) _datetime_arg = (integer | real) datetime_args = pp.Group(pp.delimitedList(_datetime_arg)) _datetime = pp.Suppress(pp.Literal('datetime') + pp.Literal("(")) + datetime_args + pp.Suppress(")") _datetime.setParseAction(lambda x: self._make_datetime(x[0])) tuple_str = pp.Forward() list_str = pp.Forward() dict_str = pp.Forward() list_item = real | integer | _datetime | pp.quotedString.setParseAction(pp.removeQuotes) | \ pp.Group(list_str) | tuple_str | dict_str tuple_str << (pp.Suppress("(") + pp.Optional(pp.delimitedList(list_item)) + pp.Optional(pp.Suppress(",")) + pp.Suppress(")")) tuple_str.setParseAction(lambda toks : tuple(toks.asList())) list_str << (lbrack + pp.Optional(pp.delimitedList(list_item) + pp.Optional(pp.Suppress(","))) + rbrack) dict_entry = pp.Group(list_item + colon + list_item) dict_str << (lbrace + pp.Optional(pp.delimitedList(dict_entry) + pp.Optional(pp.Suppress(","))) + rbrace) dict_str.setParseAction(lambda toks: dict(toks.asList())) return list_item
def number_parser(): point = pp.Literal(".") e = pp.CaselessLiteral("e") plusorminus = pp.Literal("+") ^ pp.Literal("-") num = pp.Word(pp.nums) dec = pp.Combine(num + pp.Optional(point + pp.Optional(num)) + pp.Optional(e + pp.Optional(plusorminus) + num)) ^\ pp.Combine(point + pp.Optional(num) + pp.Optional(e + pp.Optional(plusorminus) + num)) bin = pp.Combine(pp.Literal("0") + pp.CaselessLiteral("b") + pp.Word("01")) hex = pp.Combine(pp.Literal("0") + pp.CaselessLiteral("x") + pp.Word(pp.hexnums)) oct = pp.Combine(pp.Literal("0") + pp.Optional(pp.CaselessLiteral("o")) + pp.Word("01234567")) return dec ^ bin ^ hex ^ oct
def statement(): return pyparsing.Group( _IDENTIFIER.setResultsName("lhs") + _EQUALS + pyparsing.Combine( (anything_in_curly() | pyparsing.QuotedString("'", escChar="\\", unquoteResults=False) | pyparsing.QuotedString("\"", escChar="\\", unquoteResults=False) | _REGEX) + pyparsing.ZeroOrMore(_KEYWORD), adjacent=False, joinString=" ", ).setResultsName("rhs") )
def _cast_transformer(self): """Removes obvious casts.""" return pyparsing.Combine( pyparsing.Regex(r"\([^()]*\)").suppress() + (pyparsing.Word(pyparsing.alphanums + "_") | pyparsing.Literal("(")), adjacent=False)
def _hexadecimal_as_string(self): return pyparsing.Combine('0x' + pyparsing.Word(pyparsing.hexnums))
def _typeof_expression(self): keyword = ( pyparsing.Keyword('typeof') | pyparsing.Keyword('__typeof__') ) return pyparsing.Combine( keyword + pyparsing.Literal('(') + parsers.anything_beetween('()') + pyparsing.Literal(')') )
def parseTerms(): """ expop :: '^' multop :: '*' | '/' addop :: '+' | '-' integer :: ['+' | '-'] '0'..'9'+ atom :: PI | E | real | fn '(' expr ')' | '(' expr ')' factor :: atom [ expop factor ]* term :: factor [ multop factor ]* expr :: term [ addop term ]* """ global terms if not terms: point = Literal( "." ) e = CaselessLiteral( "E" ) fnumber = Combine( Word( "+-"+nums, nums ) + Optional( point + Optional( Word( nums ) ) ) + Optional( e + Word( "+-"+nums, nums ) ) ) ident = Word(alphas, alphas+nums+"_$") plus = Literal( "+" ) minus = Literal( "-" ) mult = Literal( "*" ) div = Literal( "/" ) lpar = Literal( "(" ).suppress() rpar = Literal( ")" ).suppress() addop = plus | minus multop = mult | div expop = Literal( "^" ) pi = CaselessLiteral( "PI" ) expr = Forward() atom = (Optional("-") + ( pi | e | fnumber | ident + lpar + expr + rpar ).setParseAction( pushFirst ) | ( lpar + expr.suppress() + rpar )).setParseAction(pushUMinus) # by defining exponentiation as "atom [ ^ factor ]..." instead of "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-righ # that is, 2^3^2 = 2^(3^2), not (2^3)^2. factor = Forward() factor << atom + ZeroOrMore( ( expop + factor ).setParseAction( pushFirst ) ) term = factor + ZeroOrMore( ( multop + factor ).setParseAction( pushFirst ) ) expr << term + ZeroOrMore( ( addop + term ).setParseAction( pushFirst ) ) terms = expr return terms
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
def grammar(): """Define the query grammar. Backus-Naur form (BNF) of the grammar:: <grammar> ::= "*" | <items> <items> ::= <item> | <item> <whitespace> <items> <item> ::= <key>:<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. """ quoted_string = pp.quotedString.copy().addParseAction(pp.removeQuotes) # Both single and double quotes are allowed # Key-value tokens: key:value # Lowercase key, all printable characters except the parentheses that are part of the global grammar for the value key = pp.Word(pp.srange('[a-z0-9-_.]"'), min=2)('key') all_but_par = ''.join([c for c in pp.printables if c not in ('(', ')', '{', '}')]) value = (quoted_string | pp.Word(all_but_par))('value') item = pp.Combine(key + ':' + 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 return pp.Group(pp.Literal('*')('all')) | pp.OneOrMore(pp.Group(item))
def grammar(backend_keys): """Define the main multi-query grammar. Cumin provides a user-friendly generic query language that allows to combine the results of subqueries for multiple backends: * Each query part can be composed with the others using boolean operators ``and``, ``or``, ``and not``, ``xor``. * Multiple query parts can be grouped together with parentheses ``(``, ``)``. * Specific backend query ``I{backend-specific query syntax}``, where ``I`` is an identifier for the specific backend. * Alias replacement, according to aliases defined in the configuration file ``A:group1``. * The identifier ``A`` is reserved for the aliases replacement and cannot be used to identify a backend. * A complex query example: ``(D{host1 or host2} and (P{R:Class = Role::MyClass} and not A:group1)) or D{host3}`` Backus-Naur form (BNF) of the grammar:: <grammar> ::= <item> | <item> <boolean> <grammar> <item> ::= <backend_query> | <alias> | "(" <grammar> ")" <backend_query> ::= <backend> "{" <query> "}" <alias> ::= A:<alias_name> <boolean> ::= "and not" | "and" | "xor" | "or" 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. Arguments: backend_keys (list): list of the GRAMMAR_PREFIX for each registered backend. Returns: pyparsing.ParserElement: the grammar parser. """ # Boolean operators boolean = (pp.CaselessKeyword('and not').leaveWhitespace() | pp.CaselessKeyword('and') | pp.CaselessKeyword('xor') | pp.CaselessKeyword('or'))('bool') # Parentheses lpar = pp.Literal('(')('open_subgroup') rpar = pp.Literal(')')('close_subgroup') # Backend query: P{PuppetDB specific query} query_start = pp.Combine(pp.oneOf(backend_keys, caseless=True)('backend') + pp.Literal('{')) query_end = pp.Literal('}') # Allow the backend specific query to use the end_query token as well, as long as it's in a quoted string # and fail if there is a query_start token before the first query_end is reached query = pp.SkipTo(query_end, ignore=pp.quotedString, failOn=query_start)('query') backend_query = pp.Combine(query_start + query + query_end) # Alias alias = pp.Combine(pp.CaselessKeyword('A') + ':' + pp.Word(pp.alphanums + '-_.+')('alias')) # Final grammar, see the docstring for its BNF based on the tokens defined above # Group are used to have an easy dictionary access to the parsed results full_grammar = pp.Forward() item = backend_query | alias | lpar + full_grammar + rpar full_grammar << pp.Group(item) + pp.ZeroOrMore(pp.Group(boolean + item)) # pylint: disable=expression-not-assigned return full_grammar
def parseSelector(selectorstring): # *select = @attr1 | /tf1/@attr | @attr1//objtype """ def enumtype(*args,**kwargs): #s, l, t, selectortype=None): print(args) selectortype = kwargs['selectortype'] if selectortype is None or not isinstance(selectortype, str): raise ValueError('enumtype requires a selectortype string but got a', type(selectortype)) return selectortype """ def attrtype(): return AttrSelector() # 'ATTRTYPE' def fullpathtype(): return FullPathSelector() #'FULLPATH' def attrbyobjtype(): return AttrByObjectSelector() #'ATTRBYOBJECT' def attrexpr(selectorstring=None): attrmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums)) return attrmatch.searchString(selectorstring)[0][0] def expr(selectorstring=None, returntype=False): attrmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums)) fullpathmatch = p.Combine(p.OneOrMore(p.Literal('/') + p.Word(p.alphanums))) + p.Literal( '/').suppress() + p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums)) attrbyobjmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums)) + p.Literal('//').suppress() + p.Word(p.alphanums) matchgroup = (fullpathmatch | attrbyobjmatch | attrmatch) if returntype: attrmatch.setParseAction(attrtype) fullpathmatch.setParseAction(fullpathtype) attrbyobjmatch.setParseAction(attrbyobjtype) return matchgroup.parseString(selectorstring) _selectorconfig = expr(selectorstring=selectorstring) _selectortype = expr(selectorstring=selectorstring, returntype=True) _selectorattr = attrexpr(selectorstring=selectorstring) return { 'type': _selectortype[0], 'config': _selectorconfig[:2], #TODO unclear why [0] returns only a subset of the matches 'attribute': _selectorattr }
def __init__(self, obj, config=str()): def process(config): pathexpr = p.Literal("'").suppress() + \ p.Optional( p.Combine( p.OneOrMore(p.Literal("/") + p.Word(p.alphanums)) + p.Literal("/").suppress() ) ).setResultsName('path') + \ p.Combine( (p.Literal('@').suppress() | p.Literal('!').suppress()) + p.Word(p.alphanums) + p.Literal("'").suppress() ).setResultsName('attrib') expr = p.Group(pathexpr).setResultsName('search') match = expr.parseString(config) _ret = [] if 'search' in match: if 'path' in match['search']: _ret.append(match['search']['path']) if 'attrib' in match['search']: _ret.append(match['search']['attrib']) return _ret super(Xattrib, self).__init__(obj, config=config, defer=True) if self.config is None or len(self.config) < 1 or not isinstance(self.config, str): raise ValueError('Xattrib plugin function requires a config string') try: _result = process("'%s'" % self.config) if len(_result) == 2: self.targetobject, self.targetattribute = _result elif len(_result) == 1: _config = getattr(obj, _result[0], None) if _config is None: raise ValueError('Xattrib plugin received an attribute name that does not exist') # TODO len check only required for attributes, but not method plugins if len(_config) > 1: raise ValueError('Xattrib plugin received a attribute name that contains multiple values') self.targetobject, self.targetattribute = process("'%s'" % _config[0]) else: raise Exception() except: raise ValueError('An error occured when processing the search string for the Xattrib plugin function')