from pyparsing import Literal, quotedString, Suppress, removeQuotes, restOfLine dependency_keyword = Literal('.dependency') dependency_name = quotedString.addParseAction(lambda n: n[0].split('/', maxsplit=1)[0]) dependency_definition = dependency_keyword + dependency_name + Suppress(restOfLine()) grammar = dependency_definition class PodspecParser: def parse(self, content): return (match[1] for match in grammar.searchString(content))
whereExpression = Forward() and_ = Keyword("and", caseless=True) or_ = Keyword("or", caseless=True) in_ = Keyword("in", caseless=True) E = CaselessLiteral("E") binop = oneOf("= != < > >= <= eq ne lt le gt ge", caseless=True) arithSign = Word("+-",exact=1) realNum = Combine( Optional(arithSign) + ( Word( nums ) + "." + Optional( Word(nums) ) | ( "." + Word(nums) ) ) + Optional( E + Optional(arithSign) + Word(nums) ) ) intNum = Combine( Optional(arithSign) + Word( nums ) + Optional( E + Optional("+") + Word(nums) ) ) Rval = realNum | intNum | quotedString.addParseAction(removeQuotes).addParseAction(unicodeToStr) RvalList = Group( delimitedList( Rval ) ) columnRval = Rval | columnName # need to add support for alg expressions whereCondition = Group( ( columnName + binop + columnRval ) | ( columnName + in_ + "(" + delimitedList( columnRval ) + ")" ) | ( columnName + in_ + "(" + selectStmt + ")" ) | ( Suppress("(") + whereExpression + Suppress(")") ) ) whereExpression << whereCondition + ZeroOrMore( ( and_ | or_ ) + whereExpression ) # define the grammar selectStmt << ( selectToken + ( '*' | columnNameList ).setResultsName( "columns" ) + fromToken +
emoji = Regex(':[\\S]+:').setResultsName('emoji') message = OneOrMore(Word(alphanums + "#")).setResultsName('message') def tail(name): return Suppress(White(max=1)) + CharsNotIn('').setResultsName(name) channel_name = Word(alphanums + '-').setResultsName('channel') user_name = Word(alphanums + '-_.') link = Word(printables) int_num = Word(nums) dumb_single_quotes = QuotedString("‘", endQuoteChar="’", escChar="\\") dumb_double_quotes = QuotedString("“", endQuoteChar="”", escChar="\\") quotedString.addParseAction(removeQuotes) comma_list = delimitedList((dumb_single_quotes | dumb_double_quotes | quotedString | originalTextFor(OneOrMore(Word(printables, excludeChars=","))))).setResultsName('comma_list') def flag(name): dashes = '--' if len(name) > 1 else '-' return CaselessLiteral(dashes + name).setResultsName(name) def flag_with_arg(name, argtype): dashes = '--' if len(name) > 1 else '-' return CaselessLiteral(dashes + name) + argtype.setResultsName(name)
def parser(self): point = Literal(".") e = CaselessLiteral("E") fnumber = Combine(Word("+-" + nums, nums) + Optional(point + Optional(Word(nums))) + Optional(e + Word("+-" + nums, nums))) # ident = reduce(lambda x, y: x | y, self.func_name_parsers) ident = Word(alphas, alphas + nums + "_$") plus = Literal("+") minus = Literal("-") mult = Literal("*") div = Literal("/") _or = Literal("|") _and = Literal("&") lpar = Literal("(").suppress() rpar = Literal(")").suppress() lt = Keyword("<") le = Keyword("<=") gt = Keyword(">") ge = Keyword(">=") addop = plus | minus | le | lt | gt | ge multop = mult | div | _or | _and expop = Literal("^") pi = CaselessLiteral("PI") # column_names = [Literal(col_name) for col_name in self.col_names] # Equivalent to: 'x_1 | x_2 | ... | x_n' # column = self.col_name_parser() # Function arguments plusorminus = Literal('+') | Literal('-') number = Word(nums) integer = Combine(Optional(plusorminus) + number).setParseAction(lambda x: int(x[0])) floatnumber = Combine(integer + Optional(point + Optional(number)) + Optional(e + integer) ).setParseAction(lambda x: float(x[0])) arg = (integer | floatnumber | quotedString.addParseAction(removeQuotes)).setParseAction(lambda x: x[0]) args = Optional(delimitedList(arg), default=None).setParseAction(lambda x: {'args': [z for z in x]}) kwarg = (Word(alphas, alphas + nums + "_$") + Suppress("=") + arg).setParseAction(lambda x: {x[0]: x[1]}) kwargs = Optional(Suppress(",") + delimitedList(kwarg), default=None) kwargs.setParseAction(lambda x: {'kwargs': dict(pair for d in x for pair in d.items())} if x[0] is not None else { 'kwargs': None}) func_inputs = (Suppress(",") + args + kwargs) func_input_block = Optional(func_inputs, default={'args': None, 'kwargs': None}) \ .setParseAction(lambda x: self._add_func_inputs(dict(pair for d in x for pair in d.items()))) expr = Forward() kwarg.setParseAction(lambda x: {x[0]: x[1]}) value = self.value_parser() atom = (Optional("-") + (value | pi | e | fnumber | ident + lpar + expr + func_input_block + rpar).setParseAction(lambda x: self.push_first(tok=x[0])) | ( lpar + expr.suppress() + rpar)).setParseAction(lambda x: self.push_unary_minus(toks=x)) factor = Forward() factor << atom + ZeroOrMore((expop + factor).setParseAction(lambda x: self.push_first(tok=x[0]))) term = factor + ZeroOrMore((multop + factor).setParseAction(lambda x: self.push_first(tok=x[0]))) expr << term + ZeroOrMore((addop + term).setParseAction(lambda x: self.push_first(tok=x[0]))) if self.deferred_eval: expr.setParseAction(lambda x: originalTextFor(expr)) return expr
concept_name + ZeroOrMore ( LineEnd () ) ) | \ Group ( concept_name + COLON + concept_name + ZeroOrMore ( LineEnd () ) ) question_graph_expression = question_graph_element + ZeroOrMore(arrow + question_graph_element) whereExpression = Forward() and_, or_, in_ = map(CaselessKeyword, "and or in".split()) binop = oneOf("= != =~ !=~ < > >= <= eq ne lt le gt ge", caseless=True) realNum = ppc.real() intNum = ppc.signed_integer() # need to add support for alg expressions columnRval = realNum | intNum | quotedString.addParseAction(removeQuotes) | columnName whereCondition = Group( ( columnName + binop + (columnRval | Word(printables) ) ) | ( columnName + in_ + "(" + delimitedList( columnRval ) + ")" ) | ( columnName + in_ + "(" + statement + ")" ) | ( "(" + whereExpression + ")" ) ) whereExpression << whereCondition + ZeroOrMore( ( and_ | or_ ) + whereExpression ) ''' Assignment for handoff. ''' setExpression = Forward () setStatement = Group( ( ident ) | ( quotedString("json_path") + AS + ident("name") ) | ( "(" + setExpression + ")" ) )
function_arg = named_arg | arg_value function_body <<= Word(alphanums + "_") + ( Literal("(").suppress() + (delimitedList(function_arg) | Empty()) + Literal(")").suppress()) # Since asList is called in the TranQL ast, a function ends up being structured as ["my_function_name", ["my_arg1", "my_arg"] or ["add_int", [4, 7]] # Accordingly, there is no way to distinguish a function from an actual list. Since asList is called, we cannot give function_body a name. # Therefore, the most straightforward way is to set a parsing action which converts the function structure to an actual class. # However, classes are not easily json serializable, so a dict struct will do function_body.setParseAction(lambda toks: {"name": toks[0], "args": toks[1:]}) concept_or_var_list = Group(LBRACK.suppress() + delimitedList(concept_value | ident) + RBRACK.suppress()) # need to add support for alg expressions columnRval = function_body | realNum | intNum | quotedString.addParseAction( removeQuotes) | columnName | concept_or_var_list whereCondition = Group( (columnName + binop + columnRval) | # ( columnName + in_ + concept_value_list) | # ( columnName + in_ + "(" + delimitedList( columnRval ) + ")" ) | # ( columnName + in_ + "(" + statement + ")" ) | # ( columnName + in_ + (columnRval | Word(printables))) | ("(" + whereExpression + ")")) whereExpression << whereCondition + ZeroOrMore((and_ | or_) + whereExpression) ''' Assignment for handoff. ''' setExpression = Forward() setStatement = Group((ident) | (quotedString("json_path") + AS + ident("name")) | ("(" + setExpression + ")")) setExpression << setStatement + ZeroOrMore((and_ | or_) + setExpression) optWhite = ZeroOrMore(LineEnd() | White())
from pyparsing import (nums, alphanums, cppStyleComment, ) # from pyparsing import (ParseResults, ) # from pyparsing import (ParseException, ) from ._actions import ( valuelists_detection, quoted_valuelists_detection, expression_type_detection, expression_type_detection_in_nestedvalues, ) BASE_STRINGS = alphanums + "-" + "_" NETWORK_STRINGS = alphanums + "-" + "_" + '.' # 適時調整 BASE_WORDS = Word(BASE_STRINGS) QUOTED_WORDS = quotedString.addParseAction(removeQuotes) END_OF_WORDS = WordEnd(BASE_STRINGS) LineSeparator = Literal(';').suppress().setResultsName('separator_token') Comments = Optional(cppStyleComment.setResultsName('comment')) opener, closer = Literal('{'), Literal('}') # ex: {1.1.1.1; 2.2.2.2; ...} WORD_LIST = ( opener.suppress() + delimitedList(Word(NETWORK_STRINGS), delim=';') + LineSeparator + closer.suppress() ).setParseAction(valuelists_detection)
cppStyleComment, ) # from pyparsing import (ParseResults, ) # from pyparsing import (ParseException, ) from ._actions import ( valuelists_detection, quoted_valuelists_detection, expression_type_detection, expression_type_detection_in_nestedvalues, ) BASE_STRINGS = alphanums + "-" + "_" NETWORK_STRINGS = alphanums + "-" + "_" + '.' # 適時調整 BASE_WORDS = Word(BASE_STRINGS) QUOTED_WORDS = quotedString.addParseAction(removeQuotes) END_OF_WORDS = WordEnd(BASE_STRINGS) LineSeparator = Literal(';').suppress().setResultsName('separator_token') Comments = Optional(cppStyleComment.setResultsName('comment')) opener, closer = Literal('{'), Literal('}') # ex: {1.1.1.1; 2.2.2.2; ...} WORD_LIST = (opener.suppress() + delimitedList(Word(NETWORK_STRINGS), delim=';') + LineSeparator + closer.suppress()).setParseAction(valuelists_detection) QUOTED_WORD_LIST = ( opener.suppress() + delimitedList(QUOTED_WORDS, delim=';') + LineSeparator + closer.suppress()).setParseAction(quoted_valuelists_detection)