def domain_literal(): optional(CFWS) square() many(partial(seq, partial(optional, FWS), dtext)) optional(FWS) unsquare() optional(CFWS)
def quoted_string(): optional(CFWS) DQUOTE() many(partial(seq, partial(optional, FWS), qcontent)) optional(FWS) DQUOTE() optional(CFWS)
def identifier(first=partial(one_of, ascii_letters), consecutive=partial(one_of, ascii_letters + digit_chars + '_'), must_contain=set(digit_chars)): """Expects a letter followed by one or more alphanumerical characters. If ``must_contain`` is given, the following letters must include one from this set. The default option is to expect a letter followed by a number of letters and digits, but with a requirement of at least one digit (this allows an easy distinction between names and identifiers). >>> parse(identifier, 'abc123') 'abc123' >>> parse(identifier, 'abc') # doctest: +ELLIPSIS Traceback (most recent call last): ... NoMatch: ... >>> parse(partial(identifier, must_contain=None), 'abc') 'abc' """ result = [] if first is not None: result.append(first()) if must_contain is None: chars = many(consecutive) else: chars = many1(partial(choice, consecutive, partial(one_of, must_contain))) if not set(chars) & must_contain: fail() result.extend(chars) return result
def identifier(): whitespace() not_followed_by(p(choice, *[p(reserved, rw) for rw in reserved_words])) first = identifier_char1() commit() rest = many(identifier_char) name = u''.join([first] + rest) return ('ident', name)
def parse(cls): one_of('+') caseless_string('epi') aggregates = {} if whitespace(): while peek(): try: code = "".join(pico.one_of_strings(*( tuple(cls.TOKENS) + tuple(cls.ALIAS)))) code = code.upper() except: raise FormatError( "Expected an epidemiological indicator " "such as TB or MA (got: %s)." % \ "".join(remaining())) # rewrite alias code = cls.ALIAS.get(code, code) if code in aggregates: raise FormatError("Duplicate value for %s." % code) whitespace1() try: minus = optional(partial(one_of, '-'), '') value = int("".join([minus]+pico.digits())) except: raise FormatError("Expected a value for %s." % code) if value < 0: raise FormatError("Got %d for %s. You must " "report a positive value." % ( value, cls.TOKENS[code].lower())) aggregates[code] = value many(partial(one_of, ' ,;.')) return { 'aggregates': aggregates }
def parse(cls, keyword=None, keywords=None): if keywords is None: keywords = cls.KEYWORDS slug = keywords[keyword.lower()] kind = ReportKind.objects.get(slug=slug) observations = {} result = { 'observations': observations, 'kind': kind, } total = "".join(optional(pico.digits, ())) if total: result['total'] = int(total) many1(partial(one_of, ' ,;')) kinds = ObservationKind.objects.filter(slug__startswith="%s_" % slug).all() observation_kinds = dict((kind.slug, kind) for kind in kinds) codes = [kind.abbr for kind in kinds if kind.abbr] # we allow both the observation kinds and any aliases allowed_codes = tuple(codes) + tuple(cls.ALIASES) while peek(): # look up observation kinds that double as user input # for the aggregate codes try: code = "".join(pico.one_of_strings(*allowed_codes)).lower() except: raise FormatError( "Expected an indicator code " "such as %s (got: %s)." % ( " or ".join(map(unicode.upper, codes[:2])), "".join(remaining()).strip() or u"nothing")) # rewrite alias if required, then look up kind munged= "%s_%s" % (slug, code) munged = cls.ALIASES.get(munged, munged) kind = observation_kinds[munged] # guard against duplicate entries if kind.slug in observations: raise FormatError("Duplicate value for %s." % code) whitespace() try: minus = optional(partial(one_of, '-'), '') value = int("".join([minus]+pico.digits())) except: raise FormatError("Expected a value for %s." % code) if value < 0: raise FormatError("Got %d for %s. You must " "report a positive value." % ( value, kind.name)) observations[kind.slug] = value many(partial(one_of, ' ,;.')) return result
def comment(): paren() many(partial(seq, partial(optional, FWS), ccontent)) optional(FWS)
def hex_value(): return int(build_string(many(hex_decimal_digit)), 16)
def program(): prog = many(program_part) whitespace() eof() return ('prog', prog)
def prolog(): whitespace() optional(tri(partial(processing, xmldecl)), None) many(partial(choice, processing, comment, whitespace1)) optional(doctype, None) many(partial(choice, processing, comment, whitespace1))
def open_element(name): close_angle() children = many(node) end_element(name) return children
def xml_name(): return build_string([name_start_char()] + many(name_char))