home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / lib2to3 / pgen2 / driver.py < prev    next >
Encoding:
Python Source  |  2009-04-18  |  4.7 KB  |  147 lines

  1. # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
  2. # Licensed to PSF under a Contributor Agreement.
  3.  
  4. # Modifications:
  5. # Copyright 2006 Google, Inc. All Rights Reserved.
  6. # Licensed to PSF under a Contributor Agreement.
  7.  
  8. """Parser driver.
  9.  
  10. This provides a high-level interface to parse a file into a syntax tree.
  11.  
  12. """
  13.  
  14. __author__ = "Guido van Rossum <guido@python.org>"
  15.  
  16. __all__ = ["Driver", "load_grammar"]
  17.  
  18. # Python imports
  19. import os
  20. import logging
  21. import sys
  22.  
  23. # Pgen imports
  24. from . import grammar, parse, token, tokenize, pgen
  25.  
  26.  
  27. class Driver(object):
  28.  
  29.     def __init__(self, grammar, convert=None, logger=None):
  30.         self.grammar = grammar
  31.         if logger is None:
  32.             logger = logging.getLogger()
  33.         self.logger = logger
  34.         self.convert = convert
  35.  
  36.     def parse_tokens(self, tokens, debug=False):
  37.         """Parse a series of tokens and return the syntax tree."""
  38.         # XXX Move the prefix computation into a wrapper around tokenize.
  39.         p = parse.Parser(self.grammar, self.convert)
  40.         p.setup()
  41.         lineno = 1
  42.         column = 0
  43.         type = value = start = end = line_text = None
  44.         prefix = ""
  45.         for quintuple in tokens:
  46.             type, value, start, end, line_text = quintuple
  47.             if start != (lineno, column):
  48.                 assert (lineno, column) <= start, ((lineno, column), start)
  49.                 s_lineno, s_column = start
  50.                 if lineno < s_lineno:
  51.                     prefix += "\n" * (s_lineno - lineno)
  52.                     lineno = s_lineno
  53.                     column = 0
  54.                 if column < s_column:
  55.                     prefix += line_text[column:s_column]
  56.                     column = s_column
  57.             if type in (tokenize.COMMENT, tokenize.NL):
  58.                 prefix += value
  59.                 lineno, column = end
  60.                 if value.endswith("\n"):
  61.                     lineno += 1
  62.                     column = 0
  63.                 continue
  64.             if type == token.OP:
  65.                 type = grammar.opmap[value]
  66.             if debug:
  67.                 self.logger.debug("%s %r (prefix=%r)",
  68.                                   token.tok_name[type], value, prefix)
  69.             if p.addtoken(type, value, (prefix, start)):
  70.                 if debug:
  71.                     self.logger.debug("Stop.")
  72.                 break
  73.             prefix = ""
  74.             lineno, column = end
  75.             if value.endswith("\n"):
  76.                 lineno += 1
  77.                 column = 0
  78.         else:
  79.             # We never broke out -- EOF is too soon (how can this happen???)
  80.             raise parse.ParseError("incomplete input",
  81.                                    type, value, (prefix, start))
  82.         return p.rootnode
  83.  
  84.     def parse_stream_raw(self, stream, debug=False):
  85.         """Parse a stream and return the syntax tree."""
  86.         tokens = tokenize.generate_tokens(stream.readline)
  87.         return self.parse_tokens(tokens, debug)
  88.  
  89.     def parse_stream(self, stream, debug=False):
  90.         """Parse a stream and return the syntax tree."""
  91.         return self.parse_stream_raw(stream, debug)
  92.  
  93.     def parse_file(self, filename, debug=False):
  94.         """Parse a file and return the syntax tree."""
  95.         stream = open(filename)
  96.         try:
  97.             return self.parse_stream(stream, debug)
  98.         finally:
  99.             stream.close()
  100.  
  101.     def parse_string(self, text, debug=False):
  102.         """Parse a string and return the syntax tree."""
  103.         tokens = tokenize.generate_tokens(generate_lines(text).next)
  104.         return self.parse_tokens(tokens, debug)
  105.  
  106.  
  107. def generate_lines(text):
  108.     """Generator that behaves like readline without using StringIO."""
  109.     for line in text.splitlines(True):
  110.         yield line
  111.     while True:
  112.         yield ""
  113.  
  114.  
  115. def load_grammar(gt="Grammar.txt", gp=None,
  116.                  save=True, force=False, logger=None):
  117.     """Load the grammar (maybe from a pickle)."""
  118.     if logger is None:
  119.         logger = logging.getLogger()
  120.     if gp is None:
  121.         head, tail = os.path.splitext(gt)
  122.         if tail == ".txt":
  123.             tail = ""
  124.         gp = head + tail + ".".join(map(str, sys.version_info)) + ".pickle"
  125.     if force or not _newer(gp, gt):
  126.         logger.info("Generating grammar tables from %s", gt)
  127.         g = pgen.generate_grammar(gt)
  128.         if save:
  129.             logger.info("Writing grammar tables to %s", gp)
  130.             try:
  131.                 g.dump(gp)
  132.             except IOError, e:
  133.                 logger.info("Writing failed:"+str(e))
  134.     else:
  135.         g = grammar.Grammar()
  136.         g.load(gp)
  137.     return g
  138.  
  139.  
  140. def _newer(a, b):
  141.     """Inquire whether file a was written since file b."""
  142.     if not os.path.exists(a):
  143.         return False
  144.     if not os.path.exists(b):
  145.         return True
  146.     return os.path.getmtime(a) >= os.path.getmtime(b)
  147.