Home | History | Annotate | Download | only in ply
      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 
     75