From 4710c53dcad1ebf3755f3efb9e80ac24bd72a9b2 Mon Sep 17 00:00:00 2001 From: darylm503 Date: Mon, 16 Apr 2012 22:12:42 +0000 Subject: AppPkg/Applications/Python: Add Python 2.7.2 sources since the release of Python 2.7.3 made them unavailable from the python.org web site. These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Python/Python-2.7.2/Tools/compiler/astgen.py | 294 +++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 AppPkg/Applications/Python/Python-2.7.2/Tools/compiler/astgen.py (limited to 'AppPkg/Applications/Python/Python-2.7.2/Tools/compiler/astgen.py') diff --git a/AppPkg/Applications/Python/Python-2.7.2/Tools/compiler/astgen.py b/AppPkg/Applications/Python/Python-2.7.2/Tools/compiler/astgen.py new file mode 100644 index 0000000000..51f29b71fa --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.2/Tools/compiler/astgen.py @@ -0,0 +1,294 @@ +"""Generate ast module from specification + +This script generates the ast module from a simple specification, +which makes it easy to accomodate changes in the grammar. This +approach would be quite reasonable if the grammar changed often. +Instead, it is rather complex to generate the appropriate code. And +the Node interface has changed more often than the grammar. +""" + +import fileinput +import re +import sys +from StringIO import StringIO + +SPEC = "ast.txt" +COMMA = ", " + +def load_boilerplate(file): + f = open(file) + buf = f.read() + f.close() + i = buf.find('### ''PROLOGUE') + j = buf.find('### ''EPILOGUE') + pro = buf[i+12:j].strip() + epi = buf[j+12:].strip() + return pro, epi + +def strip_default(arg): + """Return the argname from an 'arg = default' string""" + i = arg.find('=') + if i == -1: + return arg + t = arg[:i].strip() + return t + +P_NODE = 1 +P_OTHER = 2 +P_NESTED = 3 +P_NONE = 4 + +class NodeInfo: + """Each instance describes a specific AST node""" + def __init__(self, name, args): + self.name = name + self.args = args.strip() + self.argnames = self.get_argnames() + self.argprops = self.get_argprops() + self.nargs = len(self.argnames) + self.init = [] + + def get_argnames(self): + if '(' in self.args: + i = self.args.find('(') + j = self.args.rfind(')') + args = self.args[i+1:j] + else: + args = self.args + return [strip_default(arg.strip()) + for arg in args.split(',') if arg] + + def get_argprops(self): + """Each argument can have a property like '*' or '!' + + XXX This method modifies the argnames in place! + """ + d = {} + hardest_arg = P_NODE + for i in range(len(self.argnames)): + arg = self.argnames[i] + if arg.endswith('*'): + arg = self.argnames[i] = arg[:-1] + d[arg] = P_OTHER + hardest_arg = max(hardest_arg, P_OTHER) + elif arg.endswith('!'): + arg = self.argnames[i] = arg[:-1] + d[arg] = P_NESTED + hardest_arg = max(hardest_arg, P_NESTED) + elif arg.endswith('&'): + arg = self.argnames[i] = arg[:-1] + d[arg] = P_NONE + hardest_arg = max(hardest_arg, P_NONE) + else: + d[arg] = P_NODE + self.hardest_arg = hardest_arg + + if hardest_arg > P_NODE: + self.args = self.args.replace('*', '') + self.args = self.args.replace('!', '') + self.args = self.args.replace('&', '') + + return d + + def gen_source(self): + buf = StringIO() + print >> buf, "class %s(Node):" % self.name + self._gen_init(buf) + print >> buf + self._gen_getChildren(buf) + print >> buf + self._gen_getChildNodes(buf) + print >> buf + self._gen_repr(buf) + buf.seek(0, 0) + return buf.read() + + def _gen_init(self, buf): + if self.args: + argtuple = '(' in self.args + args = self.args if not argtuple else ''.join(self.argnames) + print >> buf, " def __init__(self, %s, lineno=None):" % args + else: + print >> buf, " def __init__(self, lineno=None):" + if self.argnames: + if argtuple: + for idx, name in enumerate(self.argnames): + print >> buf, " self.%s = %s[%s]" % (name, args, idx) + else: + for name in self.argnames: + print >> buf, " self.%s = %s" % (name, name) + print >> buf, " self.lineno = lineno" + # Copy the lines in self.init, indented four spaces. The rstrip() + # business is to get rid of the four spaces if line happens to be + # empty, so that reindent.py is happy with the output. + for line in self.init: + print >> buf, (" " + line).rstrip() + + def _gen_getChildren(self, buf): + print >> buf, " def getChildren(self):" + if len(self.argnames) == 0: + print >> buf, " return ()" + else: + if self.hardest_arg < P_NESTED: + clist = COMMA.join(["self.%s" % c + for c in self.argnames]) + if self.nargs == 1: + print >> buf, " return %s," % clist + else: + print >> buf, " return %s" % clist + else: + if len(self.argnames) == 1: + print >> buf, " return tuple(flatten(self.%s))" % self.argnames[0] + else: + print >> buf, " children = []" + template = " children.%s(%sself.%s%s)" + for name in self.argnames: + if self.argprops[name] == P_NESTED: + print >> buf, template % ("extend", "flatten(", + name, ")") + else: + print >> buf, template % ("append", "", name, "") + print >> buf, " return tuple(children)" + + def _gen_getChildNodes(self, buf): + print >> buf, " def getChildNodes(self):" + if len(self.argnames) == 0: + print >> buf, " return ()" + else: + if self.hardest_arg < P_NESTED: + clist = ["self.%s" % c + for c in self.argnames + if self.argprops[c] == P_NODE] + if len(clist) == 0: + print >> buf, " return ()" + elif len(clist) == 1: + print >> buf, " return %s," % clist[0] + else: + print >> buf, " return %s" % COMMA.join(clist) + else: + print >> buf, " nodelist = []" + template = " nodelist.%s(%sself.%s%s)" + for name in self.argnames: + if self.argprops[name] == P_NONE: + tmp = (" if self.%s is not None:\n" + " nodelist.append(self.%s)") + print >> buf, tmp % (name, name) + elif self.argprops[name] == P_NESTED: + print >> buf, template % ("extend", "flatten_nodes(", + name, ")") + elif self.argprops[name] == P_NODE: + print >> buf, template % ("append", "", name, "") + print >> buf, " return tuple(nodelist)" + + def _gen_repr(self, buf): + print >> buf, " def __repr__(self):" + if self.argnames: + fmt = COMMA.join(["%s"] * self.nargs) + if '(' in self.args: + fmt = '(%s)' % fmt + vals = ["repr(self.%s)" % name for name in self.argnames] + vals = COMMA.join(vals) + if self.nargs == 1: + vals = vals + "," + print >> buf, ' return "%s(%s)" %% (%s)' % \ + (self.name, fmt, vals) + else: + print >> buf, ' return "%s()"' % self.name + +rx_init = re.compile('init\((.*)\):') + +def parse_spec(file): + classes = {} + cur = None + for line in fileinput.input(file): + if line.strip().startswith('#'): + continue + mo = rx_init.search(line) + if mo is None: + if cur is None: + # a normal entry + try: + name, args = line.split(':') + except ValueError: + continue + classes[name] = NodeInfo(name, args) + cur = None + else: + # some code for the __init__ method + cur.init.append(line) + else: + # some extra code for a Node's __init__ method + name = mo.group(1) + cur = classes[name] + return sorted(classes.values(), key=lambda n: n.name) + +def main(): + prologue, epilogue = load_boilerplate(sys.argv[-1]) + print prologue + print + classes = parse_spec(SPEC) + for info in classes: + print info.gen_source() + print epilogue + +if __name__ == "__main__": + main() + sys.exit(0) + +### PROLOGUE +"""Python abstract syntax node definitions + +This file is automatically generated by Tools/compiler/astgen.py +""" +from consts import CO_VARARGS, CO_VARKEYWORDS + +def flatten(seq): + l = [] + for elt in seq: + t = type(elt) + if t is tuple or t is list: + for elt2 in flatten(elt): + l.append(elt2) + else: + l.append(elt) + return l + +def flatten_nodes(seq): + return [n for n in flatten(seq) if isinstance(n, Node)] + +nodes = {} + +class Node: + """Abstract base class for ast nodes.""" + def getChildren(self): + pass # implemented by subclasses + def __iter__(self): + for n in self.getChildren(): + yield n + def asList(self): # for backwards compatibility + return self.getChildren() + def getChildNodes(self): + pass # implemented by subclasses + +class EmptyNode(Node): + pass + +class Expression(Node): + # Expression is an artificial node class to support "eval" + nodes["expression"] = "Expression" + def __init__(self, node): + self.node = node + + def getChildren(self): + return self.node, + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Expression(%s)" % (repr(self.node)) + +### EPILOGUE +for name, obj in globals().items(): + if isinstance(obj, type) and issubclass(obj, Node): + nodes[name.lower()] = obj -- cgit v1.2.3