ygen.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. import os.path
  10. import shutil
  11. def get_source_range(lines, tag):
  12. srclines = enumerate(lines)
  13. start_tag = '#--! %s-start' % tag
  14. end_tag = '#--! %s-end' % tag
  15. for start_index, line in srclines:
  16. if line.strip().startswith(start_tag):
  17. break
  18. for end_index, line in srclines:
  19. if line.strip().endswith(end_tag):
  20. break
  21. return (start_index + 1, end_index)
  22. def filter_section(lines, tag):
  23. filtered_lines = []
  24. include = True
  25. tag_text = '#--! %s' % tag
  26. for line in lines:
  27. if line.strip().startswith(tag_text):
  28. include = not include
  29. elif include:
  30. filtered_lines.append(line)
  31. return filtered_lines
  32. def main():
  33. dirname = os.path.dirname(__file__)
  34. shutil.copy2(os.path.join(dirname, 'yacc.py'), os.path.join(dirname, 'yacc.py.bak'))
  35. with open(os.path.join(dirname, 'yacc.py'), 'r') as f:
  36. lines = f.readlines()
  37. parse_start, parse_end = get_source_range(lines, 'parsedebug')
  38. parseopt_start, parseopt_end = get_source_range(lines, 'parseopt')
  39. parseopt_notrack_start, parseopt_notrack_end = get_source_range(lines, 'parseopt-notrack')
  40. # Get the original source
  41. orig_lines = lines[parse_start:parse_end]
  42. # Filter the DEBUG sections out
  43. parseopt_lines = filter_section(orig_lines, 'DEBUG')
  44. # Filter the TRACKING sections out
  45. parseopt_notrack_lines = filter_section(parseopt_lines, 'TRACKING')
  46. # Replace the parser source sections with updated versions
  47. lines[parseopt_notrack_start:parseopt_notrack_end] = parseopt_notrack_lines
  48. lines[parseopt_start:parseopt_end] = parseopt_lines
  49. lines = [line.rstrip()+'\n' for line in lines]
  50. with open(os.path.join(dirname, 'yacc.py'), 'w') as f:
  51. f.writelines(lines)
  52. print('Updated yacc.py')
  53. if __name__ == '__main__':
  54. main()