Ejemplo n.º 1
0
def test_lex(cards):
    """ Test the lexer against the given cards' text, logging failures. """
    card.map_multi(_lex, cards)
Ejemplo n.º 2
0
def test_lex(cards):
    """ Test the lexer against the given cards' text, logging failures. """
    card.map_multi(_lex, cards)
Ejemplo n.º 3
0
def parse_helper(cards, name, rulename, yesregex=None, noregex=None):
    """ Parse a given subset of text on a given subset of cards.

        This function may override some re flags on the
        provided regex objects.

        cards: An iterable of cards to search for matching text. To save time,
            the provided regexes will be used to pare down this list to just
            those that will actually have text to attempt to parse.
        name: The function will be named _parse_{name} and the results for
            card c will be saved to c.parsed_{name}.
        rulename: The name of the parser rule to run.
        yesregex: If provided, run the parser rule on each match within each
            line of the card. The text selected is group 1 if it exists, or
            group 0 (the entire match) otherwise. If not provided, use each
            line in its entirety.
        noregex: Any text found after considering yesregex (or its absence)
            is skipped if it matches this regex. """
    def _parse_helper(c):
        """ Returns a pair (number of errors, set of unique errors). """
        results = []
        errors = 0
        uerrors = set()
        for lineno, line in enumerate(c.rules.split('\n')):
            lineno += 1
            if yesregex:
                texts = [
                    m.group(1) if m.groups() else m.group(0)
                    for m in yesregex.finditer(line)
                ]
            else:
                texts = [line]
            if noregex:
                texts = [text for text in texts if not noregex.match(text)]
            for text in texts:
                p, parse_result = _parse(rulename, text, c.name, lineno)
                tree = parse_result.tree
                results.append(tree)
                if p.getNumberOfSyntaxErrors():
                    mcase = _crawl_tree_for_errors(c.name, lineno, text, tree)
                    if mcase:
                        uerrors.add(mcase)
                    errors += 1
        return (c.name, [t.toStringTree() for t in results], errors, uerrors)

    _parse_helper.__name__ = '_parse_{}'.format(name)

    if yesregex:
        pattern = yesregex.pattern
        if noregex:
            ccards = {
                card.get_card(c[0])
                for c in card.search_text(pattern, cards=cards)
                if not noregex.match(c[1])
            }
        else:
            ccards = {
                card.get_card(c[0])
                for c in card.search_text(pattern, cards=cards)
            }
    elif noregex:
        ccards = {
            c
            for c in cards
            if not all(noregex.match(line) for line in c.rules.split('\n'))
        }
    else:
        ccards = set(cards)

    errors = 0
    uerrors = set()
    plog.removeHandler(_stdout)
    # list of (cardname, parsed result trees, number of errors, set of errors)
    results = card.map_multi(_parse_helper, ccards)
    cprop = 'parsed_{}'.format(name)
    for cname, pc, e, u in results:
        setattr(card.get_card(cname), cprop, pc)
        errors += e
        uerrors |= u
    plog.addHandler(_stdout)
    print('{} total errors.'.format(errors))
    if uerrors:
        print('{} unique cases missing.'.format(len(uerrors)))
        plog.debug('Missing cases: ' + '; '.join(sorted(uerrors)))
Ejemplo n.º 4
0
def parse_helper(cards, name, rulename, yesregex=None, noregex=None):
    """ Parse a given subset of text on a given subset of cards.

        This function may override some re flags on the
        provided regex objects.

        cards: An iterable of cards to search for matching text. To save time,
            the provided regexes will be used to pare down this list to just
            those that will actually have text to attempt to parse.
        name: The function will be named _parse_{name} and the results for
            card c will be saved to c.parsed_{name}.
        rulename: The name of the parser rule to run.
        yesregex: If provided, run the parser rule on each match within each
            line of the card. The text selected is group 1 if it exists, or
            group 0 (the entire match) otherwise. If not provided, use each
            line in its entirety.
        noregex: Any text found after considering yesregex (or its absence)
            is skipped if it matches this regex. """
    def _parse_helper(c):
        """ Returns a pair (number of errors, set of unique errors). """
        results = []
        errors = 0
        uerrors = set()
        for lineno, line in enumerate(c.rules.split('\n')):
            lineno += 1
            if yesregex:
                texts = [m.group(1) if m.groups() else m.group(0)
                         for m in yesregex.finditer(line)]
            else:
                texts = [line]
            if noregex:
                texts = [text for text in texts if not noregex.match(text)]
            for text in texts:
                p, parse_result = _parse(rulename, text, c.name, lineno)
                tree = parse_result.tree
                results.append(tree)
                if p.getNumberOfSyntaxErrors():
                    mcase = _crawl_tree_for_errors(c.name, lineno, text, tree)
                    if mcase:
                        uerrors.add(mcase)
                    errors += 1
        return (c.name, [t.toStringTree() for t in results], errors, uerrors)
    _parse_helper.__name__ = '_parse_{}'.format(name)

    if yesregex:
        pattern = yesregex.pattern
        if noregex:
            ccards = {card.get_card(c[0])
                      for c in card.search_text(pattern, cards=cards)
                      if not noregex.match(c[1])}
        else:
            ccards = {card.get_card(c[0])
                      for c in card.search_text(pattern, cards=cards)}
    elif noregex:
        ccards = {c for c in cards
                  if not all(noregex.match(line)
                             for line in c.rules.split('\n'))}
    else:
        ccards = set(cards)

    errors = 0
    uerrors = set()
    plog.removeHandler(_stdout)
    # list of (cardname, parsed result trees, number of errors, set of errors)
    results = card.map_multi(_parse_helper, ccards)
    cprop = 'parsed_{}'.format(name)
    for cname, pc, e, u in results:
        setattr(card.get_card(cname), cprop, pc)
        errors += e
        uerrors |= u
    plog.addHandler(_stdout)
    print('{} total errors.'.format(errors))
    if uerrors:
        print('{} unique cases missing.'.format(len(uerrors)))
        plog.debug('Missing cases: ' + '; '.join(sorted(uerrors)))