def instance(): lit_e = CaselessLiteral('E') plusorminus = Literal('+') | Literal('-') number = Word(nums) integer = Combine(Optional(plusorminus) + number).setParseAction(lambda t:int(t[0])) index = integer.copy().addParseAction(index_check(0)) floatnumber = Combine( integer + Optional( Literal('.') + Optional(number) ) + Optional( lit_e + integer ) ).setParseAction(lambda t:float(t[0])) #comment = Suppress("%") + Word(alphanums + " ") comment = Regex(r"%.*").setName("comment").suppress() linend = Or( [comment , LineEnd()] ).suppress() section_end = (Literal('#') + LineEnd()).suppress() vertex = (Group( OneOrMore( floatnumber('point') + OneOrMore( White() ).suppress() ) ) + linend)('vertex') vertex_header = (Keyword('VERTEX') + linend).suppress() vertex_section = (vertex_header + Group(OneOrMore(vertex))('vertices') + section_end) simplex = (Group( OneOrMore( index('index') + OneOrMore( White() ).suppress() ) ) + linend)('simplex') simplex_header = (Keyword('SIMPLEX') + linend).suppress() simplex_section = (simplex_header + Group(OneOrMore(simplex))('simplices') + section_end) boundarysegment = (Group( index('id') + OneOrMore( index('index') + OneOrMore( White() ).suppress() ) ) + linend)('boundarysegment') boundarysegment_header = (Keyword('BOUNDARYSEGMENTS') + linend).suppress() boundarysegment_section = (boundarysegment_header + Dict(OneOrMore( boundarysegment ))('boundarysegments') + section_end) sections = Each([vertex_section, simplex_section, boundarysegment_section]) dgf_header = (Keyword('DGF') + linend).suppress() dgf = (dgf_header + Dict(sections) + OneOrMore( section_end ))('dgf') return dgf
def instance(): lit_e = CaselessLiteral('E') plusorminus = Literal('+') | Literal('-') number = Word(nums) integer = Combine(Optional(plusorminus) + number).setParseAction(lambda t: int(t[0])) index = integer.copy().addParseAction(index_check(0)) floatnumber = Combine(integer + Optional(Literal('.') + Optional(number)) + Optional(lit_e + integer)).setParseAction( lambda t: float(t[0])) #comment = Suppress("%") + Word(alphanums + " ") comment = Regex(r"%.*").setName("comment").suppress() linend = Or([comment, LineEnd()]).suppress() section_end = (Literal('#') + LineEnd()).suppress() vertex = (Group( OneOrMore(floatnumber('point') + OneOrMore(White()).suppress())) + linend)('vertex') vertex_header = (Keyword('VERTEX') + linend).suppress() vertex_section = (vertex_header + Group(OneOrMore(vertex))('vertices') + section_end) simplex = ( Group(OneOrMore(index('index') + OneOrMore(White()).suppress())) + linend)('simplex') simplex_header = (Keyword('SIMPLEX') + linend).suppress() simplex_section = (simplex_header + Group(OneOrMore(simplex))('simplices') + section_end) boundarysegment = (Group( index('id') + OneOrMore(index('index') + OneOrMore(White()).suppress())) + linend)('boundarysegment') boundarysegment_header = (Keyword('BOUNDARYSEGMENTS') + linend).suppress() boundarysegment_section = ( boundarysegment_header + Dict(OneOrMore(boundarysegment))('boundarysegments') + section_end) sections = Each([vertex_section, simplex_section, boundarysegment_section]) dgf_header = (Keyword('DGF') + linend).suppress() dgf = (dgf_header + Dict(sections) + OneOrMore(section_end))('dgf') return dgf
(Keyword("distinct", caseless=True)("op").setDebugActions(*debug) + expr("params")).addParseAction(to_json_call) | Keyword("null", caseless=True).setName("null").setDebugActions(*debug) | case | (Literal("(").setDebugActions(*debug).suppress() + selectStmt + Literal(")").suppress()) | (Literal("(").setDebugActions(*debug).suppress() + Group(delimitedList(expr)) + Literal(")").suppress()) | realNum.setName("float").setDebugActions(*debug) | intNum.setName("int").setDebugActions(*debug) | (Literal("-")("op").setDebugActions(*debug) + expr("params")).addParseAction(to_json_call) | sqlString.setName("string").setDebugActions(*debug) | ( Word(alphas)("op").setName("function name").setDebugActions(*debug) + Literal("(").setName("func_param").setDebugActions(*debug) + Optional(selectStmt | Group(delimitedList(expr)))("params") + ")" ).addParseAction(to_json_call).setDebugActions(*debug) | ident.copy().setName("variable").setDebugActions(*debug) ) expr << Group(infixNotation( compound, [ ( o, 3 if isinstance(o, tuple) else 2, opAssoc.LEFT, to_json_operator ) for o in KNOWN_OPS ]+[ ( COLLATENOCASE, 1,
filtertype.setName('filtertype') simple = attr + filtertype + value simple.leaveWhitespace() simple.setName('simple') def _p_simple(s, l, t): attr, filtertype, value = t return filtertype(attributeDesc=pureldap.LDAPAttributeDescription(attr), assertionValue=pureldap.LDAPAssertionValue(value)) simple.setParseAction(_p_simple) present = attr + "=*" present.setParseAction(lambda s, l, t: pureldap.LDAPFilter_present(t[0])) initial = value.copy() initial.setParseAction( lambda s, l, t: pureldap.LDAPFilter_substrings_initial(t[0])) initial.setName('initial') any_value = value + Suppress(Literal("*")) any_value.setParseAction( lambda s, l, t: pureldap.LDAPFilter_substrings_any(t[0])) any = Suppress(Literal("*")) + ZeroOrMore(any_value) any.setName('any') final = value.copy() final.setName('final') final.setParseAction( lambda s, l, t: pureldap.LDAPFilter_substrings_final(t[0])) substring = attr + Suppress( Literal("=")) + Group(Optional(initial) + any + Optional(final)) substring.setName('substring')
| intNum.setName("int").setDebugActions(*debug) | (Literal("-")("op").setDebugActions(*debug) + expr("params")).addParseAction( to_json_call ) | sqlString.setName("string").setDebugActions(*debug) | ( Word(alphas)("op").setName("function name").setDebugActions(*debug) + Literal("(").setName("func_param").setDebugActions(*debug) + Optional( selectStmt.addParseAction(subquery_call) | Group(delimitedList(expr)) )("params") + ")" ) .addParseAction(to_json_call) .setDebugActions(*debug) | ident.copy().setName("variable").setDebugActions(*debug) ) expr << Group( infixNotation( compound, [ (o, 3 if isinstance(o, tuple) else 2, opAssoc.LEFT, to_json_operator) for o in KNOWN_OPS ] + [(COLLATENOCASE, 1, opAssoc.LEFT, to_json_operator)], ) .setName("expression") .setDebugActions(*debug) ) # SQL STATEMENT
filtertype.setName('filtertype') simple = attr + filtertype + value simple.leaveWhitespace() simple.setName('simple') def _p_simple(s, l, t): attr, filtertype, value = t return filtertype(attributeDesc=pureldap.LDAPAttributeDescription(attr), assertionValue=pureldap.LDAPAssertionValue(value)) simple.setParseAction(_p_simple) present = attr + "=*" present.setParseAction(lambda s, l, t: pureldap.LDAPFilter_present(t[0])) initial = value.copy() initial.setParseAction(lambda s, l, t: pureldap.LDAPFilter_substrings_initial(t[0])) initial.setName('initial') any_value = value + Suppress(Literal("*")) any_value.setParseAction(lambda s, l, t: pureldap.LDAPFilter_substrings_any(t[0])) any = Suppress(Literal("*")) + ZeroOrMore(any_value) any.setName('any') final = value.copy() final.setName('final') final.setParseAction(lambda s, l, t: pureldap.LDAPFilter_substrings_final(t[0])) substring = attr + Suppress(Literal("=")) + Group(Optional(initial) + any + Optional(final)) substring.setName('substring') def _p_substring(s, l, t): attrtype, substrings = t
delim=".", combine=True))).setName("identifier") # EXPRESSIONS expr = Forward() # CASE case = (CASE + Group( ZeroOrMore((WHEN + expr("when") + THEN + expr("then")).addParseAction(to_when_call)))("case") + Optional(ELSE + expr("else")) + END).addParseAction(to_case_call) ordered_sql = Forward() call_function = ( ident.copy()("op").setName("function name").setDebugActions(*debug) + Literal("(").suppress() + Optional(ordered_sql | Group(delimitedList(expr)))("params") + Literal(")").suppress()).addParseAction(to_json_call).setDebugActions( *debug) def _or(values): output = values[0] for v in values[1:]: output |= v return output interval = ( Keyword("interval", caseless=True).suppress().setDebugActions(*debug) +
def get_parser(force=False): ''' @return: a pyparsing.ParserElement object with the usual parse methods, except that pyparsing.ParserElement.parseString overridden to return a ProcessGroup object instead of a pyparsing.ParseResults object for convenience. ''' global decay_parser, ID ######################################## ## Supporting parse classes ######################################## class ParsedDecay: def __init__(self, start, end, params): self.start = start if isinstance(end, ParseResults): end = end.asList() self.end = end self.params = params class ParsedParam: def __init__(self, name, value): self.name = name self.value = value class ParsedParticle: def __init__(self, name, params): self.name = name self.params = params class ParsedDefault: def __init__(self, params, for_particle): self.params = params self.for_particle = for_particle ######################################## ## Parser action functions ######################################## def push_param_stmt(code_str, loc, toks): """ toks will be of the form [param_name, param_value] """ return ParsedParam(toks[0], toks[1]) def push_edge_stmt(code_str, loc, toks): ''' toks will be a list of the form [start_name, end (, params)] ''' if len(toks) > 2: # Check for parameter list params = toks[2] else: params = {} end = toks[1] if isinstance(end, ParsedParticle): end_name = end.name else: end_name = end return ParsedDecay(toks[0], end_name, params) def push_node_stmt(code_str, loc, toks): """ toks will be a list of the form [name, params] """ if len(toks) > 1: # Check for parameter list params = toks[1] else: params = {} return ParsedParticle(toks[0], params) def push_param_list(code_str, loc, toks): """ toks will be a list of the form [ name1, name2, '=', val2, name3, ... ] """ params = {} i = 0 l = len(toks) while i < l: param_name = toks[i] if i + 2 < l and toks[i + 1] == '=': param_value = toks[i + 2] increment = 3 else: param_value = DEFAULT_PARAM_VALUE increment = 1 params[param_name] = param_value i += increment return params def push_default_stmt(code_str, loc, toks): ''' toks will be of the form ["particle", param_dict] or ["decay", param_dict] ''' return ParsedDefault(toks[1], toks[0].lower() == 'particle') def push_stmt_list(code_str, loc, toks): """ toks will be a ParseResults of Particle/ParsedDecay/ParsedParam objects """ proc_group = ProcessGroup() seen_particles = {} edges = [] particle_defaults = {} def params_for_object(obj, defaults): params = defaults.copy() params.update(obj.params) return params # Add particle objects we've generated already toks = toks.asList() for token in toks: if isinstance(token, ParsedDefault) and token.for_particle: particle_defaults.update(token.params) elif isinstance(token, ParsedParticle): #print 'Adding ', token.name seen_particles[token.name] = Particle( token.params.pop('type', token.name), **params_for_object(token, particle_defaults) ) def find_or_insert_particle(name): if seen_particles.has_key(name): #print 'Using existing particle for %s' % name return seen_particles[name] else: #print 'Creating %s' % name seen_particles[name] = Particle(name, **particle_defaults) # Type is assumed to be the name of the particle return seen_particles[name] # Next add decays and any particles they reference that we haven't found already particle_defaults = {} # Reset so that we can use the right defaults at each place in the file decay_defaults = {} for token in toks: if isinstance(token, ParsedDefault): if token.for_particle: particle_defaults.update(token.params) else: decay_defaults.update(token.params) elif isinstance(token, ParsedDecay): start = find_or_insert_particle(token.start) end = [] for end_point in token.end: end.append( find_or_insert_particle(end_point) ) params = params_for_object(token, decay_defaults) # If a particle was used twice, this should raise an error start.add_decay(end, **params) elif isinstance(token, ParsedParam): proc_group.add_param(token.name, token.value) seen_particles = seen_particles.values() # We allow for more than one root particle while len(seen_particles) > 0: decay_root = seen_particles[0] # Find the root of the current tree while decay_root.parent: decay_root = decay_root.parent # Now record everything under that root as dealt with, so we can see if there are more roots particles_to_delete = [decay_root] while len(particles_to_delete) > 0: particle = particles_to_delete.pop() seen_particles.remove(particle) decays = particle.decays for decay in decays: particles_to_delete.extend(decay) proc_group.add_root_particle(decay_root) return proc_group ######################################## ## Parser grammar definition ######################################## if force or not decay_parser: # Literals lbrace = Literal("{") rbrace = Literal("}") lbrack = Literal("[") rbrack = Literal("]") equals = Literal("=") comma = Literal(",") semi = Literal(";") minus = Literal("-") arrow = Combine(arrow_start + arrow_end) # keywords particle = CaselessKeyword("particle") decay = CaselessKeyword("decay") # token definitions float_number = Combine(Optional(minus) + OneOrMore(Word(nums + "."))).setName("float_number") param_list = Forward() stmt_list = Forward() param_val = (float_number | ID | param_list).setName("param_val") # We don't want to suppress the equals, since there may be parameters with no values param_sequence = OneOrMore(ID + Optional(equals + param_val) + Optional(comma.suppress())).setName("param_sequence") param_list << (lbrack.suppress() + Optional(param_sequence) + rbrack.suppress()).setName("param_list") # Here a parameter statement is required, since there is no point in having a default stmt with no parameters default_stmt = ( (particle | decay) + param_list ).setName("default_stmt") node_set = Group( lbrace.suppress() + ZeroOrMore(ID) + rbrace.suppress() ).setName("node_set") edgeop = arrow.copy().setName('edgeop') edgeRHS = edgeop.suppress() + node_set edge_stmt = ID + edgeRHS + Optional(param_list) node_stmt = (ID + Optional(param_list)).setName("node_stmt") param_stmt = (ID + equals.suppress() + param_val).setName('param_stmt') ### NOTE: THE ORDER OF THE stmt OPTIONS DETERMINES THE RESOLUTION ORDER FOR WHEN IT FINDS A NODE NAME!!! ### # Default statements have highest priority, since we want to prevent the use of their keywords as # node or param names. stmt = (default_stmt | param_stmt | edge_stmt | node_stmt).setName("stmt") stmt_list << OneOrMore(stmt + semi.suppress()) decay_parser = stmt_list + StringEnd() # Comments singleLineComment = Group("//" + restOfLine) | Group("#" + restOfLine) decay_parser.ignore(singleLineComment) decay_parser.ignore(cStyleComment) ######################################## ## Set parse actions ######################################## ''' def printAction(code_str, loc, toks): print toks return toks ''' stmt_list.setParseAction(push_stmt_list) edge_stmt.setParseAction(push_edge_stmt) node_stmt.setParseAction(push_node_stmt) param_list.setParseAction(push_param_list) param_stmt.setParseAction(push_param_stmt) default_stmt.setParseAction(push_default_stmt) # Make the top-level parse method return a PyDecay object, not a ParseResults decay_parser.parseString = new.instancemethod(lambda self, instring, parseAll=False: super(self.__class__, self).parseString(instring, parseAll)[0] , decay_parser, decay_parser.__class__) return decay_parser
hs_tzName = Regex(r'[A-Z][a-zA-Z0-9_\-]*') hs_tz_UTC_GMT = Literal('UTC') ^ 'GMT' hs_tzUTCOffset = Combine( hs_tz_UTC_GMT + Optional( hs_plusMinus + hs_digit[1, ...] ^ '0' )) hs_timeZoneName = hs_tzUTCOffset ^ hs_tzName hs_dateSep = CaselessLiteral('T') hs_date_str = Combine( hs_digit + hs_digit + hs_digit + hs_digit + '-' + hs_digit + hs_digit + '-' + hs_digit + hs_digit) hs_date = hs_date_str.copy().setParseAction( lambda toks: [datetime.datetime.strptime(toks[0], '%Y-%m-%d').date()]) hs_time_str = Combine( hs_digit + hs_digit + ':' + hs_digit + hs_digit + Optional( ':' + hs_digit + hs_digit + Optional( '.' + hs_digit[1, ...]) ) ) hs_time = hs_time_str.copy().setParseAction(_parse_time)
global _ws_state _ws_state = t[0] return "" def _word_action(t): global _ws_state if _ws_state: r = ''.join((_ws_state, t[0])) _ws_state = "" return r def _text_action(t): global _ws_state _ws_state = "" _text = Combine(OneOrMore(_word.copy().setParseAction(_word_action) | _ws.copy().setParseAction(_ws_action))).setParseAction(_text_action).setFailAction(lambda s, l, ex, err: _text_action(None)) _description = _text.copy() _decimal = Word(nums).setParseAction(lambda t: int(t[0])) _cmd_state = None def _get_reset_cmd_state_action(cmd): def _reset_cmd_state_action(t): global _cmd_state if cmd is None or (_cmd_state is not None and _cmd_state == cmd): _cmd_state = None return Empty().setParseAction(_reset_cmd_state_action) def _get_keyword_action(kw):