def booleanStrAction(token): if pp.CaselessLiteral("True").matches(token): return '1' elif pp.CaselessLiteral("False").matches(token): return '0' else: return token
def get_expression_parser(): sign = pp.Optional(pp.Literal('-')) number = pp.Word(pp.nums) dpoint = pp.Literal('.') ignore_errors = pp.CaselessLiteral(IGNORE_ERRORS) all_envs = pp.CaselessLiteral(ALL_ENVS) eq, neq = pp.Literal(EQUAL), pp.Literal(NOT_EQUAL) eand, eor = pp.CaselessLiteral(AND), pp.CaselessLiteral(OR) option = (ignore_errors | all_envs).setParseAction(_tag_with(_OPTION)) options = pp.Group(pp.ZeroOrMore(option)) operator_test = (eq | neq).setParseAction(_tag_with(TEST)) operator_logical = (eand | eor).setParseAction(_tag_with(_LOGICAL)) begin_if = pp.CaselessLiteral(_IF).setParseAction(_tag_with(_IF)) obj = pp.Word(pp.printables).setParseAction(_tag_with(_OBJ)) integer = pp.Combine(sign + number + pp.WordEnd()).setParseAction( _tag_with(_OBJ, int)) real = pp.Combine(sign + ((number + dpoint + number) | (dpoint + number) | (number + dpoint))).setParseAction( _tag_with(_OBJ, float)) expritem = integer | real | obj single_test = expritem + operator_test + expritem additional_test = operator_logical + single_test expr_var = pp.Group(obj + s_end).setParseAction(_tag_with(VALUE)) expr_test = pp.Group(obj + begin_if + single_test + pp.ZeroOrMore(additional_test) + s_end).setParseAction(_tag_with(TEST)) expr_list_test = pp.Group(begin_if + single_test + pp.ZeroOrMore(additional_test) + s_end).setParseAction(_tag_with(LIST_TEST)) expr = expr_test | expr_var | expr_list_test line = options + expr + s_end return line
def __init__(self): """constructor""" """make LAD parser""" self.NwNumber = pp.Word(pp.nums, max=1).setParseAction(pp.tokenMap(int)).setBreak(False) self.Nw = pp.CaselessLiteral('NW:') + self.NwNumber + pp.Suppress(pp.lineEnd()) self.Ope_I = pp.Combine(pp.CaselessLiteral('I') + pp.Word(pp.nums, max=2)) self.Ope_O = pp.Combine(pp.CaselessLiteral('O') + pp.Word(pp.nums, max=2)) self.Ope_M = pp.Combine(pp.CaselessLiteral('M') + pp.Word(pp.nums, max=2)) self.Ope = self.Ope_I | self.Ope_O | self.Ope_M self.Command_LD = (pp.CaselessKeyword('LDN') | pp.CaselessKeyword ('LD')) + self.Ope + pp.Suppress(pp.lineEnd()) self.Command_AND = (pp.CaselessKeyword('ANDN') | pp.CaselessKeyword ('AND')) + self.Ope + pp.Suppress(pp.lineEnd()) self.Command_OR = (pp.CaselessKeyword('ORN') | pp.CaselessKeyword('OR')) + self.Ope + pp.Suppress(pp.lineEnd()) self.Command_OUT = pp.CaselessKeyword('OUT') + self.Ope + pp.Suppress(pp.lineEnd()) self.Command_BSAND = pp.CaselessKeyword('BSAND') + pp.Suppress(pp.lineEnd()) self.Command_BFAND = pp.CaselessKeyword('BFAND') + pp.Suppress(pp.lineEnd()) self.Command_BSOR = pp.CaselessKeyword('BSOR') + pp.Suppress(pp.lineEnd()) self.Command_BFOR = pp.CaselessKeyword('BFOR') + pp.Suppress(pp.lineEnd()) self.Command_LDOR = self.Command_LD + self.Command_OR * (0, 7) self.Command_ANDOR = self.Command_AND + self.Command_OR * (0, 7) self.Command_LDAND = self.Command_LDOR + self.Command_ANDOR * (0, 7) self.Complex = pp.Forward() self.Block = pp.Group((self.Complex | self.Command_LDAND) + pp.Optional(self.Command_ANDOR * (0, 7))) self.ComplexOR = self.Command_BSOR + self.Block + self.Block + self.Command_BFOR self.ComplexAND = self.Command_BSAND + self.Block + self.Block + self.Command_BFAND self.Complex <<= self.ComplexOR | self.ComplexAND self.NwProgram = pp.Group(self.Nw + self.Block + self.Command_OUT) self.Program = pp.OneOrMore(self.NwProgram)
def booleanStrAction(token): if pp.CaselessLiteral("True").matches(token) or pp.Word("1").matches(token): return True elif pp.CaselessLiteral("False").matches(token) or pp.Word("0").matches(token): return False else: print("Cannot recognize boolean value : %s" % token) return token
class TestCaselessLiteral(PyparsingExpressionTestCase): tests = [ PpTestSpec( desc = "Match colors, converting to consistent case", expr = pp.OneOrMore(pp.CaselessLiteral("RED") | pp.CaselessLiteral("GREEN") | pp.CaselessLiteral("BLUE")), text = "red Green BluE blue GREEN green rEd", expected_list = ['RED', 'GREEN', 'BLUE', 'BLUE', 'GREEN', 'GREEN', 'RED'], ), ]
class TestCaselessLiteral(PyparsingExpressionTestCase): tests = [ PpTestSpec( desc="Match colors, converting to consistent case", expr=(pp.CaselessLiteral("RED") | pp.CaselessLiteral("GREEN") | pp.CaselessLiteral("BLUE"))[...], text="red Green BluE blue GREEN green rEd", expected_list=[ "RED", "GREEN", "BLUE", "BLUE", "GREEN", "GREEN", "RED" ], ), ]
def __foreign_key_parser(database): def paste_database(unused1, unused2, toc): return ['`{database}`.`{table}`'.format(database=database, table=toc[0])] return (pp.CaselessLiteral('CONSTRAINT').suppress() + pp.QuotedString('`').suppress() + pp.CaselessLiteral('FOREIGN KEY').suppress() + pp.QuotedString('(', endQuoteChar=')').setResultsName('attributes') + pp.CaselessLiteral('REFERENCES') + pp.Or([ pp.QuotedString('`').setParseAction(paste_database), pp.Combine(pp.QuotedString('`', unquoteResults=False) + '.' + pp.QuotedString('`', unquoteResults=False))]).setResultsName('referenced_table') + pp.QuotedString('(', endQuoteChar=')').setResultsName('referenced_attributes'))
def build_grammar(self): def flatten(tokens): return tokens[0] def add_back_trailing_slash(tokens): if tokens: tokens[0] += "/" return tokens registry = pp.Optional( self.pp_word(without="/").setResultsName("registry") + "/") username = pp.Optional( pp.OneOrMore(self.pp_word(without="/") + pp.Suppress("/")).addParseAction("/".join). setResultsName("username")).addParseAction(add_back_trailing_slash) image = self.pp_word(without="/:").setResultsName("image") tag = pp.Optional(":" + self.pp_word().setResultsName("tag")) full_image = pp.Combine(registry + username + image + tag).setResultsName("full_image_name") full_image.addParseAction(flatten) stage_name = pp.Optional( pp.CaselessLiteral("as") + self.pp_word().setResultsName("stage_name")) grammar = full_image + stage_name return grammar
def WithParser( callback, *args ): """Lazily creates the parser, calls callback with the pp.ParserElement instance as the sole argument. @param callback callable( parser, *args ) """ RangeExpression.fParserLock_.acquire() try: # -- Create parser if necessary # -- if RangeExpression.fParser_ is None: #logical_op = pp.Or( [ pp.CaselessLiteral( 'and' ), pp.Literal( '&&' ) ] ) logical_op = pp.CaselessLiteral( 'and' ) ^ pp.Literal( '&&' ) word = pp.Word( pp.alphas ) op = pp.oneOf( '!= <= < >= >' ) number = pp.Word( pp.nums + '.Ee+-' ) expr = pp.Optional( word ).suppress() + op + number #expr = pp.ZeroOrMore( word ).suppress() + op + number RangeExpression.fParser_ = \ expr + pp.Optional( logical_op ).suppress() + pp.Optional( expr ) #end if callback( RangeExpression.fParser_, *args ) finally: RangeExpression.fParserLock_.release()
def __init__(self): self.digits = pp.Word(pp.nums) self.plus_or_minus = pp.oneOf("+ -") self.opt_plus_minus = pp.Optional(self.plus_or_minus) self.mul_or_div = pp.oneOf("* /") self.point = pp.Word(".") self.left_par = pp.Literal("(") self.right_par = pp.Literal(")") self.unsigned_int = self.digits self.signed_int = pp.Combine(self.plus_or_minus + self.unsigned_int) self.opt_signed_int = (pp.Combine(self.opt_plus_minus + self.unsigned_int) .setParseAction(lambda el: int(el[0]))) self.float_num = (((self.unsigned_int + self.point + pp.Optional(self.unsigned_int)) ^ (self.point + self.unsigned_int)) + pp.Optional(pp.CaselessLiteral("e") + self.opt_signed_int)) self.real_num_pos = (pp.Combine(self.float_num).setParseAction(lambda el: float(el[0])) ^ self.unsigned_int.setParseAction(lambda el: int(el[0]))) self.real_num = (pp.Combine(self.opt_plus_minus + self.float_num).setParseAction(lambda el: float(el[0])) ^ self.opt_signed_int.setParseAction(lambda el: int(el[0]))) self.variable_name = pp.Word(pp.alphas + "_", pp.alphas + pp.nums + "_")
def _parse_expr(text, ldelim='(', rdelim=')'): """ Parse mathematical expression using PyParsing """ var = pyparsing.Word(pyparsing.alphas+'_', pyparsing.alphanums+'_') point = pyparsing.Literal('.') exp = pyparsing.CaselessLiteral('E') number = pyparsing.Combine( pyparsing.Word('+-'+pyparsing.nums, pyparsing.nums)+ pyparsing.Optional( point+pyparsing.Optional(pyparsing.Word(pyparsing.nums)) )+ pyparsing.Optional( exp+pyparsing.Word('+-'+pyparsing.nums, pyparsing.nums) ) ) atom = var | number oplist = [ (pyparsing.Literal('**'), 2, pyparsing.opAssoc.RIGHT), (pyparsing.oneOf('+ - ~'), 1, pyparsing.opAssoc.RIGHT), (pyparsing.oneOf('* / // %'), 2, pyparsing.opAssoc.LEFT), (pyparsing.oneOf('+ -'), 2, pyparsing.opAssoc.LEFT), (pyparsing.oneOf('<< >>'), 2, pyparsing.opAssoc.LEFT), (pyparsing.Literal('&'), 2, pyparsing.opAssoc.LEFT), (pyparsing.Literal('^'), 2, pyparsing.opAssoc.LEFT), (pyparsing.Literal('|'), 2, pyparsing.opAssoc.LEFT), ] # Get functions expr = pyparsing.infixNotation( atom, oplist, lpar=pyparsing.Suppress(ldelim), rpar=pyparsing.Suppress(rdelim) ) return expr.parseString(text)[0]
def language_def(self): and_ = pp.CaselessLiteral("and") or_ = pp.CaselessLiteral("or") not_ = pp.CaselessLiteral("not") number = (pp.Word(pp.nums)).setParseAction(Number) functionname = pp.Word(pp.alphanums + '_').setParseAction(Identifier) functionbody = pp.Forward() functionbody <<= functionname + (pp.Suppress("(") + pp.Optional(pp.delimitedList(number),'') + pp.Suppress(")")) condition = functionbody | functionname condition.setParseAction(Condition) not_condition = (not_ + condition | condition).setParseAction(NotCondition) and_condition = (not_condition + pp.ZeroOrMore(and_ + not_condition)).setParseAction(AndCondition) or_condition = (and_condition + pp.ZeroOrMore(or_ + and_condition)).setParseAction(OrCondition) return or_condition
def grammar(cls): """Grammar to parse a color value""" hex3 = (pp.Suppress(pp.Literal('#')) + pp.Word(cls.HEX_CHARS, exact=3).leaveWhitespace()) hex6 = (pp.Suppress(pp.Literal('#')) + pp.Word(cls.HEX_CHARS, exact=6).leaveWhitespace()) rgb = (pp.Suppress(pp.CaselessLiteral('rgb(')) + Number.grammar() + pp.Suppress(pp.Literal(',')) + Number.grammar() + pp.Suppress(pp.Literal(',')) + Number.grammar() + pp.Suppress(pp.Literal(')'))) rgba = (pp.Suppress(pp.CaselessLiteral('rgba(')) + Number.grammar() + pp.Suppress(pp.Literal(',')) + Number.grammar() + pp.Suppress(pp.Literal(',')) + Number.grammar() + pp.Suppress(pp.Literal(',')) + Number.grammar() + pp.Suppress(pp.Literal(')'))) return hex6 | hex3 | rgba | rgb
def grammar(cls): """Grammar to parse the length value""" number = Number.grammar() units = pp.CaselessLiteral(cls.UNITS[0]) for unit in cls.UNITS[1:]: units |= pp.Literal(unit) return number + units.leaveWhitespace()
def expr(cls): parts = [pp.CaselessLiteral(i) for i in cls.options] m = pp.MatchFirst(parts) spec = m | TokValue.copy() spec = spec.setParseAction(lambda x: cls(*x)) if cls.preamble: spec = pp.Literal(cls.preamble).suppress() + spec return spec
def expr(cls): parts = [pp.CaselessLiteral(i) for i in cls.names.keys()] m = pp.MatchFirst(parts) spec = m | v_integer.copy() spec = spec.setParseAction(lambda x: cls(*x)) if cls.preamble: spec = pp.Literal(cls.preamble).suppress() + spec return spec
def parse_constraint_line(line): obs = pp.Word(pp.alphas, pp.alphanums+'_.') point = pp.Literal(".") e = pp.CaselessLiteral("E") const = pp.Combine(pp.Word("+-" + pp.nums, pp.nums) + pp.Optional(point + pp.Optional(pp.Word(pp.nums))) + pp.Optional(e + pp.Word("+-" + pp.nums, pp.nums))) iop = pp.oneOf("< <= > >=") ineq0 = obs + iop + (obs ^ const) ineq1 = const + iop + obs ineq = ineq0 ^ ineq1 equals = pp.Suppress('=') obs_crit = obs - equals - const enforce_crit = const | obs_crit enforce_at = pp.CaselessLiteral('at') - pp.Group(enforce_crit) - pp.Optional(pp.oneOf('everytime first', caseless=True)) -\ pp.Optional(pp.CaselessLiteral('before')) enforce_between = pp.CaselessLiteral('between') - pp.Group(enforce_crit) - pp.Suppress(',') - pp.Group(enforce_crit) enforce_other = pp.oneOf('once always', caseless=True) enforce = enforce_at ^ enforce_between ^ enforce_other min = pp.CaselessLiteral('min') - const.setResultsName('min') penalty = pp.CaselessLiteral('altpenalty') - pp.Group(ineq).setResultsName('altpenalty') wt_expr = const.setResultsName('weight') - pp.Optional(penalty) - pp.Optional(min) weight = pp.CaselessLiteral('weight') - wt_expr comment = pp.Suppress(pp.Literal('#') - pp.ZeroOrMore(pp.Word(pp.printables))) constraint = pp.Group(ineq).setResultsName('ineq') + pp.Group(enforce).setResultsName('enforce') + \ pp.Optional(pp.Group(weight).setResultsName('weight_expr')) + pp.Optional(comment) return constraint.parseString(line, parseAll=True)
def __init__(self): self.session_keys = {} self.encrypted_data = None self.info = {} self.base64_buf = [] self.key_block = False self.data_block = False self.p1735 = False protect_kw = pp.Keyword('`pragma protect').suppress() identifier = pp.Word(pp.alphas, pp.alphanums + "_") number = pp.Word(pp.nums).setParseAction(lambda t: int(t[0])) string = pp.dblQuotedString().setParseAction(pp.removeQuotes) equals = pp.Suppress("=") lbrace = pp.Suppress('(') rbrace = pp.Suppress(')') simpleAssignment = (identifier + equals + (number | string)).setParseAction( self.assignment_action) multiAssignment = simpleAssignment + pp.ZeroOrMore(',' + simpleAssignment) tupleAssignment = identifier + equals + lbrace + multiAssignment + rbrace assignment = protect_kw + (multiAssignment | tupleAssignment) PSTART = (protect_kw + pp.CaselessLiteral('begin_protected')).setParseAction( self.begin) PFINISH = (protect_kw + pp.CaselessLiteral('end_protected')).setParseAction( self.finish) key_block = (protect_kw + pp.CaselessLiteral('key_block')).setParseAction( self.begin_key_block) data_block = (protect_kw + pp.CaselessLiteral('data_block')).setParseAction( self.begin_data_block) base64_string = pp.Word(pp.alphanums + "+-/=").setParseAction( self.base64_action) emptyLine = (pp.LineStart() + pp.LineEnd()).suppress() self.parser = (PSTART | assignment | key_block | data_block | base64_string | emptyLine | PFINISH)
def float(self): # set up a float, allow scientific notation point = pp.Literal( "." ) e = pp.CaselessLiteral( "E" ) ppFloat = pp.Combine( pp.Word( "+-"+pp.nums, pp.nums ) + pp.Optional( point + pp.Optional( pp.Word( pp.nums ) ) ) + pp.Optional( e + pp.Word( "+-"+pp.nums, pp.nums ) ) ) def onParse(token): return float(token[0]) ppFloat.setParseAction(onParse) return ppFloat
def parse_search_category_request(request): logging.debug("Entered function parse_search_category_request().") #command = search_command + category_files_command #command = command + for_command + top_command + results_count #command = command + hitsfor_command #command = command + pp.Group(search_terms).setResultsName("searchterms") command = None number_of_search_results = 10 category = "" searchterms = [] logging.debug("Value of globals.search_categories: %s" % globals.search_categories) for i in globals.search_categories: logging.debug("Trying category %s." % i) command = search_command category_command = pp.CaselessLiteral(i).setResultsName("category") # Assemble the search command custom for this iteration of the loop. # The process is unrolled to make it easier to understand, and thus # maintain later. command = command + category_command command = command + for_command # There has to be a better way to do this. I haven't figured it out # yet, though. command = command + pp.Optional(top_command) command = command + pp.Optional(results_count) command = command + pp.Optional(hitsfor_command) command = command + pp.Group(search_terms).setResultsName( "searchterms") # See if the newly assembled command matches. try: parsed_command = command.parseString(request) # Extract the specifics. number_of_search_results = word_and_number(parsed_command["count"]) search_term = make_search_term(parsed_command["searchterms"]) category = parsed_command["category"] # Append the search category to the search term. search_term = search_term + "&categories=" + i # Yup. return (number_of_search_results, search_term, "XMPP") except pp.ParseException as x: # Nope. logging.debug("Category %s didn't work." % i) # Trap case: No categories matched. logging.info("No categories matched.") return (None, None, None)
def parse_math_expr(estr): """ Function to parse algebraic expressions. This function identifies built-in functions, numbers, variables and previously defined functions as they occur in algebraic expressions. Functions are alphanumeric strings starting with a letter. They are preceded by an arithmetic operator or a parenthesis and encompass something in parentheses. Parameters are also alphanumeric strings starting with a letter. They are preceded and succeeded by operators or parentheses Parameters ---------- estr : str String in BNGL file corresponding to an algebraic expression Returns ------- list List of algebraic tokens, including functions, variables, numbers, and operators """ point = pp.Literal(".") e = pp.CaselessLiteral("E") fnumber = pp.Combine(pp.Word("+-" + pp.nums, pp.nums) + pp.Optional(point + pp.Optional(pp.Word(pp.nums))) + pp.Optional(e + pp.Word("+-" + pp.nums, pp.nums))) ident = pp.Word(pp.alphas, pp.alphas + pp.nums + "_") plus = pp.Literal("+") minus = pp.Literal("-") mult = pp.Literal("*") div = pp.Literal("/") lpar = pp.Literal("(") rpar = pp.Literal(")") addop = plus | minus multop = mult | div expop = pp.Literal("^") lowerPi = pp.Literal("pi") upperPi = pp.Literal("PI") pi = lowerPi | upperPi func = pp.Combine(ident + lpar + rpar) expr = pp.Forward() atom = (pp.Optional("-") + (pi ^ e ^ fnumber ^ ident + lpar + expr + rpar ^ func ^ ident) ^ (lpar + expr + rpar)) factor = pp.Forward() factor << atom + pp.ZeroOrMore((expop + factor)) term = factor + pp.ZeroOrMore((multop + factor)) expr << term + pp.ZeroOrMore((addop + term)) pattern = expr return pattern.parseString(estr.strip())
def __init__(self): """ BNF HERE """ #integer = pp.Word(nums) #floatNumber = pp.Regex(r'\d+(\.\d*)?([eE]\d+)?') point = pp.Literal(".") e = pp.CaselessLiteral("E") # Regex string representing the set of possible operators # Example : ">=|<=|!=|>|<|=" OPERATOR_RX = '|'.join( [re.sub('\|', '\|', o) for o in Predicate.operators.keys()]) # predicate field = pp.Word(pp.alphanums + '_') operator = pp.Regex(OPERATOR_RX).setName("operator") value = pp.QuotedString( '"' ) #| pp.Combine( pp.Word( "+-"+ pp.nums, pp.nums) + pp.Optional( point + pp.Optional( pp.Word( pp.nums ) ) ) + pp.Optional( e + pp.Word( "+-"+pp.nums, pp.nums ) ) ) predicate = (field + operator + value).setParseAction( self.handlePredicate) # clause of predicates and_op = pp.CaselessLiteral("and") | pp.Keyword("&&") or_op = pp.CaselessLiteral("or") | pp.Keyword("||") not_op = pp.Keyword("!") predicate_precedence_list = [ (not_op, 1, pp.opAssoc.RIGHT, lambda x: self.handleClause(*x)), (and_op, 2, pp.opAssoc.LEFT, lambda x: self.handleClause(*x)), (or_op, 2, pp.opAssoc.LEFT, lambda x: self.handleClause(*x)) ] clause = pp.operatorPrecedence(predicate, predicate_precedence_list) self.bnf = clause
def expr_pyparse(full_expr): """ Run the full string evaluation expression through initial parsing. This should be some combination of AND,ORs using appropriate parenthesis, and the evaluation statement should looks like so: KEYWORD = "value" for strings, KEYWORD = value for integer/float values. Example of full expression: "(BUNIT = 'UNITLESS' and NAXIS1 = 1014) OR BUNIT='ELECTRONS/S'" Can use lower or upper case for or/and argument, and spaces around operators not required. Parameters ---------- full_expr : string Returns ------- list nested list of expression elements, where inner list has [keyword, operator, value] """ # Setup "word" patterns and_ = pyp.CaselessLiteral('and') or_ = pyp.CaselessLiteral('or') keyword = pyp.Word(pyp.alphanums + '_' + '-') value = (pyp.Word(pyp.nums + '.') | pyp.quotedString.setParseAction(pyp.removeQuotes)) expr = pyp.Word('=<>') searchTerm = pyp.Group(keyword + expr + value) searchExpr = pyp.operatorPrecedence(searchTerm, [ (and_, 2, pyp.opAssoc.LEFT), (or_, 2, pyp.opAssoc.LEFT), ]) # change this to catch exception, this is most likely where parsing # exception will happen from bad user input return searchExpr.parseString(full_expr, parseAll=True).asList()
def _compile_literal(self, element, src_state, dst_state, grammar, kaldi_rule, fst): # "insert" new states for individual words words = element.words words = map(str, words) # FIXME: handle unicode matcher = pp.CaselessLiteral(' '.join(words)) words = self.translate_words(words) states = [src_state ] + [fst.add_state() for i in range(len(words) - 1)] + [dst_state] for i, word in enumerate(words): s1 = states[i] s2 = states[i + 1] fst.add_arc(s1, s2, word.lower()) return matcher
def _get_parser(): def _object(string, location, tokens): token = tokens[0] tokens[0] = (_OBJ, token) def _integer(string, location, tokens): try: token = int(tokens[0]) except ValueError: token = tokens[0] tokens[0] = (_OBJ, token) def _number(string, location, tokens): try: token = float(tokens[0]) except ValueError: token = tokens[0] tokens[0] = (_OBJ, token) def _test(string, location, tokens): token = tokens[0] tokens[0] = (_TEST, token) def _if(string, location, tokens): token = tokens[0] tokens[0] = (_IF, token) def _expr_var(string, location, tokens): token = tokens[0] tokens[0] = (_VALUE, token) def _expr_test(string, location, tokens): token = tokens[0] tokens[0] = (_TEST, token) white_space = pp.White().suppress() end = pp.StringEnd() operator = (pp.Literal(_EQUAL) | pp.Literal(_NOT_EQUAL)).setParseAction(_test) begin_if = pp.CaselessLiteral(_IF, ).setParseAction(_if) obj = pp.Word(pp.printables).setParseAction(_object) integer = pp.Word('0123456789-').setParseAction(_integer) number = pp.Word('0123456789-.').setParseAction(_number) item = integer | number | obj expr_var = pp.Group(obj + pp.Optional(white_space) + end).setParseAction(_expr_var) expr_test = pp.Group(obj + white_space + begin_if + white_space + item + white_space + operator + white_space + item).setParseAction(_expr_test) expr = pp.Optional(white_space) + (expr_test | expr_var) return expr
def _adapt_match_expression(self, match_expression): """ Convenience method to wrap pyparsing, regex, string, or unicode expression as pyparsing. """ # One might argue that we shouldn't do this kind of type-checking in # Python, but this is the simplest way I know to do this (this is effectively # an ad-hoc "adapter" for string, unicode, regex, and pyparsing to pyparsing) if type(match_expression) in (str, unicode): return pyparsing.CaselessLiteral(match_expression) elif type(match_expression) == type(re.compile('')): return pyparsing.Regex(match_expression.pattern + '$') elif isinstance(match_expression, pyparsing.ParserElement): return match_expression else: raise TypeError("Match object must be string, unicode, " "regular expression or pyparsing parse expression" "(not %s)" % repr(type(match_expression)))
def parse_value_and_unit(text): """ When a text is given by "value (unit)", returns them. value :: fracion | real | integer NO arithmetic operation is allowed. """ # elementary operations div = pp.Literal("/") lpar = pp.Literal("(").suppress() rpar = pp.Literal(")").suppress() # parser for numbers nums = pp.nums integer = pp.Word("+-" + nums, nums) point = pp.Literal(".") e = pp.CaselessLiteral("e") fraction = pp.Combine(integer + div + integer) real = pp.Combine( pp.Word( "+-"+nums, nums ) \ + pp.Optional( point + pp.Optional( pp.Word( nums ) ) ) \ + pp.Optional( e + pp.Word( "+-"+nums, nums ) ) ) number_term = pp.Forward() number = fraction | real | integer | (lpar + number_term + rpar) number_term << number # define BNF(Backus-Naur Form) #bnf = number_term + pp.ZeroOrMore( pp.Word( " ()[]*/^+-"+pp.alphas+nums) ) bnf = number_term + pp.restOfLine() result = bnf.parseString(text) value = 0 unit_strg = '' if len(result) > 0: value_strg = result[0] if '/' in value_strg: # if a fraction value = Fraction(value_strg) elif ('.' in value_strg) or ('e' in value_strg): # if a real number value = float(value_strg) else: value = int(value_strg) if len(result) > 1: unit_strg = result[1] return (value, MetricUnit(unit_strg))
def BNF(decorate): """This function returns the parser for the language of arithmetic expressions. """ # function to perform calculations on the AST def fnumberFunc(s, loc, tok): text = "".join(tok) return float(text) def op(s, loc, tok): v = tok[0] for i in range(1, len(tok), 2): v = tok[i](v, tok[i+1]) return v def factorOp(s, loc, tok): if "-" == tok[0]: return - tok[1] return tok[0] # the grammar itself point = pp.Literal( "." ) e = pp.CaselessLiteral( "E" ) fnumber = pp.Combine( pp.Word( "+-" + pp.nums, pp.nums ) + pp.Optional( point + pp.Optional( pp.Word( pp.nums ) ) ) + pp.Optional( e + pp.Word( "+-"+pp.nums, pp.nums ) ) ) fnumber.setParseAction(decorate("float", fnumberFunc)) plus = pp.Literal( "+" ).setParseAction(decorate("+", lambda s, loc, tok: operator.add)) minus = pp.Literal( "-" ).setParseAction(decorate("-", lambda s, loc, tok: operator.sub)) mult = pp.Literal( "*" ).setParseAction(decorate("*", lambda s, loc, tok: operator.mul)) div = pp.Literal( "/" ).setParseAction(decorate("/", lambda s, loc, tok: operator.truediv)) lpar = pp.Literal( "(" ).suppress() rpar = pp.Literal( ")" ).suppress() addop = plus | minus multop = mult | div expr = pp.Forward() factor = (pp.Optional("-") + ( fnumber | lpar + expr + rpar ) ).setParseAction(decorate("factor", factorOp)) term = (factor + pp.ZeroOrMore( multop + factor)).setParseAction( decorate("term", op )) expr << (term + pp.ZeroOrMore( addop + term )).setParseAction(decorate("expr", op)) return expr
def get_parser( parse_action ): """ atom :: '1' | unit | '(' term ')' number :: integer | fraction | real | '(' number ')' factor :: atom + expop + number | atom term :: factor [ multop factor ]* """ # parser for elementary operations mult = pp.Literal( "*" ) | pp.White(max=1) div = pp.Literal( "/" ) lpar = pp.Literal( "(" ).suppress() rpar = pp.Literal( ")" ).suppress() multop = div | pp.Optional(mult, default='*') expop = pp.Literal( "^" ) # parser for numbers nums = pp.nums integer = pp.Word( "+-"+nums, nums ) point = pp.Literal(".") e = pp.CaselessLiteral( "e" ) fraction = pp.Combine( integer + div + integer ) real = pp.Combine( pp.Word( "+-"+nums, nums ) \ + pp.Optional( point + pp.Optional( pp.Word( nums ) ) ) \ + pp.Optional( e + pp.Word( "+-"+nums, nums ) ) ) number_term = pp.Forward() number = fraction | real | integer | (lpar + number_term + rpar) number_term << number # parser for units prefix_symbols = ''.join(' '+symbol for symbol in MetricPrefix.symbols()) nonprefix_symbols = ''.join(' '+symbol for symbol in MetricNonprefix.symbols()) prefix = pp.oneOf(prefix_symbols) nonprefix = pp.oneOf(nonprefix_symbols) unit = pp.Combine(prefix + nonprefix) | nonprefix # define BNF(Backus-Naur Form) term = pp.Forward() atom = pp.Literal("1").setParseAction(parse_action) | unit.setParseAction(parse_action) | ( lpar + term.suppress() + rpar ) factor = atom + pp.ZeroOrMore( ( pp.Optional(expop,default='^') + number_term ).setParseAction(parse_action) ) term << factor + pp.ZeroOrMore( (multop + factor.suppress()).setParseAction(parse_action) ) bnf = pp.Literal("[") + term + pp.Literal("]") | term return bnf
def _make_parser(): word = pp.CharsNotIn(''.join(whitespace)) word.skipWhitespace = True value = pp.MatchFirst([ pp.dblQuotedString.copy().setParseAction(pp.removeQuotes), pp.sglQuotedString.copy().setParseAction(pp.removeQuotes), pp.Empty() + pp.CharsNotIn(''.join(whitespace)), ]) expressions = [] for field in named_fields: exp = pp.Suppress(pp.CaselessLiteral(field) + ':') + \ value.copy().setParseAction(_decorate_match(field)) expressions.append(exp) any_ = value.copy().setParseAction(_decorate_match('any')) expressions.append(any_) return pp.ZeroOrMore(pp.MatchFirst(expressions))