]> git.lizzy.rs Git - rust.git/blob - src/grammar/testparser.py
4b5a7fb9e10b5c4ce4f6d6f52932787194713d5d
[rust.git] / src / grammar / testparser.py
1 #!/usr/bin/env python
2
3 # ignore-tidy-linelength
4
5 import sys
6
7 import os
8 import subprocess
9 import argparse
10
11 # usage: testparser.py [-h] [-p PARSER [PARSER ...]] -s SOURCE_DIR
12
13 # Parsers should read from stdin and return exit status 0 for a
14 # successful parse, and nonzero for an unsuccessful parse
15
16 parser = argparse.ArgumentParser()
17 parser.add_argument('-p', '--parser', nargs='+')
18 parser.add_argument('-s', '--source-dir', nargs=1, required=True)
19 args = parser.parse_args(sys.argv[1:])
20
21 total = 0
22 ok = {}
23 bad = {}
24 for parser in args.parser:
25     ok[parser] = 0
26     bad[parser] = []
27 devnull = open(os.devnull, 'w')
28 print("\n")
29
30 for base, dirs, files in os.walk(args.source_dir[0]):
31     for f in filter(lambda p: p.endswith('.rs'), files):
32         p = os.path.join(base, f)
33         parse_fail = 'parse-fail' in p
34         if sys.version_info.major == 3:
35             lines = open(p, encoding='utf-8').readlines()
36         else:
37             lines = open(p).readlines()
38         if any('ignore-test' in line or 'ignore-lexer-test' in line for line in lines):
39             continue
40         total += 1
41         for parser in args.parser:
42             if subprocess.call(parser, stdin=open(p), stderr=subprocess.STDOUT, stdout=devnull) == 0:
43                 if parse_fail:
44                     bad[parser].append(p)
45                 else:
46                     ok[parser] += 1
47             else:
48                 if parse_fail:
49                     ok[parser] += 1
50                 else:
51                     bad[parser].append(p)
52         parser_stats = ', '.join(['{}: {}'.format(parser, ok[parser]) for parser in args.parser])
53         sys.stdout.write("\033[K\r total: {}, {}, scanned {}"
54                          .format(total, os.path.relpath(parser_stats), os.path.relpath(p)))
55
56 devnull.close()
57
58 print("\n")
59
60 for parser in args.parser:
61     filename = os.path.basename(parser) + '.bad'
62     print("writing {} files that did not yield the correct result with {} to {}".format(len(bad[parser]), parser, filename))
63     with open(filename, "w") as f:
64         for p in bad[parser]:
65             f.write(p)
66             f.write("\n")