7267
|
1 # ply: ygen.py
|
|
2 #
|
|
3 # This is a support program that auto-generates different versions of the YACC parsing
|
|
4 # function with different features removed for the purposes of performance.
|
|
5 #
|
|
6 # Users should edit the method LParser.parsedebug() in yacc.py. The source code
|
|
7 # for that method is then used to create the other methods. See the comments in
|
|
8 # yacc.py for further details.
|
|
9
|
|
10 import os.path
|
|
11 import shutil
|
|
12
|
|
13 def get_source_range(lines, tag):
|
|
14 srclines = enumerate(lines)
|
|
15 start_tag = '#--! %s-start' % tag
|
|
16 end_tag = '#--! %s-end' % tag
|
|
17
|
|
18 for start_index, line in srclines:
|
|
19 if line.strip().startswith(start_tag):
|
|
20 break
|
|
21
|
|
22 for end_index, line in srclines:
|
|
23 if line.strip().endswith(end_tag):
|
|
24 break
|
|
25
|
|
26 return (start_index + 1, end_index)
|
|
27
|
|
28 def filter_section(lines, tag):
|
|
29 filtered_lines = []
|
|
30 include = True
|
|
31 tag_text = '#--! %s' % tag
|
|
32 for line in lines:
|
|
33 if line.strip().startswith(tag_text):
|
|
34 include = not include
|
|
35 elif include:
|
|
36 filtered_lines.append(line)
|
|
37 return filtered_lines
|
|
38
|
|
39 def main():
|
|
40 dirname = os.path.dirname(__file__)
|
|
41 shutil.copy2(os.path.join(dirname, 'yacc.py'), os.path.join(dirname, 'yacc.py.bak'))
|
|
42 with open(os.path.join(dirname, 'yacc.py'), 'r') as f:
|
|
43 lines = f.readlines()
|
|
44
|
|
45 parse_start, parse_end = get_source_range(lines, 'parsedebug')
|
|
46 parseopt_start, parseopt_end = get_source_range(lines, 'parseopt')
|
|
47 parseopt_notrack_start, parseopt_notrack_end = get_source_range(lines, 'parseopt-notrack')
|
|
48
|
|
49 # Get the original source
|
|
50 orig_lines = lines[parse_start:parse_end]
|
|
51
|
|
52 # Filter the DEBUG sections out
|
|
53 parseopt_lines = filter_section(orig_lines, 'DEBUG')
|
|
54
|
|
55 # Filter the TRACKING sections out
|
|
56 parseopt_notrack_lines = filter_section(parseopt_lines, 'TRACKING')
|
|
57
|
|
58 # Replace the parser source sections with updated versions
|
|
59 lines[parseopt_notrack_start:parseopt_notrack_end] = parseopt_notrack_lines
|
|
60 lines[parseopt_start:parseopt_end] = parseopt_lines
|
|
61
|
|
62 lines = [line.rstrip()+'\n' for line in lines]
|
|
63 with open(os.path.join(dirname, 'yacc.py'), 'w') as f:
|
|
64 f.writelines(lines)
|
|
65
|
|
66 print('Updated yacc.py')
|
|
67
|
|
68 if __name__ == '__main__':
|
|
69 main()
|
|
70
|
|
71
|
|
72
|
|
73
|
|
74
|