]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Python/ast.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 1/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Python / ast.c
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Python/ast.c b/AppPkg/Applications/Python/Python-2.7.10/Python/ast.c
new file mode 100644 (file)
index 0000000..2ec1514
--- /dev/null
@@ -0,0 +1,3587 @@
+/*\r
+ * This file includes functions to transform a concrete syntax tree (CST) to\r
+ * an abstract syntax tree (AST).  The main function is PyAST_FromNode().\r
+ *\r
+ */\r
+#include "Python.h"\r
+#include "Python-ast.h"\r
+#include "grammar.h"\r
+#include "node.h"\r
+#include "pyarena.h"\r
+#include "ast.h"\r
+#include "token.h"\r
+#include "parsetok.h"\r
+#include "graminit.h"\r
+\r
+#include <assert.h>\r
+\r
+/* Data structure used internally */\r
+struct compiling {\r
+    char *c_encoding; /* source encoding */\r
+    int c_future_unicode; /* __future__ unicode literals flag */\r
+    PyArena *c_arena; /* arena for allocating memeory */\r
+    const char *c_filename; /* filename */\r
+};\r
+\r
+static asdl_seq *seq_for_testlist(struct compiling *, const node *);\r
+static expr_ty ast_for_expr(struct compiling *, const node *);\r
+static stmt_ty ast_for_stmt(struct compiling *, const node *);\r
+static asdl_seq *ast_for_suite(struct compiling *, const node *);\r
+static asdl_seq *ast_for_exprlist(struct compiling *, const node *,\r
+                                  expr_context_ty);\r
+static expr_ty ast_for_testlist(struct compiling *, const node *);\r
+static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *);\r
+static expr_ty ast_for_testlist_comp(struct compiling *, const node *);\r
+\r
+/* Note different signature for ast_for_call */\r
+static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);\r
+\r
+static PyObject *parsenumber(struct compiling *, const char *);\r
+static PyObject *parsestr(struct compiling *, const node *n, const char *);\r
+static PyObject *parsestrplus(struct compiling *, const node *n);\r
+\r
+#ifndef LINENO\r
+#define LINENO(n)       ((n)->n_lineno)\r
+#endif\r
+\r
+#define COMP_GENEXP 0\r
+#define COMP_SETCOMP  1\r
+\r
+static identifier\r
+new_identifier(const char* n, PyArena *arena) {\r
+    PyObject* id = PyString_InternFromString(n);\r
+    if (id != NULL)\r
+        PyArena_AddPyObject(arena, id);\r
+    return id;\r
+}\r
+\r
+#define NEW_IDENTIFIER(n) new_identifier(STR(n), c->c_arena)\r
+\r
+/* This routine provides an invalid object for the syntax error.\r
+   The outermost routine must unpack this error and create the\r
+   proper object.  We do this so that we don't have to pass\r
+   the filename to everything function.\r
+\r
+   XXX Maybe we should just pass the filename...\r
+*/\r
+\r
+static int\r
+ast_error(const node *n, const char *errstr)\r
+{\r
+    PyObject *u = Py_BuildValue("zi", errstr, LINENO(n));\r
+    if (!u)\r
+        return 0;\r
+    PyErr_SetObject(PyExc_SyntaxError, u);\r
+    Py_DECREF(u);\r
+    return 0;\r
+}\r
+\r
+static void\r
+ast_error_finish(const char *filename)\r
+{\r
+    PyObject *type, *value, *tback, *errstr, *loc, *tmp;\r
+    long lineno;\r
+\r
+    assert(PyErr_Occurred());\r
+    if (!PyErr_ExceptionMatches(PyExc_SyntaxError))\r
+        return;\r
+\r
+    PyErr_Fetch(&type, &value, &tback);\r
+    errstr = PyTuple_GetItem(value, 0);\r
+    if (!errstr)\r
+        return;\r
+    Py_INCREF(errstr);\r
+    lineno = PyInt_AsLong(PyTuple_GetItem(value, 1));\r
+    if (lineno == -1) {\r
+        Py_DECREF(errstr);\r
+        return;\r
+    }\r
+    Py_DECREF(value);\r
+\r
+    loc = PyErr_ProgramText(filename, lineno);\r
+    if (!loc) {\r
+        Py_INCREF(Py_None);\r
+        loc = Py_None;\r
+    }\r
+    tmp = Py_BuildValue("(zlOO)", filename, lineno, Py_None, loc);\r
+    Py_DECREF(loc);\r
+    if (!tmp) {\r
+        Py_DECREF(errstr);\r
+        return;\r
+    }\r
+    value = PyTuple_Pack(2, errstr, tmp);\r
+    Py_DECREF(errstr);\r
+    Py_DECREF(tmp);\r
+    if (!value)\r
+        return;\r
+    PyErr_Restore(type, value, tback);\r
+}\r
+\r
+static int\r
+ast_warn(struct compiling *c, const node *n, char *msg)\r
+{\r
+    if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, LINENO(n),\r
+                           NULL, NULL) < 0) {\r
+        /* if -Werr, change it to a SyntaxError */\r
+        if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SyntaxWarning))\r
+            ast_error(n, msg);\r
+        return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+static int\r
+forbidden_check(struct compiling *c, const node *n, const char *x)\r
+{\r
+    if (!strcmp(x, "None"))\r
+        return ast_error(n, "cannot assign to None");\r
+    if (!strcmp(x, "__debug__"))\r
+        return ast_error(n, "cannot assign to __debug__");\r
+    if (Py_Py3kWarningFlag) {\r
+        if (!(strcmp(x, "True") && strcmp(x, "False")) &&\r
+            !ast_warn(c, n, "assignment to True or False is forbidden in 3.x"))\r
+            return 0;\r
+        if (!strcmp(x, "nonlocal") &&\r
+            !ast_warn(c, n, "nonlocal is a keyword in 3.x"))\r
+            return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+/* num_stmts() returns number of contained statements.\r
+\r
+   Use this routine to determine how big a sequence is needed for\r
+   the statements in a parse tree.  Its raison d'etre is this bit of\r
+   grammar:\r
+\r
+   stmt: simple_stmt | compound_stmt\r
+   simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE\r
+\r
+   A simple_stmt can contain multiple small_stmt elements joined\r
+   by semicolons.  If the arg is a simple_stmt, the number of\r
+   small_stmt elements is returned.\r
+*/\r
+\r
+static int\r
+num_stmts(const node *n)\r
+{\r
+    int i, l;\r
+    node *ch;\r
+\r
+    switch (TYPE(n)) {\r
+        case single_input:\r
+            if (TYPE(CHILD(n, 0)) == NEWLINE)\r
+                return 0;\r
+            else\r
+                return num_stmts(CHILD(n, 0));\r
+        case file_input:\r
+            l = 0;\r
+            for (i = 0; i < NCH(n); i++) {\r
+                ch = CHILD(n, i);\r
+                if (TYPE(ch) == stmt)\r
+                    l += num_stmts(ch);\r
+            }\r
+            return l;\r
+        case stmt:\r
+            return num_stmts(CHILD(n, 0));\r
+        case compound_stmt:\r
+            return 1;\r
+        case simple_stmt:\r
+            return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */\r
+        case suite:\r
+            if (NCH(n) == 1)\r
+                return num_stmts(CHILD(n, 0));\r
+            else {\r
+                l = 0;\r
+                for (i = 2; i < (NCH(n) - 1); i++)\r
+                    l += num_stmts(CHILD(n, i));\r
+                return l;\r
+            }\r
+        default: {\r
+            char buf[128];\r
+\r
+            sprintf(buf, "Non-statement found: %d %d",\r
+                    TYPE(n), NCH(n));\r
+            Py_FatalError(buf);\r
+        }\r
+    }\r
+    assert(0);\r
+    return 0;\r
+}\r
+\r
+/* Transform the CST rooted at node * to the appropriate AST\r
+*/\r
+\r
+mod_ty\r
+PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,\r
+               PyArena *arena)\r
+{\r
+    int i, j, k, num;\r
+    asdl_seq *stmts = NULL;\r
+    stmt_ty s;\r
+    node *ch;\r
+    struct compiling c;\r
+\r
+    if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {\r
+        c.c_encoding = "utf-8";\r
+        if (TYPE(n) == encoding_decl) {\r
+            ast_error(n, "encoding declaration in Unicode string");\r
+            goto error;\r
+        }\r
+    } else if (TYPE(n) == encoding_decl) {\r
+        c.c_encoding = STR(n);\r
+        n = CHILD(n, 0);\r
+    } else {\r
+        c.c_encoding = NULL;\r
+    }\r
+    c.c_future_unicode = flags && flags->cf_flags & CO_FUTURE_UNICODE_LITERALS;\r
+    c.c_arena = arena;\r
+    c.c_filename = filename;\r
+\r
+    k = 0;\r
+    switch (TYPE(n)) {\r
+        case file_input:\r
+            stmts = asdl_seq_new(num_stmts(n), arena);\r
+            if (!stmts)\r
+                return NULL;\r
+            for (i = 0; i < NCH(n) - 1; i++) {\r
+                ch = CHILD(n, i);\r
+                if (TYPE(ch) == NEWLINE)\r
+                    continue;\r
+                REQ(ch, stmt);\r
+                num = num_stmts(ch);\r
+                if (num == 1) {\r
+                    s = ast_for_stmt(&c, ch);\r
+                    if (!s)\r
+                        goto error;\r
+                    asdl_seq_SET(stmts, k++, s);\r
+                }\r
+                else {\r
+                    ch = CHILD(ch, 0);\r
+                    REQ(ch, simple_stmt);\r
+                    for (j = 0; j < num; j++) {\r
+                        s = ast_for_stmt(&c, CHILD(ch, j * 2));\r
+                        if (!s)\r
+                            goto error;\r
+                        asdl_seq_SET(stmts, k++, s);\r
+                    }\r
+                }\r
+            }\r
+            return Module(stmts, arena);\r
+        case eval_input: {\r
+            expr_ty testlist_ast;\r
+\r
+            /* XXX Why not comp_for here? */\r
+            testlist_ast = ast_for_testlist(&c, CHILD(n, 0));\r
+            if (!testlist_ast)\r
+                goto error;\r
+            return Expression(testlist_ast, arena);\r
+        }\r
+        case single_input:\r
+            if (TYPE(CHILD(n, 0)) == NEWLINE) {\r
+                stmts = asdl_seq_new(1, arena);\r
+                if (!stmts)\r
+                    goto error;\r
+                asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset,\r
+                                            arena));\r
+                if (!asdl_seq_GET(stmts, 0))\r
+                    goto error;\r
+                return Interactive(stmts, arena);\r
+            }\r
+            else {\r
+                n = CHILD(n, 0);\r
+                num = num_stmts(n);\r
+                stmts = asdl_seq_new(num, arena);\r
+                if (!stmts)\r
+                    goto error;\r
+                if (num == 1) {\r
+                    s = ast_for_stmt(&c, n);\r
+                    if (!s)\r
+                        goto error;\r
+                    asdl_seq_SET(stmts, 0, s);\r
+                }\r
+                else {\r
+                    /* Only a simple_stmt can contain multiple statements. */\r
+                    REQ(n, simple_stmt);\r
+                    for (i = 0; i < NCH(n); i += 2) {\r
+                        if (TYPE(CHILD(n, i)) == NEWLINE)\r
+                            break;\r
+                        s = ast_for_stmt(&c, CHILD(n, i));\r
+                        if (!s)\r
+                            goto error;\r
+                        asdl_seq_SET(stmts, i / 2, s);\r
+                    }\r
+                }\r
+\r
+                return Interactive(stmts, arena);\r
+            }\r
+        default:\r
+            PyErr_Format(PyExc_SystemError,\r
+                         "invalid node %d for PyAST_FromNode", TYPE(n));\r
+            goto error;\r
+    }\r
+ error:\r
+    ast_error_finish(filename);\r
+    return NULL;\r
+}\r
+\r
+/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)\r
+*/\r
+\r
+static operator_ty\r
+get_operator(const node *n)\r
+{\r
+    switch (TYPE(n)) {\r
+        case VBAR:\r
+            return BitOr;\r
+        case CIRCUMFLEX:\r
+            return BitXor;\r
+        case AMPER:\r
+            return BitAnd;\r
+        case LEFTSHIFT:\r
+            return LShift;\r
+        case RIGHTSHIFT:\r
+            return RShift;\r
+        case PLUS:\r
+            return Add;\r
+        case MINUS:\r
+            return Sub;\r
+        case STAR:\r
+            return Mult;\r
+        case SLASH:\r
+            return Div;\r
+        case DOUBLESLASH:\r
+            return FloorDiv;\r
+        case PERCENT:\r
+            return Mod;\r
+        default:\r
+            return (operator_ty)0;\r
+    }\r
+}\r
+\r
+/* Set the context ctx for expr_ty e, recursively traversing e.\r
+\r
+   Only sets context for expr kinds that "can appear in assignment context"\r
+   (according to ../Parser/Python.asdl).  For other expr kinds, it sets\r
+   an appropriate syntax error and returns false.\r
+*/\r
+\r
+static int\r
+set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)\r
+{\r
+    asdl_seq *s = NULL;\r
+    /* If a particular expression type can't be used for assign / delete,\r
+       set expr_name to its name and an error message will be generated.\r
+    */\r
+    const char* expr_name = NULL;\r
+\r
+    /* The ast defines augmented store and load contexts, but the\r
+       implementation here doesn't actually use them.  The code may be\r
+       a little more complex than necessary as a result.  It also means\r
+       that expressions in an augmented assignment have a Store context.\r
+       Consider restructuring so that augmented assignment uses\r
+       set_context(), too.\r
+    */\r
+    assert(ctx != AugStore && ctx != AugLoad);\r
+\r
+    switch (e->kind) {\r
+        case Attribute_kind:\r
+            if (ctx == Store && !forbidden_check(c, n,\r
+                                PyBytes_AS_STRING(e->v.Attribute.attr)))\r
+                    return 0;\r
+            e->v.Attribute.ctx = ctx;\r
+            break;\r
+        case Subscript_kind:\r
+            e->v.Subscript.ctx = ctx;\r
+            break;\r
+        case Name_kind:\r
+            if (ctx == Store && !forbidden_check(c, n,\r
+                                PyBytes_AS_STRING(e->v.Name.id)))\r
+                    return 0;\r
+            e->v.Name.ctx = ctx;\r
+            break;\r
+        case List_kind:\r
+            e->v.List.ctx = ctx;\r
+            s = e->v.List.elts;\r
+            break;\r
+        case Tuple_kind:\r
+            if (asdl_seq_LEN(e->v.Tuple.elts))  {\r
+                e->v.Tuple.ctx = ctx;\r
+                s = e->v.Tuple.elts;\r
+            }\r
+            else {\r
+                expr_name = "()";\r
+            }\r
+            break;\r
+        case Lambda_kind:\r
+            expr_name = "lambda";\r
+            break;\r
+        case Call_kind:\r
+            expr_name = "function call";\r
+            break;\r
+        case BoolOp_kind:\r
+        case BinOp_kind:\r
+        case UnaryOp_kind:\r
+            expr_name = "operator";\r
+            break;\r
+        case GeneratorExp_kind:\r
+            expr_name = "generator expression";\r
+            break;\r
+        case Yield_kind:\r
+            expr_name = "yield expression";\r
+            break;\r
+        case ListComp_kind:\r
+            expr_name = "list comprehension";\r
+            break;\r
+        case SetComp_kind:\r
+            expr_name = "set comprehension";\r
+            break;\r
+        case DictComp_kind:\r
+            expr_name = "dict comprehension";\r
+            break;\r
+        case Dict_kind:\r
+        case Set_kind:\r
+        case Num_kind:\r
+        case Str_kind:\r
+            expr_name = "literal";\r
+            break;\r
+        case Compare_kind:\r
+            expr_name = "comparison";\r
+            break;\r
+        case Repr_kind:\r
+            expr_name = "repr";\r
+            break;\r
+        case IfExp_kind:\r
+            expr_name = "conditional expression";\r
+            break;\r
+        default:\r
+            PyErr_Format(PyExc_SystemError,\r
+                         "unexpected expression in assignment %d (line %d)",\r
+                         e->kind, e->lineno);\r
+            return 0;\r
+    }\r
+    /* Check for error string set by switch */\r
+    if (expr_name) {\r
+        char buf[300];\r
+        PyOS_snprintf(buf, sizeof(buf),\r
+                      "can't %s %s",\r
+                      ctx == Store ? "assign to" : "delete",\r
+                      expr_name);\r
+        return ast_error(n, buf);\r
+    }\r
+\r
+    /* If the LHS is a list or tuple, we need to set the assignment\r
+       context for all the contained elements.\r
+    */\r
+    if (s) {\r
+        int i;\r
+\r
+        for (i = 0; i < asdl_seq_LEN(s); i++) {\r
+            if (!set_context(c, (expr_ty)asdl_seq_GET(s, i), ctx, n))\r
+                return 0;\r
+        }\r
+    }\r
+    return 1;\r
+}\r
+\r
+static operator_ty\r
+ast_for_augassign(struct compiling *c, const node *n)\r
+{\r
+    REQ(n, augassign);\r
+    n = CHILD(n, 0);\r
+    switch (STR(n)[0]) {\r
+        case '+':\r
+            return Add;\r
+        case '-':\r
+            return Sub;\r
+        case '/':\r
+            if (STR(n)[1] == '/')\r
+                return FloorDiv;\r
+            else\r
+                return Div;\r
+        case '%':\r
+            return Mod;\r
+        case '<':\r
+            return LShift;\r
+        case '>':\r
+            return RShift;\r
+        case '&':\r
+            return BitAnd;\r
+        case '^':\r
+            return BitXor;\r
+        case '|':\r
+            return BitOr;\r
+        case '*':\r
+            if (STR(n)[1] == '*')\r
+                return Pow;\r
+            else\r
+                return Mult;\r
+        default:\r
+            PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n));\r
+            return (operator_ty)0;\r
+    }\r
+}\r
+\r
+static cmpop_ty\r
+ast_for_comp_op(struct compiling *c, const node *n)\r
+{\r
+    /* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'\r
+               |'is' 'not'\r
+    */\r
+    REQ(n, comp_op);\r
+    if (NCH(n) == 1) {\r
+        n = CHILD(n, 0);\r
+        switch (TYPE(n)) {\r
+            case LESS:\r
+                return Lt;\r
+            case GREATER:\r
+                return Gt;\r
+            case EQEQUAL:                       /* == */\r
+                return Eq;\r
+            case LESSEQUAL:\r
+                return LtE;\r
+            case GREATEREQUAL:\r
+                return GtE;\r
+            case NOTEQUAL:\r
+                return NotEq;\r
+            case NAME:\r
+                if (strcmp(STR(n), "in") == 0)\r
+                    return In;\r
+                if (strcmp(STR(n), "is") == 0)\r
+                    return Is;\r
+            default:\r
+                PyErr_Format(PyExc_SystemError, "invalid comp_op: %s",\r
+                             STR(n));\r
+                return (cmpop_ty)0;\r
+        }\r
+    }\r
+    else if (NCH(n) == 2) {\r
+        /* handle "not in" and "is not" */\r
+        switch (TYPE(CHILD(n, 0))) {\r
+            case NAME:\r
+                if (strcmp(STR(CHILD(n, 1)), "in") == 0)\r
+                    return NotIn;\r
+                if (strcmp(STR(CHILD(n, 0)), "is") == 0)\r
+                    return IsNot;\r
+            default:\r
+                PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s",\r
+                             STR(CHILD(n, 0)), STR(CHILD(n, 1)));\r
+                return (cmpop_ty)0;\r
+        }\r
+    }\r
+    PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children",\r
+                 NCH(n));\r
+    return (cmpop_ty)0;\r
+}\r
+\r
+static asdl_seq *\r
+seq_for_testlist(struct compiling *c, const node *n)\r
+{\r
+    /* testlist: test (',' test)* [','] */\r
+    asdl_seq *seq;\r
+    expr_ty expression;\r
+    int i;\r
+    assert(TYPE(n) == testlist ||\r
+           TYPE(n) == listmaker ||\r
+           TYPE(n) == testlist_comp ||\r
+           TYPE(n) == testlist_safe ||\r
+           TYPE(n) == testlist1);\r
+\r
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);\r
+    if (!seq)\r
+        return NULL;\r
+\r
+    for (i = 0; i < NCH(n); i += 2) {\r
+        assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == old_test);\r
+\r
+        expression = ast_for_expr(c, CHILD(n, i));\r
+        if (!expression)\r
+            return NULL;\r
+\r
+        assert(i / 2 < seq->size);\r
+        asdl_seq_SET(seq, i / 2, expression);\r
+    }\r
+    return seq;\r
+}\r
+\r
+static expr_ty\r
+compiler_complex_args(struct compiling *c, const node *n)\r
+{\r
+    int i, len = (NCH(n) + 1) / 2;\r
+    expr_ty result;\r
+    asdl_seq *args = asdl_seq_new(len, c->c_arena);\r
+    if (!args)\r
+        return NULL;\r
+\r
+    /* fpdef: NAME | '(' fplist ')'\r
+       fplist: fpdef (',' fpdef)* [',']\r
+    */\r
+    REQ(n, fplist);\r
+    for (i = 0; i < len; i++) {\r
+        PyObject *arg_id;\r
+        const node *fpdef_node = CHILD(n, 2*i);\r
+        const node *child;\r
+        expr_ty arg;\r
+set_name:\r
+        /* fpdef_node is either a NAME or an fplist */\r
+        child = CHILD(fpdef_node, 0);\r
+        if (TYPE(child) == NAME) {\r
+            if (!forbidden_check(c, n, STR(child)))\r
+                return NULL;\r
+            arg_id = NEW_IDENTIFIER(child);\r
+            if (!arg_id)\r
+                return NULL;\r
+            arg = Name(arg_id, Store, LINENO(child), child->n_col_offset,\r
+                       c->c_arena);\r
+        }\r
+        else {\r
+            assert(TYPE(fpdef_node) == fpdef);\r
+            /* fpdef_node[0] is not a name, so it must be '(', get CHILD[1] */\r
+            child = CHILD(fpdef_node, 1);\r
+            assert(TYPE(child) == fplist);\r
+            /* NCH == 1 means we have (x), we need to elide the extra parens */\r
+            if (NCH(child) == 1) {\r
+                fpdef_node = CHILD(child, 0);\r
+                assert(TYPE(fpdef_node) == fpdef);\r
+                goto set_name;\r
+            }\r
+            arg = compiler_complex_args(c, child);\r
+        }\r
+        asdl_seq_SET(args, i, arg);\r
+    }\r
+\r
+    result = Tuple(args, Store, LINENO(n), n->n_col_offset, c->c_arena);\r
+    if (!set_context(c, result, Store, n))\r
+        return NULL;\r
+    return result;\r
+}\r
+\r
+\r
+/* Create AST for argument list. */\r
+\r
+static arguments_ty\r
+ast_for_arguments(struct compiling *c, const node *n)\r
+{\r
+    /* parameters: '(' [varargslist] ')'\r
+       varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]\r
+            | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']\r
+    */\r
+    int i, j, k, n_args = 0, n_defaults = 0, found_default = 0;\r
+    asdl_seq *args, *defaults;\r
+    identifier vararg = NULL, kwarg = NULL;\r
+    node *ch;\r
+\r
+    if (TYPE(n) == parameters) {\r
+        if (NCH(n) == 2) /* () as argument list */\r
+            return arguments(NULL, NULL, NULL, NULL, c->c_arena);\r
+        n = CHILD(n, 1);\r
+    }\r
+    REQ(n, varargslist);\r
+\r
+    /* first count the number of normal args & defaults */\r
+    for (i = 0; i < NCH(n); i++) {\r
+        ch = CHILD(n, i);\r
+        if (TYPE(ch) == fpdef)\r
+            n_args++;\r
+        if (TYPE(ch) == EQUAL)\r
+            n_defaults++;\r
+    }\r
+    args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);\r
+    if (!args && n_args)\r
+        return NULL;\r
+    defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);\r
+    if (!defaults && n_defaults)\r
+        return NULL;\r
+\r
+    /* fpdef: NAME | '(' fplist ')'\r
+       fplist: fpdef (',' fpdef)* [',']\r
+    */\r
+    i = 0;\r
+    j = 0;  /* index for defaults */\r
+    k = 0;  /* index for args */\r
+    while (i < NCH(n)) {\r
+        ch = CHILD(n, i);\r
+        switch (TYPE(ch)) {\r
+            case fpdef: {\r
+                int complex_args = 0, parenthesized = 0;\r
+            handle_fpdef:\r
+                /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is\r
+                   anything other than EQUAL or a comma? */\r
+                /* XXX Should NCH(n) check be made a separate check? */\r
+                if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {\r
+                    expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));\r
+                    if (!expression)\r
+                        return NULL;\r
+                    assert(defaults != NULL);\r
+                    asdl_seq_SET(defaults, j++, expression);\r
+                    i += 2;\r
+                    found_default = 1;\r
+                }\r
+                else if (found_default) {\r
+                    /* def f((x)=4): pass should raise an error.\r
+                       def f((x, (y))): pass will just incur the tuple unpacking warning. */\r
+                    if (parenthesized && !complex_args) {\r
+                        ast_error(n, "parenthesized arg with default");\r
+                        return NULL;\r
+                    }\r
+                    ast_error(n,\r
+                             "non-default argument follows default argument");\r
+                    return NULL;\r
+                }\r
+                if (NCH(ch) == 3) {\r
+                    ch = CHILD(ch, 1);\r
+                    /* def foo((x)): is not complex, special case. */\r
+                    if (NCH(ch) != 1) {\r
+                        /* We have complex arguments, setup for unpacking. */\r
+                        if (Py_Py3kWarningFlag && !ast_warn(c, ch,\r
+                            "tuple parameter unpacking has been removed in 3.x"))\r
+                            return NULL;\r
+                        complex_args = 1;\r
+                        asdl_seq_SET(args, k++, compiler_complex_args(c, ch));\r
+                        if (!asdl_seq_GET(args, k-1))\r
+                                return NULL;\r
+                    } else {\r
+                        /* def foo((x)): setup for checking NAME below. */\r
+                        /* Loop because there can be many parens and tuple\r
+                           unpacking mixed in. */\r
+                        parenthesized = 1;\r
+                        ch = CHILD(ch, 0);\r
+                        assert(TYPE(ch) == fpdef);\r
+                        goto handle_fpdef;\r
+                    }\r
+                }\r
+                if (TYPE(CHILD(ch, 0)) == NAME) {\r
+                    PyObject *id;\r
+                    expr_ty name;\r
+                    if (!forbidden_check(c, n, STR(CHILD(ch, 0))))\r
+                        return NULL;\r
+                    id = NEW_IDENTIFIER(CHILD(ch, 0));\r
+                    if (!id)\r
+                        return NULL;\r
+                    name = Name(id, Param, LINENO(ch), ch->n_col_offset,\r
+                                c->c_arena);\r
+                    if (!name)\r
+                        return NULL;\r
+                    asdl_seq_SET(args, k++, name);\r
+\r
+                }\r
+                i += 2; /* the name and the comma */\r
+                if (parenthesized && Py_Py3kWarningFlag &&\r
+                    !ast_warn(c, ch, "parenthesized argument names "\r
+                              "are invalid in 3.x"))\r
+                    return NULL;\r
+\r
+                break;\r
+            }\r
+            case STAR:\r
+                if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))\r
+                    return NULL;\r
+                vararg = NEW_IDENTIFIER(CHILD(n, i+1));\r
+                if (!vararg)\r
+                    return NULL;\r
+                i += 3;\r
+                break;\r
+            case DOUBLESTAR:\r
+                if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))\r
+                    return NULL;\r
+                kwarg = NEW_IDENTIFIER(CHILD(n, i+1));\r
+                if (!kwarg)\r
+                    return NULL;\r
+                i += 3;\r
+                break;\r
+            default:\r
+                PyErr_Format(PyExc_SystemError,\r
+                             "unexpected node in varargslist: %d @ %d",\r
+                             TYPE(ch), i);\r
+                return NULL;\r
+        }\r
+    }\r
+\r
+    return arguments(args, vararg, kwarg, defaults, c->c_arena);\r
+}\r
+\r
+static expr_ty\r
+ast_for_dotted_name(struct compiling *c, const node *n)\r
+{\r
+    expr_ty e;\r
+    identifier id;\r
+    int lineno, col_offset;\r
+    int i;\r
+\r
+    REQ(n, dotted_name);\r
+\r
+    lineno = LINENO(n);\r
+    col_offset = n->n_col_offset;\r
+\r
+    id = NEW_IDENTIFIER(CHILD(n, 0));\r
+    if (!id)\r
+        return NULL;\r
+    e = Name(id, Load, lineno, col_offset, c->c_arena);\r
+    if (!e)\r
+        return NULL;\r
+\r
+    for (i = 2; i < NCH(n); i+=2) {\r
+        id = NEW_IDENTIFIER(CHILD(n, i));\r
+        if (!id)\r
+            return NULL;\r
+        e = Attribute(e, id, Load, lineno, col_offset, c->c_arena);\r
+        if (!e)\r
+            return NULL;\r
+    }\r
+\r
+    return e;\r
+}\r
+\r
+static expr_ty\r
+ast_for_decorator(struct compiling *c, const node *n)\r
+{\r
+    /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */\r
+    expr_ty d = NULL;\r
+    expr_ty name_expr;\r
+\r
+    REQ(n, decorator);\r
+    REQ(CHILD(n, 0), AT);\r
+    REQ(RCHILD(n, -1), NEWLINE);\r
+\r
+    name_expr = ast_for_dotted_name(c, CHILD(n, 1));\r
+    if (!name_expr)\r
+        return NULL;\r
+\r
+    if (NCH(n) == 3) { /* No arguments */\r
+        d = name_expr;\r
+        name_expr = NULL;\r
+    }\r
+    else if (NCH(n) == 5) { /* Call with no arguments */\r
+        d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n),\r
+                 n->n_col_offset, c->c_arena);\r
+        if (!d)\r
+            return NULL;\r
+        name_expr = NULL;\r
+    }\r
+    else {\r
+        d = ast_for_call(c, CHILD(n, 3), name_expr);\r
+        if (!d)\r
+            return NULL;\r
+        name_expr = NULL;\r
+    }\r
+\r
+    return d;\r
+}\r
+\r
+static asdl_seq*\r
+ast_for_decorators(struct compiling *c, const node *n)\r
+{\r
+    asdl_seq* decorator_seq;\r
+    expr_ty d;\r
+    int i;\r
+\r
+    REQ(n, decorators);\r
+    decorator_seq = asdl_seq_new(NCH(n), c->c_arena);\r
+    if (!decorator_seq)\r
+        return NULL;\r
+\r
+    for (i = 0; i < NCH(n); i++) {\r
+        d = ast_for_decorator(c, CHILD(n, i));\r
+        if (!d)\r
+            return NULL;\r
+        asdl_seq_SET(decorator_seq, i, d);\r
+    }\r
+    return decorator_seq;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)\r
+{\r
+    /* funcdef: 'def' NAME parameters ':' suite */\r
+    identifier name;\r
+    arguments_ty args;\r
+    asdl_seq *body;\r
+    int name_i = 1;\r
+\r
+    REQ(n, funcdef);\r
+\r
+    name = NEW_IDENTIFIER(CHILD(n, name_i));\r
+    if (!name)\r
+        return NULL;\r
+    else if (!forbidden_check(c, CHILD(n, name_i), STR(CHILD(n, name_i))))\r
+        return NULL;\r
+    args = ast_for_arguments(c, CHILD(n, name_i + 1));\r
+    if (!args)\r
+        return NULL;\r
+    body = ast_for_suite(c, CHILD(n, name_i + 3));\r
+    if (!body)\r
+        return NULL;\r
+\r
+    return FunctionDef(name, args, body, decorator_seq, LINENO(n),\r
+                       n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_decorated(struct compiling *c, const node *n)\r
+{\r
+    /* decorated: decorators (classdef | funcdef) */\r
+    stmt_ty thing = NULL;\r
+    asdl_seq *decorator_seq = NULL;\r
+\r
+    REQ(n, decorated);\r
+\r
+    decorator_seq = ast_for_decorators(c, CHILD(n, 0));\r
+    if (!decorator_seq)\r
+      return NULL;\r
+\r
+    assert(TYPE(CHILD(n, 1)) == funcdef ||\r
+           TYPE(CHILD(n, 1)) == classdef);\r
+\r
+    if (TYPE(CHILD(n, 1)) == funcdef) {\r
+      thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq);\r
+    } else if (TYPE(CHILD(n, 1)) == classdef) {\r
+      thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq);\r
+    }\r
+    /* we count the decorators in when talking about the class' or\r
+       function's line number */\r
+    if (thing) {\r
+        thing->lineno = LINENO(n);\r
+        thing->col_offset = n->n_col_offset;\r
+    }\r
+    return thing;\r
+}\r
+\r
+static expr_ty\r
+ast_for_lambdef(struct compiling *c, const node *n)\r
+{\r
+    /* lambdef: 'lambda' [varargslist] ':' test */\r
+    arguments_ty args;\r
+    expr_ty expression;\r
+\r
+    if (NCH(n) == 3) {\r
+        args = arguments(NULL, NULL, NULL, NULL, c->c_arena);\r
+        if (!args)\r
+            return NULL;\r
+        expression = ast_for_expr(c, CHILD(n, 2));\r
+        if (!expression)\r
+            return NULL;\r
+    }\r
+    else {\r
+        args = ast_for_arguments(c, CHILD(n, 1));\r
+        if (!args)\r
+            return NULL;\r
+        expression = ast_for_expr(c, CHILD(n, 3));\r
+        if (!expression)\r
+            return NULL;\r
+    }\r
+\r
+    return Lambda(args, expression, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static expr_ty\r
+ast_for_ifexpr(struct compiling *c, const node *n)\r
+{\r
+    /* test: or_test 'if' or_test 'else' test */\r
+    expr_ty expression, body, orelse;\r
+\r
+    assert(NCH(n) == 5);\r
+    body = ast_for_expr(c, CHILD(n, 0));\r
+    if (!body)\r
+        return NULL;\r
+    expression = ast_for_expr(c, CHILD(n, 2));\r
+    if (!expression)\r
+        return NULL;\r
+    orelse = ast_for_expr(c, CHILD(n, 4));\r
+    if (!orelse)\r
+        return NULL;\r
+    return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,\r
+                 c->c_arena);\r
+}\r
+\r
+/* XXX(nnorwitz): the listcomp and genexpr code should be refactored\r
+   so there is only a single version.  Possibly for loops can also re-use\r
+   the code.\r
+*/\r
+\r
+/* Count the number of 'for' loop in a list comprehension.\r
+\r
+   Helper for ast_for_listcomp().\r
+*/\r
+\r
+static int\r
+count_list_fors(struct compiling *c, const node *n)\r
+{\r
+    int n_fors = 0;\r
+    node *ch = CHILD(n, 1);\r
+\r
+ count_list_for:\r
+    n_fors++;\r
+    REQ(ch, list_for);\r
+    if (NCH(ch) == 5)\r
+        ch = CHILD(ch, 4);\r
+    else\r
+        return n_fors;\r
+ count_list_iter:\r
+    REQ(ch, list_iter);\r
+    ch = CHILD(ch, 0);\r
+    if (TYPE(ch) == list_for)\r
+        goto count_list_for;\r
+    else if (TYPE(ch) == list_if) {\r
+        if (NCH(ch) == 3) {\r
+            ch = CHILD(ch, 2);\r
+            goto count_list_iter;\r
+        }\r
+        else\r
+            return n_fors;\r
+    }\r
+\r
+    /* Should never be reached */\r
+    PyErr_SetString(PyExc_SystemError, "logic error in count_list_fors");\r
+    return -1;\r
+}\r
+\r
+/* Count the number of 'if' statements in a list comprehension.\r
+\r
+   Helper for ast_for_listcomp().\r
+*/\r
+\r
+static int\r
+count_list_ifs(struct compiling *c, const node *n)\r
+{\r
+    int n_ifs = 0;\r
+\r
+ count_list_iter:\r
+    REQ(n, list_iter);\r
+    if (TYPE(CHILD(n, 0)) == list_for)\r
+        return n_ifs;\r
+    n = CHILD(n, 0);\r
+    REQ(n, list_if);\r
+    n_ifs++;\r
+    if (NCH(n) == 2)\r
+        return n_ifs;\r
+    n = CHILD(n, 2);\r
+    goto count_list_iter;\r
+}\r
+\r
+static expr_ty\r
+ast_for_listcomp(struct compiling *c, const node *n)\r
+{\r
+    /* listmaker: test ( list_for | (',' test)* [','] )\r
+       list_for: 'for' exprlist 'in' testlist_safe [list_iter]\r
+       list_iter: list_for | list_if\r
+       list_if: 'if' test [list_iter]\r
+       testlist_safe: test [(',' test)+ [',']]\r
+    */\r
+    expr_ty elt, first;\r
+    asdl_seq *listcomps;\r
+    int i, n_fors;\r
+    node *ch;\r
+\r
+    REQ(n, listmaker);\r
+    assert(NCH(n) > 1);\r
+\r
+    elt = ast_for_expr(c, CHILD(n, 0));\r
+    if (!elt)\r
+        return NULL;\r
+\r
+    n_fors = count_list_fors(c, n);\r
+    if (n_fors == -1)\r
+        return NULL;\r
+\r
+    listcomps = asdl_seq_new(n_fors, c->c_arena);\r
+    if (!listcomps)\r
+        return NULL;\r
+\r
+    ch = CHILD(n, 1);\r
+    for (i = 0; i < n_fors; i++) {\r
+        comprehension_ty lc;\r
+        asdl_seq *t;\r
+        expr_ty expression;\r
+        node *for_ch;\r
+\r
+        REQ(ch, list_for);\r
+\r
+        for_ch = CHILD(ch, 1);\r
+        t = ast_for_exprlist(c, for_ch, Store);\r
+        if (!t)\r
+            return NULL;\r
+        expression = ast_for_testlist(c, CHILD(ch, 3));\r
+        if (!expression)\r
+            return NULL;\r
+\r
+        /* Check the # of children rather than the length of t, since\r
+           [x for x, in ... ] has 1 element in t, but still requires a Tuple.\r
+        */\r
+        first = (expr_ty)asdl_seq_GET(t, 0);\r
+        if (NCH(for_ch) == 1)\r
+            lc = comprehension(first, expression, NULL, c->c_arena);\r
+        else\r
+            lc = comprehension(Tuple(t, Store, first->lineno, first->col_offset,\r
+                                     c->c_arena),\r
+                               expression, NULL, c->c_arena);\r
+        if (!lc)\r
+            return NULL;\r
+\r
+        if (NCH(ch) == 5) {\r
+            int j, n_ifs;\r
+            asdl_seq *ifs;\r
+            expr_ty list_for_expr;\r
+\r
+            ch = CHILD(ch, 4);\r
+            n_ifs = count_list_ifs(c, ch);\r
+            if (n_ifs == -1)\r
+                return NULL;\r
+\r
+            ifs = asdl_seq_new(n_ifs, c->c_arena);\r
+            if (!ifs)\r
+                return NULL;\r
+\r
+            for (j = 0; j < n_ifs; j++) {\r
+                REQ(ch, list_iter);\r
+                ch = CHILD(ch, 0);\r
+                REQ(ch, list_if);\r
+\r
+                list_for_expr = ast_for_expr(c, CHILD(ch, 1));\r
+                if (!list_for_expr)\r
+                    return NULL;\r
+\r
+                asdl_seq_SET(ifs, j, list_for_expr);\r
+                if (NCH(ch) == 3)\r
+                    ch = CHILD(ch, 2);\r
+            }\r
+            /* on exit, must guarantee that ch is a list_for */\r
+            if (TYPE(ch) == list_iter)\r
+                ch = CHILD(ch, 0);\r
+            lc->ifs = ifs;\r
+        }\r
+        asdl_seq_SET(listcomps, i, lc);\r
+    }\r
+\r
+    return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+/*\r
+   Count the number of 'for' loops in a comprehension.\r
+\r
+   Helper for ast_for_comprehension().\r
+*/\r
+\r
+static int\r
+count_comp_fors(struct compiling *c, const node *n)\r
+{\r
+    int n_fors = 0;\r
+\r
+  count_comp_for:\r
+    n_fors++;\r
+    REQ(n, comp_for);\r
+    if (NCH(n) == 5)\r
+        n = CHILD(n, 4);\r
+    else\r
+        return n_fors;\r
+  count_comp_iter:\r
+    REQ(n, comp_iter);\r
+    n = CHILD(n, 0);\r
+    if (TYPE(n) == comp_for)\r
+        goto count_comp_for;\r
+    else if (TYPE(n) == comp_if) {\r
+        if (NCH(n) == 3) {\r
+            n = CHILD(n, 2);\r
+            goto count_comp_iter;\r
+        }\r
+        else\r
+            return n_fors;\r
+    }\r
+\r
+    /* Should never be reached */\r
+    PyErr_SetString(PyExc_SystemError,\r
+                    "logic error in count_comp_fors");\r
+    return -1;\r
+}\r
+\r
+/* Count the number of 'if' statements in a comprehension.\r
+\r
+   Helper for ast_for_comprehension().\r
+*/\r
+\r
+static int\r
+count_comp_ifs(struct compiling *c, const node *n)\r
+{\r
+    int n_ifs = 0;\r
+\r
+    while (1) {\r
+        REQ(n, comp_iter);\r
+        if (TYPE(CHILD(n, 0)) == comp_for)\r
+            return n_ifs;\r
+        n = CHILD(n, 0);\r
+        REQ(n, comp_if);\r
+        n_ifs++;\r
+        if (NCH(n) == 2)\r
+            return n_ifs;\r
+        n = CHILD(n, 2);\r
+    }\r
+}\r
+\r
+static asdl_seq *\r
+ast_for_comprehension(struct compiling *c, const node *n)\r
+{\r
+    int i, n_fors;\r
+    asdl_seq *comps;\r
+\r
+    n_fors = count_comp_fors(c, n);\r
+    if (n_fors == -1)\r
+        return NULL;\r
+\r
+    comps = asdl_seq_new(n_fors, c->c_arena);\r
+    if (!comps)\r
+        return NULL;\r
+\r
+    for (i = 0; i < n_fors; i++) {\r
+        comprehension_ty comp;\r
+        asdl_seq *t;\r
+        expr_ty expression, first;\r
+        node *for_ch;\r
+\r
+        REQ(n, comp_for);\r
+\r
+        for_ch = CHILD(n, 1);\r
+        t = ast_for_exprlist(c, for_ch, Store);\r
+        if (!t)\r
+            return NULL;\r
+        expression = ast_for_expr(c, CHILD(n, 3));\r
+        if (!expression)\r
+            return NULL;\r
+\r
+        /* Check the # of children rather than the length of t, since\r
+           (x for x, in ...) has 1 element in t, but still requires a Tuple. */\r
+        first = (expr_ty)asdl_seq_GET(t, 0);\r
+        if (NCH(for_ch) == 1)\r
+            comp = comprehension(first, expression, NULL, c->c_arena);\r
+        else\r
+            comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset,\r
+                                     c->c_arena),\r
+                               expression, NULL, c->c_arena);\r
+        if (!comp)\r
+            return NULL;\r
+\r
+        if (NCH(n) == 5) {\r
+            int j, n_ifs;\r
+            asdl_seq *ifs;\r
+\r
+            n = CHILD(n, 4);\r
+            n_ifs = count_comp_ifs(c, n);\r
+            if (n_ifs == -1)\r
+                return NULL;\r
+\r
+            ifs = asdl_seq_new(n_ifs, c->c_arena);\r
+            if (!ifs)\r
+                return NULL;\r
+\r
+            for (j = 0; j < n_ifs; j++) {\r
+                REQ(n, comp_iter);\r
+                n = CHILD(n, 0);\r
+                REQ(n, comp_if);\r
+\r
+                expression = ast_for_expr(c, CHILD(n, 1));\r
+                if (!expression)\r
+                    return NULL;\r
+                asdl_seq_SET(ifs, j, expression);\r
+                if (NCH(n) == 3)\r
+                    n = CHILD(n, 2);\r
+            }\r
+            /* on exit, must guarantee that n is a comp_for */\r
+            if (TYPE(n) == comp_iter)\r
+                n = CHILD(n, 0);\r
+            comp->ifs = ifs;\r
+        }\r
+        asdl_seq_SET(comps, i, comp);\r
+    }\r
+    return comps;\r
+}\r
+\r
+static expr_ty\r
+ast_for_itercomp(struct compiling *c, const node *n, int type)\r
+{\r
+    expr_ty elt;\r
+    asdl_seq *comps;\r
+\r
+    assert(NCH(n) > 1);\r
+\r
+    elt = ast_for_expr(c, CHILD(n, 0));\r
+    if (!elt)\r
+        return NULL;\r
+\r
+    comps = ast_for_comprehension(c, CHILD(n, 1));\r
+    if (!comps)\r
+        return NULL;\r
+\r
+    if (type == COMP_GENEXP)\r
+        return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);\r
+    else if (type == COMP_SETCOMP)\r
+        return SetComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);\r
+    else\r
+        /* Should never happen */\r
+        return NULL;\r
+}\r
+\r
+static expr_ty\r
+ast_for_dictcomp(struct compiling *c, const node *n)\r
+{\r
+    expr_ty key, value;\r
+    asdl_seq *comps;\r
+\r
+    assert(NCH(n) > 3);\r
+    REQ(CHILD(n, 1), COLON);\r
+\r
+    key = ast_for_expr(c, CHILD(n, 0));\r
+    if (!key)\r
+        return NULL;\r
+\r
+    value = ast_for_expr(c, CHILD(n, 2));\r
+    if (!value)\r
+        return NULL;\r
+\r
+    comps = ast_for_comprehension(c, CHILD(n, 3));\r
+    if (!comps)\r
+        return NULL;\r
+\r
+    return DictComp(key, value, comps, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static expr_ty\r
+ast_for_genexp(struct compiling *c, const node *n)\r
+{\r
+    assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument));\r
+    return ast_for_itercomp(c, n, COMP_GENEXP);\r
+}\r
+\r
+static expr_ty\r
+ast_for_setcomp(struct compiling *c, const node *n)\r
+{\r
+    assert(TYPE(n) == (dictorsetmaker));\r
+    return ast_for_itercomp(c, n, COMP_SETCOMP);\r
+}\r
+\r
+static expr_ty\r
+ast_for_atom(struct compiling *c, const node *n)\r
+{\r
+    /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']'\r
+       | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+\r
+    */\r
+    node *ch = CHILD(n, 0);\r
+\r
+    switch (TYPE(ch)) {\r
+    case NAME: {\r
+        /* All names start in Load context, but may later be\r
+           changed. */\r
+        PyObject *name = NEW_IDENTIFIER(ch);\r
+        if (!name)\r
+            return NULL;\r
+        return Name(name, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    case STRING: {\r
+        PyObject *str = parsestrplus(c, n);\r
+        if (!str) {\r
+#ifdef Py_USING_UNICODE\r
+            if (PyErr_ExceptionMatches(PyExc_UnicodeError)){\r
+                PyObject *type, *value, *tback, *errstr;\r
+                PyErr_Fetch(&type, &value, &tback);\r
+                errstr = PyObject_Str(value);\r
+                if (errstr) {\r
+                    char *s = "";\r
+                    char buf[128];\r
+                    s = PyString_AsString(errstr);\r
+                    PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s);\r
+                    ast_error(n, buf);\r
+                    Py_DECREF(errstr);\r
+                } else {\r
+                    ast_error(n, "(unicode error) unknown error");\r
+                }\r
+                Py_DECREF(type);\r
+                Py_DECREF(value);\r
+                Py_XDECREF(tback);\r
+            }\r
+#endif\r
+            return NULL;\r
+        }\r
+        PyArena_AddPyObject(c->c_arena, str);\r
+        return Str(str, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    case NUMBER: {\r
+        PyObject *pynum = parsenumber(c, STR(ch));\r
+        if (!pynum)\r
+            return NULL;\r
+\r
+        PyArena_AddPyObject(c->c_arena, pynum);\r
+        return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    case LPAR: /* some parenthesized expressions */\r
+        ch = CHILD(n, 1);\r
+\r
+        if (TYPE(ch) == RPAR)\r
+            return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+\r
+        if (TYPE(ch) == yield_expr)\r
+            return ast_for_expr(c, ch);\r
+\r
+        return ast_for_testlist_comp(c, ch);\r
+    case LSQB: /* list (or list comprehension) */\r
+        ch = CHILD(n, 1);\r
+\r
+        if (TYPE(ch) == RSQB)\r
+            return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+\r
+        REQ(ch, listmaker);\r
+        if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {\r
+            asdl_seq *elts = seq_for_testlist(c, ch);\r
+            if (!elts)\r
+                return NULL;\r
+\r
+            return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+        }\r
+        else\r
+            return ast_for_listcomp(c, ch);\r
+    case LBRACE: {\r
+        /* dictorsetmaker:\r
+         *    (test ':' test (comp_for | (',' test ':' test)* [','])) |\r
+         *    (test (comp_for | (',' test)* [',']))\r
+         */\r
+        int i, size;\r
+        asdl_seq *keys, *values;\r
+\r
+        ch = CHILD(n, 1);\r
+        if (TYPE(ch) == RBRACE) {\r
+            /* it's an empty dict */\r
+            return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);\r
+        } else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {\r
+            /* it's a simple set */\r
+            asdl_seq *elts;\r
+            size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */\r
+            elts = asdl_seq_new(size, c->c_arena);\r
+            if (!elts)\r
+                return NULL;\r
+            for (i = 0; i < NCH(ch); i += 2) {\r
+                expr_ty expression;\r
+                expression = ast_for_expr(c, CHILD(ch, i));\r
+                if (!expression)\r
+                    return NULL;\r
+                asdl_seq_SET(elts, i / 2, expression);\r
+            }\r
+            return Set(elts, LINENO(n), n->n_col_offset, c->c_arena);\r
+        } else if (TYPE(CHILD(ch, 1)) == comp_for) {\r
+            /* it's a set comprehension */\r
+            return ast_for_setcomp(c, ch);\r
+        } else if (NCH(ch) > 3 && TYPE(CHILD(ch, 3)) == comp_for) {\r
+            return ast_for_dictcomp(c, ch);\r
+        } else {\r
+            /* it's a dict */\r
+            size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */\r
+            keys = asdl_seq_new(size, c->c_arena);\r
+            if (!keys)\r
+                return NULL;\r
+\r
+            values = asdl_seq_new(size, c->c_arena);\r
+            if (!values)\r
+                return NULL;\r
+\r
+            for (i = 0; i < NCH(ch); i += 4) {\r
+                expr_ty expression;\r
+\r
+                expression = ast_for_expr(c, CHILD(ch, i));\r
+                if (!expression)\r
+                    return NULL;\r
+\r
+                asdl_seq_SET(keys, i / 4, expression);\r
+\r
+                expression = ast_for_expr(c, CHILD(ch, i + 2));\r
+                if (!expression)\r
+                    return NULL;\r
+\r
+                asdl_seq_SET(values, i / 4, expression);\r
+            }\r
+            return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);\r
+        }\r
+    }\r
+    case BACKQUOTE: { /* repr */\r
+        expr_ty expression;\r
+        if (Py_Py3kWarningFlag &&\r
+            !ast_warn(c, n, "backquote not supported in 3.x; use repr()"))\r
+            return NULL;\r
+        expression = ast_for_testlist(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+\r
+        return Repr(expression, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    default:\r
+        PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));\r
+        return NULL;\r
+    }\r
+}\r
+\r
+static slice_ty\r
+ast_for_slice(struct compiling *c, const node *n)\r
+{\r
+    node *ch;\r
+    expr_ty lower = NULL, upper = NULL, step = NULL;\r
+\r
+    REQ(n, subscript);\r
+\r
+    /*\r
+       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]\r
+       sliceop: ':' [test]\r
+    */\r
+    ch = CHILD(n, 0);\r
+    if (TYPE(ch) == DOT)\r
+        return Ellipsis(c->c_arena);\r
+\r
+    if (NCH(n) == 1 && TYPE(ch) == test) {\r
+        /* 'step' variable hold no significance in terms of being used over\r
+           other vars */\r
+        step = ast_for_expr(c, ch);\r
+        if (!step)\r
+            return NULL;\r
+\r
+        return Index(step, c->c_arena);\r
+    }\r
+\r
+    if (TYPE(ch) == test) {\r
+        lower = ast_for_expr(c, ch);\r
+        if (!lower)\r
+            return NULL;\r
+    }\r
+\r
+    /* If there's an upper bound it's in the second or third position. */\r
+    if (TYPE(ch) == COLON) {\r
+        if (NCH(n) > 1) {\r
+            node *n2 = CHILD(n, 1);\r
+\r
+            if (TYPE(n2) == test) {\r
+                upper = ast_for_expr(c, n2);\r
+                if (!upper)\r
+                    return NULL;\r
+            }\r
+        }\r
+    } else if (NCH(n) > 2) {\r
+        node *n2 = CHILD(n, 2);\r
+\r
+        if (TYPE(n2) == test) {\r
+            upper = ast_for_expr(c, n2);\r
+            if (!upper)\r
+                return NULL;\r
+        }\r
+    }\r
+\r
+    ch = CHILD(n, NCH(n) - 1);\r
+    if (TYPE(ch) == sliceop) {\r
+        if (NCH(ch) == 1) {\r
+            /*\r
+              This is an extended slice (ie "x[::]") with no expression in the\r
+              step field. We set this literally to "None" in order to\r
+              disambiguate it from x[:]. (The interpreter might have to call\r
+              __getslice__ for x[:], but it must call __getitem__ for x[::].)\r
+            */\r
+            identifier none = new_identifier("None", c->c_arena);\r
+            if (!none)\r
+                return NULL;\r
+            ch = CHILD(ch, 0);\r
+            step = Name(none, Load, LINENO(ch), ch->n_col_offset, c->c_arena);\r
+            if (!step)\r
+                return NULL;\r
+        } else {\r
+            ch = CHILD(ch, 1);\r
+            if (TYPE(ch) == test) {\r
+                step = ast_for_expr(c, ch);\r
+                if (!step)\r
+                    return NULL;\r
+            }\r
+        }\r
+    }\r
+\r
+    return Slice(lower, upper, step, c->c_arena);\r
+}\r
+\r
+static expr_ty\r
+ast_for_binop(struct compiling *c, const node *n)\r
+{\r
+        /* Must account for a sequence of expressions.\r
+           How should A op B op C by represented?\r
+           BinOp(BinOp(A, op, B), op, C).\r
+        */\r
+\r
+        int i, nops;\r
+        expr_ty expr1, expr2, result;\r
+        operator_ty newoperator;\r
+\r
+        expr1 = ast_for_expr(c, CHILD(n, 0));\r
+        if (!expr1)\r
+            return NULL;\r
+\r
+        expr2 = ast_for_expr(c, CHILD(n, 2));\r
+        if (!expr2)\r
+            return NULL;\r
+\r
+        newoperator = get_operator(CHILD(n, 1));\r
+        if (!newoperator)\r
+            return NULL;\r
+\r
+        result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,\r
+                       c->c_arena);\r
+        if (!result)\r
+            return NULL;\r
+\r
+        nops = (NCH(n) - 1) / 2;\r
+        for (i = 1; i < nops; i++) {\r
+                expr_ty tmp_result, tmp;\r
+                const node* next_oper = CHILD(n, i * 2 + 1);\r
+\r
+                newoperator = get_operator(next_oper);\r
+                if (!newoperator)\r
+                    return NULL;\r
+\r
+                tmp = ast_for_expr(c, CHILD(n, i * 2 + 2));\r
+                if (!tmp)\r
+                    return NULL;\r
+\r
+                tmp_result = BinOp(result, newoperator, tmp,\r
+                                   LINENO(next_oper), next_oper->n_col_offset,\r
+                                   c->c_arena);\r
+                if (!tmp_result)\r
+                        return NULL;\r
+                result = tmp_result;\r
+        }\r
+        return result;\r
+}\r
+\r
+static expr_ty\r
+ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)\r
+{\r
+    /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME\r
+       subscriptlist: subscript (',' subscript)* [',']\r
+       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]\r
+     */\r
+    REQ(n, trailer);\r
+    if (TYPE(CHILD(n, 0)) == LPAR) {\r
+        if (NCH(n) == 2)\r
+            return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n),\r
+                        n->n_col_offset, c->c_arena);\r
+        else\r
+            return ast_for_call(c, CHILD(n, 1), left_expr);\r
+    }\r
+    else if (TYPE(CHILD(n, 0)) == DOT ) {\r
+        PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1));\r
+        if (!attr_id)\r
+            return NULL;\r
+        return Attribute(left_expr, attr_id, Load,\r
+                         LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    else {\r
+        REQ(CHILD(n, 0), LSQB);\r
+        REQ(CHILD(n, 2), RSQB);\r
+        n = CHILD(n, 1);\r
+        if (NCH(n) == 1) {\r
+            slice_ty slc = ast_for_slice(c, CHILD(n, 0));\r
+            if (!slc)\r
+                return NULL;\r
+            return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset,\r
+                             c->c_arena);\r
+        }\r
+        else {\r
+            /* The grammar is ambiguous here. The ambiguity is resolved\r
+               by treating the sequence as a tuple literal if there are\r
+               no slice features.\r
+            */\r
+            int j;\r
+            slice_ty slc;\r
+            expr_ty e;\r
+            bool simple = true;\r
+            asdl_seq *slices, *elts;\r
+            slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);\r
+            if (!slices)\r
+                return NULL;\r
+            for (j = 0; j < NCH(n); j += 2) {\r
+                slc = ast_for_slice(c, CHILD(n, j));\r
+                if (!slc)\r
+                    return NULL;\r
+                if (slc->kind != Index_kind)\r
+                    simple = false;\r
+                asdl_seq_SET(slices, j / 2, slc);\r
+            }\r
+            if (!simple) {\r
+                return Subscript(left_expr, ExtSlice(slices, c->c_arena),\r
+                                 Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+            }\r
+            /* extract Index values and put them in a Tuple */\r
+            elts = asdl_seq_new(asdl_seq_LEN(slices), c->c_arena);\r
+            if (!elts)\r
+                return NULL;\r
+            for (j = 0; j < asdl_seq_LEN(slices); ++j) {\r
+                slc = (slice_ty)asdl_seq_GET(slices, j);\r
+                assert(slc->kind == Index_kind  && slc->v.Index.value);\r
+                asdl_seq_SET(elts, j, slc->v.Index.value);\r
+            }\r
+            e = Tuple(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+            if (!e)\r
+                return NULL;\r
+            return Subscript(left_expr, Index(e, c->c_arena),\r
+                             Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+        }\r
+    }\r
+}\r
+\r
+static expr_ty\r
+ast_for_factor(struct compiling *c, const node *n)\r
+{\r
+    node *pfactor, *ppower, *patom, *pnum;\r
+    expr_ty expression;\r
+\r
+    /* If the unary - operator is applied to a constant, don't generate\r
+       a UNARY_NEGATIVE opcode.  Just store the approriate value as a\r
+       constant.  The peephole optimizer already does something like\r
+       this but it doesn't handle the case where the constant is\r
+       (sys.maxint - 1).  In that case, we want a PyIntObject, not a\r
+       PyLongObject.\r
+    */\r
+    if (TYPE(CHILD(n, 0)) == MINUS &&\r
+        NCH(n) == 2 &&\r
+        TYPE((pfactor = CHILD(n, 1))) == factor &&\r
+        NCH(pfactor) == 1 &&\r
+        TYPE((ppower = CHILD(pfactor, 0))) == power &&\r
+        NCH(ppower) == 1 &&\r
+        TYPE((patom = CHILD(ppower, 0))) == atom &&\r
+        TYPE((pnum = CHILD(patom, 0))) == NUMBER) {\r
+        PyObject *pynum;\r
+        char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2);\r
+        if (s == NULL)\r
+            return NULL;\r
+        s[0] = '-';\r
+        strcpy(s + 1, STR(pnum));\r
+        pynum = parsenumber(c, s);\r
+        PyObject_FREE(s);\r
+        if (!pynum)\r
+            return NULL;\r
+\r
+        PyArena_AddPyObject(c->c_arena, pynum);\r
+        return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+\r
+    expression = ast_for_expr(c, CHILD(n, 1));\r
+    if (!expression)\r
+        return NULL;\r
+\r
+    switch (TYPE(CHILD(n, 0))) {\r
+        case PLUS:\r
+            return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,\r
+                           c->c_arena);\r
+        case MINUS:\r
+            return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,\r
+                           c->c_arena);\r
+        case TILDE:\r
+            return UnaryOp(Invert, expression, LINENO(n),\r
+                           n->n_col_offset, c->c_arena);\r
+    }\r
+    PyErr_Format(PyExc_SystemError, "unhandled factor: %d",\r
+                 TYPE(CHILD(n, 0)));\r
+    return NULL;\r
+}\r
+\r
+static expr_ty\r
+ast_for_power(struct compiling *c, const node *n)\r
+{\r
+    /* power: atom trailer* ('**' factor)*\r
+     */\r
+    int i;\r
+    expr_ty e, tmp;\r
+    REQ(n, power);\r
+    e = ast_for_atom(c, CHILD(n, 0));\r
+    if (!e)\r
+        return NULL;\r
+    if (NCH(n) == 1)\r
+        return e;\r
+    for (i = 1; i < NCH(n); i++) {\r
+        node *ch = CHILD(n, i);\r
+        if (TYPE(ch) != trailer)\r
+            break;\r
+        tmp = ast_for_trailer(c, ch, e);\r
+        if (!tmp)\r
+            return NULL;\r
+        tmp->lineno = e->lineno;\r
+        tmp->col_offset = e->col_offset;\r
+        e = tmp;\r
+    }\r
+    if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {\r
+        expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));\r
+        if (!f)\r
+            return NULL;\r
+        tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);\r
+        if (!tmp)\r
+            return NULL;\r
+        e = tmp;\r
+    }\r
+    return e;\r
+}\r
+\r
+/* Do not name a variable 'expr'!  Will cause a compile error.\r
+*/\r
+\r
+static expr_ty\r
+ast_for_expr(struct compiling *c, const node *n)\r
+{\r
+    /* handle the full range of simple expressions\r
+       test: or_test ['if' or_test 'else' test] | lambdef\r
+       or_test: and_test ('or' and_test)*\r
+       and_test: not_test ('and' not_test)*\r
+       not_test: 'not' not_test | comparison\r
+       comparison: expr (comp_op expr)*\r
+       expr: xor_expr ('|' xor_expr)*\r
+       xor_expr: and_expr ('^' and_expr)*\r
+       and_expr: shift_expr ('&' shift_expr)*\r
+       shift_expr: arith_expr (('<<'|'>>') arith_expr)*\r
+       arith_expr: term (('+'|'-') term)*\r
+       term: factor (('*'|'/'|'%'|'//') factor)*\r
+       factor: ('+'|'-'|'~') factor | power\r
+       power: atom trailer* ('**' factor)*\r
+\r
+       As well as modified versions that exist for backward compatibility,\r
+       to explicitly allow:\r
+       [ x for x in lambda: 0, lambda: 1 ]\r
+       (which would be ambiguous without these extra rules)\r
+\r
+       old_test: or_test | old_lambdef\r
+       old_lambdef: 'lambda' [vararglist] ':' old_test\r
+\r
+    */\r
+\r
+    asdl_seq *seq;\r
+    int i;\r
+\r
+ loop:\r
+    switch (TYPE(n)) {\r
+        case test:\r
+        case old_test:\r
+            if (TYPE(CHILD(n, 0)) == lambdef ||\r
+                TYPE(CHILD(n, 0)) == old_lambdef)\r
+                return ast_for_lambdef(c, CHILD(n, 0));\r
+            else if (NCH(n) > 1)\r
+                return ast_for_ifexpr(c, n);\r
+            /* Fallthrough */\r
+        case or_test:\r
+        case and_test:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);\r
+            if (!seq)\r
+                return NULL;\r
+            for (i = 0; i < NCH(n); i += 2) {\r
+                expr_ty e = ast_for_expr(c, CHILD(n, i));\r
+                if (!e)\r
+                    return NULL;\r
+                asdl_seq_SET(seq, i / 2, e);\r
+            }\r
+            if (!strcmp(STR(CHILD(n, 1)), "and"))\r
+                return BoolOp(And, seq, LINENO(n), n->n_col_offset,\r
+                              c->c_arena);\r
+            assert(!strcmp(STR(CHILD(n, 1)), "or"));\r
+            return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena);\r
+        case not_test:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            else {\r
+                expr_ty expression = ast_for_expr(c, CHILD(n, 1));\r
+                if (!expression)\r
+                    return NULL;\r
+\r
+                return UnaryOp(Not, expression, LINENO(n), n->n_col_offset,\r
+                               c->c_arena);\r
+            }\r
+        case comparison:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            else {\r
+                expr_ty expression;\r
+                asdl_int_seq *ops;\r
+                asdl_seq *cmps;\r
+                ops = asdl_int_seq_new(NCH(n) / 2, c->c_arena);\r
+                if (!ops)\r
+                    return NULL;\r
+                cmps = asdl_seq_new(NCH(n) / 2, c->c_arena);\r
+                if (!cmps) {\r
+                    return NULL;\r
+                }\r
+                for (i = 1; i < NCH(n); i += 2) {\r
+                    cmpop_ty newoperator;\r
+\r
+                    newoperator = ast_for_comp_op(c, CHILD(n, i));\r
+                    if (!newoperator) {\r
+                        return NULL;\r
+                    }\r
+\r
+                    expression = ast_for_expr(c, CHILD(n, i + 1));\r
+                    if (!expression) {\r
+                        return NULL;\r
+                    }\r
+\r
+                    asdl_seq_SET(ops, i / 2, newoperator);\r
+                    asdl_seq_SET(cmps, i / 2, expression);\r
+                }\r
+                expression = ast_for_expr(c, CHILD(n, 0));\r
+                if (!expression) {\r
+                    return NULL;\r
+                }\r
+\r
+                return Compare(expression, ops, cmps, LINENO(n),\r
+                               n->n_col_offset, c->c_arena);\r
+            }\r
+            break;\r
+\r
+        /* The next five cases all handle BinOps.  The main body of code\r
+           is the same in each case, but the switch turned inside out to\r
+           reuse the code for each type of operator.\r
+         */\r
+        case expr:\r
+        case xor_expr:\r
+        case and_expr:\r
+        case shift_expr:\r
+        case arith_expr:\r
+        case term:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            return ast_for_binop(c, n);\r
+        case yield_expr: {\r
+            expr_ty exp = NULL;\r
+            if (NCH(n) == 2) {\r
+                exp = ast_for_testlist(c, CHILD(n, 1));\r
+                if (!exp)\r
+                    return NULL;\r
+            }\r
+            return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena);\r
+        }\r
+        case factor:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            return ast_for_factor(c, n);\r
+        case power:\r
+            return ast_for_power(c, n);\r
+        default:\r
+            PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n));\r
+            return NULL;\r
+    }\r
+    /* should never get here unless if error is set */\r
+    return NULL;\r
+}\r
+\r
+static expr_ty\r
+ast_for_call(struct compiling *c, const node *n, expr_ty func)\r
+{\r
+    /*\r
+      arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]\r
+               | '**' test)\r
+      argument: [test '='] test [comp_for]        # Really [keyword '='] test\r
+    */\r
+\r
+    int i, nargs, nkeywords, ngens;\r
+    asdl_seq *args;\r
+    asdl_seq *keywords;\r
+    expr_ty vararg = NULL, kwarg = NULL;\r
+\r
+    REQ(n, arglist);\r
+\r
+    nargs = 0;\r
+    nkeywords = 0;\r
+    ngens = 0;\r
+    for (i = 0; i < NCH(n); i++) {\r
+        node *ch = CHILD(n, i);\r
+        if (TYPE(ch) == argument) {\r
+            if (NCH(ch) == 1)\r
+                nargs++;\r
+            else if (TYPE(CHILD(ch, 1)) == comp_for)\r
+                ngens++;\r
+            else\r
+                nkeywords++;\r
+        }\r
+    }\r
+    if (ngens > 1 || (ngens && (nargs || nkeywords))) {\r
+        ast_error(n, "Generator expression must be parenthesized "\r
+                  "if not sole argument");\r
+        return NULL;\r
+    }\r
+\r
+    if (nargs + nkeywords + ngens > 255) {\r
+      ast_error(n, "more than 255 arguments");\r
+      return NULL;\r
+    }\r
+\r
+    args = asdl_seq_new(nargs + ngens, c->c_arena);\r
+    if (!args)\r
+        return NULL;\r
+    keywords = asdl_seq_new(nkeywords, c->c_arena);\r
+    if (!keywords)\r
+        return NULL;\r
+    nargs = 0;\r
+    nkeywords = 0;\r
+    for (i = 0; i < NCH(n); i++) {\r
+        node *ch = CHILD(n, i);\r
+        if (TYPE(ch) == argument) {\r
+            expr_ty e;\r
+            if (NCH(ch) == 1) {\r
+                if (nkeywords) {\r
+                    ast_error(CHILD(ch, 0),\r
+                              "non-keyword arg after keyword arg");\r
+                    return NULL;\r
+                }\r
+                if (vararg) {\r
+                    ast_error(CHILD(ch, 0),\r
+                              "only named arguments may follow *expression");\r
+                    return NULL;\r
+                }\r
+                e = ast_for_expr(c, CHILD(ch, 0));\r
+                if (!e)\r
+                    return NULL;\r
+                asdl_seq_SET(args, nargs++, e);\r
+            }\r
+            else if (TYPE(CHILD(ch, 1)) == comp_for) {\r
+                e = ast_for_genexp(c, ch);\r
+                if (!e)\r
+                    return NULL;\r
+                asdl_seq_SET(args, nargs++, e);\r
+            }\r
+            else {\r
+                keyword_ty kw;\r
+                identifier key;\r
+                int k;\r
+                char *tmp;\r
+\r
+                /* CHILD(ch, 0) is test, but must be an identifier? */\r
+                e = ast_for_expr(c, CHILD(ch, 0));\r
+                if (!e)\r
+                    return NULL;\r
+                /* f(lambda x: x[0] = 3) ends up getting parsed with\r
+                 * LHS test = lambda x: x[0], and RHS test = 3.\r
+                 * SF bug 132313 points out that complaining about a keyword\r
+                 * then is very confusing.\r
+                 */\r
+                if (e->kind == Lambda_kind) {\r
+                    ast_error(CHILD(ch, 0),\r
+                              "lambda cannot contain assignment");\r
+                    return NULL;\r
+                } else if (e->kind != Name_kind) {\r
+                    ast_error(CHILD(ch, 0), "keyword can't be an expression");\r
+                    return NULL;\r
+                }\r
+                key = e->v.Name.id;\r
+                if (!forbidden_check(c, CHILD(ch, 0), PyBytes_AS_STRING(key)))\r
+                    return NULL;\r
+                for (k = 0; k < nkeywords; k++) {\r
+                    tmp = PyString_AS_STRING(\r
+                        ((keyword_ty)asdl_seq_GET(keywords, k))->arg);\r
+                    if (!strcmp(tmp, PyString_AS_STRING(key))) {\r
+                        ast_error(CHILD(ch, 0), "keyword argument repeated");\r
+                        return NULL;\r
+                    }\r
+                }\r
+                e = ast_for_expr(c, CHILD(ch, 2));\r
+                if (!e)\r
+                    return NULL;\r
+                kw = keyword(key, e, c->c_arena);\r
+                if (!kw)\r
+                    return NULL;\r
+                asdl_seq_SET(keywords, nkeywords++, kw);\r
+            }\r
+        }\r
+        else if (TYPE(ch) == STAR) {\r
+            vararg = ast_for_expr(c, CHILD(n, i+1));\r
+            if (!vararg)\r
+                return NULL;\r
+            i++;\r
+        }\r
+        else if (TYPE(ch) == DOUBLESTAR) {\r
+            kwarg = ast_for_expr(c, CHILD(n, i+1));\r
+            if (!kwarg)\r
+                return NULL;\r
+            i++;\r
+        }\r
+    }\r
+\r
+    return Call(func, args, keywords, vararg, kwarg, func->lineno,\r
+                func->col_offset, c->c_arena);\r
+}\r
+\r
+static expr_ty\r
+ast_for_testlist(struct compiling *c, const node* n)\r
+{\r
+    /* testlist_comp: test (',' test)* [','] */\r
+    /* testlist: test (',' test)* [','] */\r
+    /* testlist_safe: test (',' test)+ [','] */\r
+    /* testlist1: test (',' test)* */\r
+    assert(NCH(n) > 0);\r
+    if (TYPE(n) == testlist_comp) {\r
+        if (NCH(n) > 1)\r
+            assert(TYPE(CHILD(n, 1)) != comp_for);\r
+    }\r
+    else {\r
+        assert(TYPE(n) == testlist ||\r
+               TYPE(n) == testlist_safe ||\r
+               TYPE(n) == testlist1);\r
+    }\r
+    if (NCH(n) == 1)\r
+        return ast_for_expr(c, CHILD(n, 0));\r
+    else {\r
+        asdl_seq *tmp = seq_for_testlist(c, n);\r
+        if (!tmp)\r
+            return NULL;\r
+        return Tuple(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+}\r
+\r
+static expr_ty\r
+ast_for_testlist_comp(struct compiling *c, const node* n)\r
+{\r
+    /* testlist_comp: test ( comp_for | (',' test)* [','] ) */\r
+    /* argument: test [ comp_for ] */\r
+    assert(TYPE(n) == testlist_comp || TYPE(n) == argument);\r
+    if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == comp_for)\r
+        return ast_for_genexp(c, n);\r
+    return ast_for_testlist(c, n);\r
+}\r
+\r
+/* like ast_for_testlist() but returns a sequence */\r
+static asdl_seq*\r
+ast_for_class_bases(struct compiling *c, const node* n)\r
+{\r
+    /* testlist: test (',' test)* [','] */\r
+    assert(NCH(n) > 0);\r
+    REQ(n, testlist);\r
+    if (NCH(n) == 1) {\r
+        expr_ty base;\r
+        asdl_seq *bases = asdl_seq_new(1, c->c_arena);\r
+        if (!bases)\r
+            return NULL;\r
+        base = ast_for_expr(c, CHILD(n, 0));\r
+        if (!base)\r
+            return NULL;\r
+        asdl_seq_SET(bases, 0, base);\r
+        return bases;\r
+    }\r
+\r
+    return seq_for_testlist(c, n);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_expr_stmt(struct compiling *c, const node *n)\r
+{\r
+    REQ(n, expr_stmt);\r
+    /* expr_stmt: testlist (augassign (yield_expr|testlist)\r
+                | ('=' (yield_expr|testlist))*)\r
+       testlist: test (',' test)* [',']\r
+       augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='\r
+                | '<<=' | '>>=' | '**=' | '//='\r
+       test: ... here starts the operator precendence dance\r
+     */\r
+\r
+    if (NCH(n) == 1) {\r
+        expr_ty e = ast_for_testlist(c, CHILD(n, 0));\r
+        if (!e)\r
+            return NULL;\r
+\r
+        return Expr(e, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    else if (TYPE(CHILD(n, 1)) == augassign) {\r
+        expr_ty expr1, expr2;\r
+        operator_ty newoperator;\r
+        node *ch = CHILD(n, 0);\r
+\r
+        expr1 = ast_for_testlist(c, ch);\r
+        if (!expr1)\r
+            return NULL;\r
+        if(!set_context(c, expr1, Store, ch))\r
+            return NULL;\r
+        /* set_context checks that most expressions are not the left side.\r
+          Augmented assignments can only have a name, a subscript, or an\r
+          attribute on the left, though, so we have to explicitly check for\r
+          those. */\r
+        switch (expr1->kind) {\r
+            case Name_kind:\r
+            case Attribute_kind:\r
+            case Subscript_kind:\r
+                break;\r
+            default:\r
+                ast_error(ch, "illegal expression for augmented assignment");\r
+                return NULL;\r
+        }\r
+\r
+        ch = CHILD(n, 2);\r
+        if (TYPE(ch) == testlist)\r
+            expr2 = ast_for_testlist(c, ch);\r
+        else\r
+            expr2 = ast_for_expr(c, ch);\r
+        if (!expr2)\r
+            return NULL;\r
+\r
+        newoperator = ast_for_augassign(c, CHILD(n, 1));\r
+        if (!newoperator)\r
+            return NULL;\r
+\r
+        return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,\r
+                         c->c_arena);\r
+    }\r
+    else {\r
+        int i;\r
+        asdl_seq *targets;\r
+        node *value;\r
+        expr_ty expression;\r
+\r
+        /* a normal assignment */\r
+        REQ(CHILD(n, 1), EQUAL);\r
+        targets = asdl_seq_new(NCH(n) / 2, c->c_arena);\r
+        if (!targets)\r
+            return NULL;\r
+        for (i = 0; i < NCH(n) - 2; i += 2) {\r
+            expr_ty e;\r
+            node *ch = CHILD(n, i);\r
+            if (TYPE(ch) == yield_expr) {\r
+                ast_error(ch, "assignment to yield expression not possible");\r
+                return NULL;\r
+            }\r
+            e = ast_for_testlist(c, ch);\r
+            if (!e)\r
+                return NULL;\r
+\r
+            /* set context to assign */\r
+            if (!set_context(c, e, Store, CHILD(n, i)))\r
+                return NULL;\r
+\r
+            asdl_seq_SET(targets, i / 2, e);\r
+        }\r
+        value = CHILD(n, NCH(n) - 1);\r
+        if (TYPE(value) == testlist)\r
+            expression = ast_for_testlist(c, value);\r
+        else\r
+            expression = ast_for_expr(c, value);\r
+        if (!expression)\r
+            return NULL;\r
+        return Assign(targets, expression, LINENO(n), n->n_col_offset,\r
+                      c->c_arena);\r
+    }\r
+}\r
+\r
+static stmt_ty\r
+ast_for_print_stmt(struct compiling *c, const node *n)\r
+{\r
+    /* print_stmt: 'print' ( [ test (',' test)* [','] ]\r
+                             | '>>' test [ (',' test)+ [','] ] )\r
+     */\r
+    expr_ty dest = NULL, expression;\r
+    asdl_seq *seq = NULL;\r
+    bool nl;\r
+    int i, j, values_count, start = 1;\r
+\r
+    REQ(n, print_stmt);\r
+    if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {\r
+        dest = ast_for_expr(c, CHILD(n, 2));\r
+        if (!dest)\r
+            return NULL;\r
+            start = 4;\r
+    }\r
+    values_count = (NCH(n) + 1 - start) / 2;\r
+    if (values_count) {\r
+        seq = asdl_seq_new(values_count, c->c_arena);\r
+        if (!seq)\r
+            return NULL;\r
+        for (i = start, j = 0; i < NCH(n); i += 2, ++j) {\r
+            expression = ast_for_expr(c, CHILD(n, i));\r
+            if (!expression)\r
+                return NULL;\r
+            asdl_seq_SET(seq, j, expression);\r
+        }\r
+    }\r
+    nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;\r
+    return Print(dest, seq, nl, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static asdl_seq *\r
+ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context)\r
+{\r
+    asdl_seq *seq;\r
+    int i;\r
+    expr_ty e;\r
+\r
+    REQ(n, exprlist);\r
+\r
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);\r
+    if (!seq)\r
+        return NULL;\r
+    for (i = 0; i < NCH(n); i += 2) {\r
+        e = ast_for_expr(c, CHILD(n, i));\r
+        if (!e)\r
+            return NULL;\r
+        asdl_seq_SET(seq, i / 2, e);\r
+        if (context && !set_context(c, e, context, CHILD(n, i)))\r
+            return NULL;\r
+    }\r
+    return seq;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_del_stmt(struct compiling *c, const node *n)\r
+{\r
+    asdl_seq *expr_list;\r
+\r
+    /* del_stmt: 'del' exprlist */\r
+    REQ(n, del_stmt);\r
+\r
+    expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);\r
+    if (!expr_list)\r
+        return NULL;\r
+    return Delete(expr_list, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_flow_stmt(struct compiling *c, const node *n)\r
+{\r
+    /*\r
+      flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt\r
+                 | yield_stmt\r
+      break_stmt: 'break'\r
+      continue_stmt: 'continue'\r
+      return_stmt: 'return' [testlist]\r
+      yield_stmt: yield_expr\r
+      yield_expr: 'yield' testlist\r
+      raise_stmt: 'raise' [test [',' test [',' test]]]\r
+    */\r
+    node *ch;\r
+\r
+    REQ(n, flow_stmt);\r
+    ch = CHILD(n, 0);\r
+    switch (TYPE(ch)) {\r
+        case break_stmt:\r
+            return Break(LINENO(n), n->n_col_offset, c->c_arena);\r
+        case continue_stmt:\r
+            return Continue(LINENO(n), n->n_col_offset, c->c_arena);\r
+        case yield_stmt: { /* will reduce to yield_expr */\r
+            expr_ty exp = ast_for_expr(c, CHILD(ch, 0));\r
+            if (!exp)\r
+                return NULL;\r
+            return Expr(exp, LINENO(n), n->n_col_offset, c->c_arena);\r
+        }\r
+        case return_stmt:\r
+            if (NCH(ch) == 1)\r
+                return Return(NULL, LINENO(n), n->n_col_offset, c->c_arena);\r
+            else {\r
+                expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));\r
+                if (!expression)\r
+                    return NULL;\r
+                return Return(expression, LINENO(n), n->n_col_offset,\r
+                              c->c_arena);\r
+            }\r
+        case raise_stmt:\r
+            if (NCH(ch) == 1)\r
+                return Raise(NULL, NULL, NULL, LINENO(n), n->n_col_offset,\r
+                             c->c_arena);\r
+            else if (NCH(ch) == 2) {\r
+                expr_ty expression = ast_for_expr(c, CHILD(ch, 1));\r
+                if (!expression)\r
+                    return NULL;\r
+                return Raise(expression, NULL, NULL, LINENO(n),\r
+                             n->n_col_offset, c->c_arena);\r
+            }\r
+            else if (NCH(ch) == 4) {\r
+                expr_ty expr1, expr2;\r
+\r
+                expr1 = ast_for_expr(c, CHILD(ch, 1));\r
+                if (!expr1)\r
+                    return NULL;\r
+                expr2 = ast_for_expr(c, CHILD(ch, 3));\r
+                if (!expr2)\r
+                    return NULL;\r
+\r
+                return Raise(expr1, expr2, NULL, LINENO(n), n->n_col_offset,\r
+                             c->c_arena);\r
+            }\r
+            else if (NCH(ch) == 6) {\r
+                expr_ty expr1, expr2, expr3;\r
+\r
+                expr1 = ast_for_expr(c, CHILD(ch, 1));\r
+                if (!expr1)\r
+                    return NULL;\r
+                expr2 = ast_for_expr(c, CHILD(ch, 3));\r
+                if (!expr2)\r
+                    return NULL;\r
+                expr3 = ast_for_expr(c, CHILD(ch, 5));\r
+                if (!expr3)\r
+                    return NULL;\r
+\r
+                return Raise(expr1, expr2, expr3, LINENO(n), n->n_col_offset,\r
+                             c->c_arena);\r
+            }\r
+        default:\r
+            PyErr_Format(PyExc_SystemError,\r
+                         "unexpected flow_stmt: %d", TYPE(ch));\r
+            return NULL;\r
+    }\r
+\r
+    PyErr_SetString(PyExc_SystemError, "unhandled flow statement");\r
+    return NULL;\r
+}\r
+\r
+static alias_ty\r
+alias_for_import_name(struct compiling *c, const node *n, int store)\r
+{\r
+    /*\r
+      import_as_name: NAME ['as' NAME]\r
+      dotted_as_name: dotted_name ['as' NAME]\r
+      dotted_name: NAME ('.' NAME)*\r
+    */\r
+    PyObject *str, *name;\r
+\r
+ loop:\r
+    switch (TYPE(n)) {\r
+         case import_as_name: {\r
+            node *name_node = CHILD(n, 0);\r
+            str = NULL;\r
+            if (NCH(n) == 3) {\r
+                node *str_node = CHILD(n, 2);\r
+                if (store && !forbidden_check(c, str_node, STR(str_node)))\r
+                    return NULL;\r
+                str = NEW_IDENTIFIER(str_node);\r
+                if (!str)\r
+                    return NULL;\r
+            }\r
+            else {\r
+                if (!forbidden_check(c, name_node, STR(name_node)))\r
+                    return NULL;\r
+            }\r
+            name = NEW_IDENTIFIER(name_node);\r
+            if (!name)\r
+                return NULL;\r
+            return alias(name, str, c->c_arena);\r
+        }\r
+        case dotted_as_name:\r
+            if (NCH(n) == 1) {\r
+                n = CHILD(n, 0);\r
+                goto loop;\r
+            }\r
+            else {\r
+                node *asname_node = CHILD(n, 2);\r
+                alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0);\r
+                if (!a)\r
+                    return NULL;\r
+                assert(!a->asname);\r
+                if (!forbidden_check(c, asname_node, STR(asname_node)))\r
+                    return NULL;\r
+                a->asname = NEW_IDENTIFIER(asname_node);\r
+                if (!a->asname)\r
+                    return NULL;\r
+                return a;\r
+            }\r
+            break;\r
+        case dotted_name:\r
+            if (NCH(n) == 1) {\r
+                node *name_node = CHILD(n, 0);\r
+                if (store && !forbidden_check(c, name_node, STR(name_node)))\r
+                    return NULL;\r
+                name = NEW_IDENTIFIER(name_node);\r
+                if (!name)\r
+                    return NULL;\r
+                return alias(name, NULL, c->c_arena);\r
+            }\r
+            else {\r
+                /* Create a string of the form "a.b.c" */\r
+                int i;\r
+                size_t len;\r
+                char *s;\r
+\r
+                len = 0;\r
+                for (i = 0; i < NCH(n); i += 2)\r
+                    /* length of string plus one for the dot */\r
+                    len += strlen(STR(CHILD(n, i))) + 1;\r
+                len--; /* the last name doesn't have a dot */\r
+                str = PyString_FromStringAndSize(NULL, len);\r
+                if (!str)\r
+                    return NULL;\r
+                s = PyString_AS_STRING(str);\r
+                if (!s)\r
+                    return NULL;\r
+                for (i = 0; i < NCH(n); i += 2) {\r
+                    char *sch = STR(CHILD(n, i));\r
+                    strcpy(s, STR(CHILD(n, i)));\r
+                    s += strlen(sch);\r
+                    *s++ = '.';\r
+                }\r
+                --s;\r
+                *s = '\0';\r
+                PyString_InternInPlace(&str);\r
+                PyArena_AddPyObject(c->c_arena, str);\r
+                return alias(str, NULL, c->c_arena);\r
+            }\r
+            break;\r
+        case STAR:\r
+            str = PyString_InternFromString("*");\r
+            PyArena_AddPyObject(c->c_arena, str);\r
+            return alias(str, NULL, c->c_arena);\r
+        default:\r
+            PyErr_Format(PyExc_SystemError,\r
+                         "unexpected import name: %d", TYPE(n));\r
+            return NULL;\r
+    }\r
+\r
+    PyErr_SetString(PyExc_SystemError, "unhandled import name condition");\r
+    return NULL;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_import_stmt(struct compiling *c, const node *n)\r
+{\r
+    /*\r
+      import_stmt: import_name | import_from\r
+      import_name: 'import' dotted_as_names\r
+      import_from: 'from' ('.'* dotted_name | '.') 'import'\r
+                          ('*' | '(' import_as_names ')' | import_as_names)\r
+    */\r
+    int lineno;\r
+    int col_offset;\r
+    int i;\r
+    asdl_seq *aliases;\r
+\r
+    REQ(n, import_stmt);\r
+    lineno = LINENO(n);\r
+    col_offset = n->n_col_offset;\r
+    n = CHILD(n, 0);\r
+    if (TYPE(n) == import_name) {\r
+        n = CHILD(n, 1);\r
+        REQ(n, dotted_as_names);\r
+        aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);\r
+        if (!aliases)\r
+            return NULL;\r
+        for (i = 0; i < NCH(n); i += 2) {\r
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);\r
+            if (!import_alias)\r
+                return NULL;\r
+            asdl_seq_SET(aliases, i / 2, import_alias);\r
+        }\r
+        return Import(aliases, lineno, col_offset, c->c_arena);\r
+    }\r
+    else if (TYPE(n) == import_from) {\r
+        int n_children;\r
+        int idx, ndots = 0;\r
+        alias_ty mod = NULL;\r
+        identifier modname = NULL;\r
+\r
+       /* Count the number of dots (for relative imports) and check for the\r
+          optional module name */\r
+        for (idx = 1; idx < NCH(n); idx++) {\r
+            if (TYPE(CHILD(n, idx)) == dotted_name) {\r
+                mod = alias_for_import_name(c, CHILD(n, idx), 0);\r
+                if (!mod)\r
+                    return NULL;\r
+                idx++;\r
+                break;\r
+            } else if (TYPE(CHILD(n, idx)) != DOT) {\r
+                break;\r
+            }\r
+            ndots++;\r
+        }\r
+        idx++; /* skip over the 'import' keyword */\r
+        switch (TYPE(CHILD(n, idx))) {\r
+        case STAR:\r
+            /* from ... import * */\r
+            n = CHILD(n, idx);\r
+            n_children = 1;\r
+            break;\r
+        case LPAR:\r
+            /* from ... import (x, y, z) */\r
+            n = CHILD(n, idx + 1);\r
+            n_children = NCH(n);\r
+            break;\r
+        case import_as_names:\r
+            /* from ... import x, y, z */\r
+            n = CHILD(n, idx);\r
+            n_children = NCH(n);\r
+            if (n_children % 2 == 0) {\r
+                ast_error(n, "trailing comma not allowed without"\r
+                             " surrounding parentheses");\r
+                return NULL;\r
+            }\r
+            break;\r
+        default:\r
+            ast_error(n, "Unexpected node-type in from-import");\r
+            return NULL;\r
+        }\r
+\r
+        aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena);\r
+        if (!aliases)\r
+            return NULL;\r
+\r
+        /* handle "from ... import *" special b/c there's no children */\r
+        if (TYPE(n) == STAR) {\r
+            alias_ty import_alias = alias_for_import_name(c, n, 1);\r
+            if (!import_alias)\r
+                return NULL;\r
+                asdl_seq_SET(aliases, 0, import_alias);\r
+        }\r
+        else {\r
+            for (i = 0; i < NCH(n); i += 2) {\r
+                alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);\r
+                if (!import_alias)\r
+                    return NULL;\r
+                    asdl_seq_SET(aliases, i / 2, import_alias);\r
+            }\r
+        }\r
+        if (mod != NULL)\r
+            modname = mod->name;\r
+        return ImportFrom(modname, aliases, ndots, lineno, col_offset,\r
+                          c->c_arena);\r
+    }\r
+    PyErr_Format(PyExc_SystemError,\r
+                 "unknown import statement: starts with command '%s'",\r
+                 STR(CHILD(n, 0)));\r
+    return NULL;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_global_stmt(struct compiling *c, const node *n)\r
+{\r
+    /* global_stmt: 'global' NAME (',' NAME)* */\r
+    identifier name;\r
+    asdl_seq *s;\r
+    int i;\r
+\r
+    REQ(n, global_stmt);\r
+    s = asdl_seq_new(NCH(n) / 2, c->c_arena);\r
+    if (!s)\r
+        return NULL;\r
+    for (i = 1; i < NCH(n); i += 2) {\r
+        name = NEW_IDENTIFIER(CHILD(n, i));\r
+        if (!name)\r
+            return NULL;\r
+        asdl_seq_SET(s, i / 2, name);\r
+    }\r
+    return Global(s, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_exec_stmt(struct compiling *c, const node *n)\r
+{\r
+    expr_ty expr1, globals = NULL, locals = NULL;\r
+    int n_children = NCH(n);\r
+    if (n_children != 2 && n_children != 4 && n_children != 6) {\r
+        PyErr_Format(PyExc_SystemError,\r
+                     "poorly formed 'exec' statement: %d parts to statement",\r
+                     n_children);\r
+        return NULL;\r
+    }\r
+\r
+    /* exec_stmt: 'exec' expr ['in' test [',' test]] */\r
+    REQ(n, exec_stmt);\r
+    expr1 = ast_for_expr(c, CHILD(n, 1));\r
+    if (!expr1)\r
+        return NULL;\r
+\r
+    if (expr1->kind == Tuple_kind && n_children < 4 &&\r
+        (asdl_seq_LEN(expr1->v.Tuple.elts) == 2 ||\r
+         asdl_seq_LEN(expr1->v.Tuple.elts) == 3)) {\r
+        /* Backwards compatibility: passing exec args as a tuple */\r
+        globals = asdl_seq_GET(expr1->v.Tuple.elts, 1);\r
+        if (asdl_seq_LEN(expr1->v.Tuple.elts) == 3) {\r
+            locals = asdl_seq_GET(expr1->v.Tuple.elts, 2);\r
+        }\r
+        expr1 = asdl_seq_GET(expr1->v.Tuple.elts, 0);\r
+    }\r
+\r
+    if (n_children >= 4) {\r
+        globals = ast_for_expr(c, CHILD(n, 3));\r
+        if (!globals)\r
+            return NULL;\r
+    }\r
+    if (n_children == 6) {\r
+        locals = ast_for_expr(c, CHILD(n, 5));\r
+        if (!locals)\r
+            return NULL;\r
+    }\r
+\r
+    return Exec(expr1, globals, locals, LINENO(n), n->n_col_offset,\r
+                c->c_arena);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_assert_stmt(struct compiling *c, const node *n)\r
+{\r
+    /* assert_stmt: 'assert' test [',' test] */\r
+    REQ(n, assert_stmt);\r
+    if (NCH(n) == 2) {\r
+        expr_ty expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        return Assert(expression, NULL, LINENO(n), n->n_col_offset,\r
+                      c->c_arena);\r
+    }\r
+    else if (NCH(n) == 4) {\r
+        expr_ty expr1, expr2;\r
+\r
+        expr1 = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expr1)\r
+            return NULL;\r
+        expr2 = ast_for_expr(c, CHILD(n, 3));\r
+        if (!expr2)\r
+            return NULL;\r
+\r
+        return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+    PyErr_Format(PyExc_SystemError,\r
+                 "improper number of parts to 'assert' statement: %d",\r
+                 NCH(n));\r
+    return NULL;\r
+}\r
+\r
+static asdl_seq *\r
+ast_for_suite(struct compiling *c, const node *n)\r
+{\r
+    /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */\r
+    asdl_seq *seq;\r
+    stmt_ty s;\r
+    int i, total, num, end, pos = 0;\r
+    node *ch;\r
+\r
+    REQ(n, suite);\r
+\r
+    total = num_stmts(n);\r
+    seq = asdl_seq_new(total, c->c_arena);\r
+    if (!seq)\r
+        return NULL;\r
+    if (TYPE(CHILD(n, 0)) == simple_stmt) {\r
+        n = CHILD(n, 0);\r
+        /* simple_stmt always ends with a NEWLINE,\r
+           and may have a trailing SEMI\r
+        */\r
+        end = NCH(n) - 1;\r
+        if (TYPE(CHILD(n, end - 1)) == SEMI)\r
+            end--;\r
+        /* loop by 2 to skip semi-colons */\r
+        for (i = 0; i < end; i += 2) {\r
+            ch = CHILD(n, i);\r
+            s = ast_for_stmt(c, ch);\r
+            if (!s)\r
+                return NULL;\r
+            asdl_seq_SET(seq, pos++, s);\r
+        }\r
+    }\r
+    else {\r
+        for (i = 2; i < (NCH(n) - 1); i++) {\r
+            ch = CHILD(n, i);\r
+            REQ(ch, stmt);\r
+            num = num_stmts(ch);\r
+            if (num == 1) {\r
+                /* small_stmt or compound_stmt with only one child */\r
+                s = ast_for_stmt(c, ch);\r
+                if (!s)\r
+                    return NULL;\r
+                asdl_seq_SET(seq, pos++, s);\r
+            }\r
+            else {\r
+                int j;\r
+                ch = CHILD(ch, 0);\r
+                REQ(ch, simple_stmt);\r
+                for (j = 0; j < NCH(ch); j += 2) {\r
+                    /* statement terminates with a semi-colon ';' */\r
+                    if (NCH(CHILD(ch, j)) == 0) {\r
+                        assert((j + 1) == NCH(ch));\r
+                        break;\r
+                    }\r
+                    s = ast_for_stmt(c, CHILD(ch, j));\r
+                    if (!s)\r
+                        return NULL;\r
+                    asdl_seq_SET(seq, pos++, s);\r
+                }\r
+            }\r
+        }\r
+    }\r
+    assert(pos == seq->size);\r
+    return seq;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_if_stmt(struct compiling *c, const node *n)\r
+{\r
+    /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)*\r
+       ['else' ':' suite]\r
+    */\r
+    char *s;\r
+\r
+    REQ(n, if_stmt);\r
+\r
+    if (NCH(n) == 4) {\r
+        expr_ty expression;\r
+        asdl_seq *suite_seq;\r
+\r
+        expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        suite_seq = ast_for_suite(c, CHILD(n, 3));\r
+        if (!suite_seq)\r
+            return NULL;\r
+\r
+        return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset,\r
+                  c->c_arena);\r
+    }\r
+\r
+    s = STR(CHILD(n, 4));\r
+    /* s[2], the third character in the string, will be\r
+       's' for el_s_e, or\r
+       'i' for el_i_f\r
+    */\r
+    if (s[2] == 's') {\r
+        expr_ty expression;\r
+        asdl_seq *seq1, *seq2;\r
+\r
+        expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        seq1 = ast_for_suite(c, CHILD(n, 3));\r
+        if (!seq1)\r
+            return NULL;\r
+        seq2 = ast_for_suite(c, CHILD(n, 6));\r
+        if (!seq2)\r
+            return NULL;\r
+\r
+        return If(expression, seq1, seq2, LINENO(n), n->n_col_offset,\r
+                  c->c_arena);\r
+    }\r
+    else if (s[2] == 'i') {\r
+        int i, n_elif, has_else = 0;\r
+        expr_ty expression;\r
+        asdl_seq *suite_seq;\r
+        asdl_seq *orelse = NULL;\r
+        n_elif = NCH(n) - 4;\r
+        /* must reference the child n_elif+1 since 'else' token is third,\r
+           not fourth, child from the end. */\r
+        if (TYPE(CHILD(n, (n_elif + 1))) == NAME\r
+            && STR(CHILD(n, (n_elif + 1)))[2] == 's') {\r
+            has_else = 1;\r
+            n_elif -= 3;\r
+        }\r
+        n_elif /= 4;\r
+\r
+        if (has_else) {\r
+            asdl_seq *suite_seq2;\r
+\r
+            orelse = asdl_seq_new(1, c->c_arena);\r
+            if (!orelse)\r
+                return NULL;\r
+            expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));\r
+            if (!expression)\r
+                return NULL;\r
+            suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));\r
+            if (!suite_seq)\r
+                return NULL;\r
+            suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));\r
+            if (!suite_seq2)\r
+                return NULL;\r
+\r
+            asdl_seq_SET(orelse, 0,\r
+                         If(expression, suite_seq, suite_seq2,\r
+                            LINENO(CHILD(n, NCH(n) - 6)),\r
+                            CHILD(n, NCH(n) - 6)->n_col_offset,\r
+                            c->c_arena));\r
+            /* the just-created orelse handled the last elif */\r
+            n_elif--;\r
+        }\r
+\r
+        for (i = 0; i < n_elif; i++) {\r
+            int off = 5 + (n_elif - i - 1) * 4;\r
+            asdl_seq *newobj = asdl_seq_new(1, c->c_arena);\r
+            if (!newobj)\r
+                return NULL;\r
+            expression = ast_for_expr(c, CHILD(n, off));\r
+            if (!expression)\r
+                return NULL;\r
+            suite_seq = ast_for_suite(c, CHILD(n, off + 2));\r
+            if (!suite_seq)\r
+                return NULL;\r
+\r
+            asdl_seq_SET(newobj, 0,\r
+                         If(expression, suite_seq, orelse,\r
+                            LINENO(CHILD(n, off)),\r
+                            CHILD(n, off)->n_col_offset, c->c_arena));\r
+            orelse = newobj;\r
+        }\r
+        expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        suite_seq = ast_for_suite(c, CHILD(n, 3));\r
+        if (!suite_seq)\r
+            return NULL;\r
+        return If(expression, suite_seq, orelse,\r
+                  LINENO(n), n->n_col_offset, c->c_arena);\r
+    }\r
+\r
+    PyErr_Format(PyExc_SystemError,\r
+                 "unexpected token in 'if' statement: %s", s);\r
+    return NULL;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_while_stmt(struct compiling *c, const node *n)\r
+{\r
+    /* while_stmt: 'while' test ':' suite ['else' ':' suite] */\r
+    REQ(n, while_stmt);\r
+\r
+    if (NCH(n) == 4) {\r
+        expr_ty expression;\r
+        asdl_seq *suite_seq;\r
+\r
+        expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        suite_seq = ast_for_suite(c, CHILD(n, 3));\r
+        if (!suite_seq)\r
+            return NULL;\r
+        return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset,\r
+                     c->c_arena);\r
+    }\r
+    else if (NCH(n) == 7) {\r
+        expr_ty expression;\r
+        asdl_seq *seq1, *seq2;\r
+\r
+        expression = ast_for_expr(c, CHILD(n, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        seq1 = ast_for_suite(c, CHILD(n, 3));\r
+        if (!seq1)\r
+            return NULL;\r
+        seq2 = ast_for_suite(c, CHILD(n, 6));\r
+        if (!seq2)\r
+            return NULL;\r
+\r
+        return While(expression, seq1, seq2, LINENO(n), n->n_col_offset,\r
+                     c->c_arena);\r
+    }\r
+\r
+    PyErr_Format(PyExc_SystemError,\r
+                 "wrong number of tokens for 'while' statement: %d",\r
+                 NCH(n));\r
+    return NULL;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_for_stmt(struct compiling *c, const node *n)\r
+{\r
+    asdl_seq *_target, *seq = NULL, *suite_seq;\r
+    expr_ty expression;\r
+    expr_ty target, first;\r
+    const node *node_target;\r
+    /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */\r
+    REQ(n, for_stmt);\r
+\r
+    if (NCH(n) == 9) {\r
+        seq = ast_for_suite(c, CHILD(n, 8));\r
+        if (!seq)\r
+            return NULL;\r
+    }\r
+\r
+    node_target = CHILD(n, 1);\r
+    _target = ast_for_exprlist(c, node_target, Store);\r
+    if (!_target)\r
+        return NULL;\r
+    /* Check the # of children rather than the length of _target, since\r
+       for x, in ... has 1 element in _target, but still requires a Tuple. */\r
+    first = (expr_ty)asdl_seq_GET(_target, 0);\r
+    if (NCH(node_target) == 1)\r
+        target = first;\r
+    else\r
+        target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena);\r
+\r
+    expression = ast_for_testlist(c, CHILD(n, 3));\r
+    if (!expression)\r
+        return NULL;\r
+    suite_seq = ast_for_suite(c, CHILD(n, 5));\r
+    if (!suite_seq)\r
+        return NULL;\r
+\r
+    return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset,\r
+               c->c_arena);\r
+}\r
+\r
+static excepthandler_ty\r
+ast_for_except_clause(struct compiling *c, const node *exc, node *body)\r
+{\r
+    /* except_clause: 'except' [test [(',' | 'as') test]] */\r
+    REQ(exc, except_clause);\r
+    REQ(body, suite);\r
+\r
+    if (NCH(exc) == 1) {\r
+        asdl_seq *suite_seq = ast_for_suite(c, body);\r
+        if (!suite_seq)\r
+            return NULL;\r
+\r
+        return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc),\r
+                             exc->n_col_offset, c->c_arena);\r
+    }\r
+    else if (NCH(exc) == 2) {\r
+        expr_ty expression;\r
+        asdl_seq *suite_seq;\r
+\r
+        expression = ast_for_expr(c, CHILD(exc, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        suite_seq = ast_for_suite(c, body);\r
+        if (!suite_seq)\r
+            return NULL;\r
+\r
+        return ExceptHandler(expression, NULL, suite_seq, LINENO(exc),\r
+                             exc->n_col_offset, c->c_arena);\r
+    }\r
+    else if (NCH(exc) == 4) {\r
+        asdl_seq *suite_seq;\r
+        expr_ty expression;\r
+        expr_ty e = ast_for_expr(c, CHILD(exc, 3));\r
+        if (!e)\r
+            return NULL;\r
+        if (!set_context(c, e, Store, CHILD(exc, 3)))\r
+            return NULL;\r
+        expression = ast_for_expr(c, CHILD(exc, 1));\r
+        if (!expression)\r
+            return NULL;\r
+        suite_seq = ast_for_suite(c, body);\r
+        if (!suite_seq)\r
+            return NULL;\r
+\r
+        return ExceptHandler(expression, e, suite_seq, LINENO(exc),\r
+                             exc->n_col_offset, c->c_arena);\r
+    }\r
+\r
+    PyErr_Format(PyExc_SystemError,\r
+                 "wrong number of children for 'except' clause: %d",\r
+                 NCH(exc));\r
+    return NULL;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_try_stmt(struct compiling *c, const node *n)\r
+{\r
+    const int nch = NCH(n);\r
+    int n_except = (nch - 3)/3;\r
+    asdl_seq *body, *orelse = NULL, *finally = NULL;\r
+\r
+    REQ(n, try_stmt);\r
+\r
+    body = ast_for_suite(c, CHILD(n, 2));\r
+    if (body == NULL)\r
+        return NULL;\r
+\r
+    if (TYPE(CHILD(n, nch - 3)) == NAME) {\r
+        if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {\r
+            if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {\r
+                /* we can assume it's an "else",\r
+                   because nch >= 9 for try-else-finally and\r
+                   it would otherwise have a type of except_clause */\r
+                orelse = ast_for_suite(c, CHILD(n, nch - 4));\r
+                if (orelse == NULL)\r
+                    return NULL;\r
+                n_except--;\r
+            }\r
+\r
+            finally = ast_for_suite(c, CHILD(n, nch - 1));\r
+            if (finally == NULL)\r
+                return NULL;\r
+            n_except--;\r
+        }\r
+        else {\r
+            /* we can assume it's an "else",\r
+               otherwise it would have a type of except_clause */\r
+            orelse = ast_for_suite(c, CHILD(n, nch - 1));\r
+            if (orelse == NULL)\r
+                return NULL;\r
+            n_except--;\r
+        }\r
+    }\r
+    else if (TYPE(CHILD(n, nch - 3)) != except_clause) {\r
+        ast_error(n, "malformed 'try' statement");\r
+        return NULL;\r
+    }\r
+\r
+    if (n_except > 0) {\r
+        int i;\r
+        stmt_ty except_st;\r
+        /* process except statements to create a try ... except */\r
+        asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);\r
+        if (handlers == NULL)\r
+            return NULL;\r
+\r
+        for (i = 0; i < n_except; i++) {\r
+            excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),\r
+                                                       CHILD(n, 5 + i * 3));\r
+            if (!e)\r
+                return NULL;\r
+            asdl_seq_SET(handlers, i, e);\r
+        }\r
+\r
+        except_st = TryExcept(body, handlers, orelse, LINENO(n),\r
+                              n->n_col_offset, c->c_arena);\r
+        if (!finally)\r
+            return except_st;\r
+\r
+        /* if a 'finally' is present too, we nest the TryExcept within a\r
+           TryFinally to emulate try ... except ... finally */\r
+        body = asdl_seq_new(1, c->c_arena);\r
+        if (body == NULL)\r
+            return NULL;\r
+        asdl_seq_SET(body, 0, except_st);\r
+    }\r
+\r
+    /* must be a try ... finally (except clauses are in body, if any exist) */\r
+    assert(finally != NULL);\r
+    return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+/* with_item: test ['as' expr] */\r
+static stmt_ty\r
+ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content)\r
+{\r
+    expr_ty context_expr, optional_vars = NULL;\r
+\r
+    REQ(n, with_item);\r
+    context_expr = ast_for_expr(c, CHILD(n, 0));\r
+    if (!context_expr)\r
+        return NULL;\r
+    if (NCH(n) == 3) {\r
+        optional_vars = ast_for_expr(c, CHILD(n, 2));\r
+\r
+        if (!optional_vars) {\r
+            return NULL;\r
+        }\r
+        if (!set_context(c, optional_vars, Store, n)) {\r
+            return NULL;\r
+        }\r
+    }\r
+\r
+    return With(context_expr, optional_vars, content, LINENO(n),\r
+                n->n_col_offset, c->c_arena);\r
+}\r
+\r
+/* with_stmt: 'with' with_item (',' with_item)* ':' suite */\r
+static stmt_ty\r
+ast_for_with_stmt(struct compiling *c, const node *n)\r
+{\r
+    int i;\r
+    stmt_ty ret;\r
+    asdl_seq *inner;\r
+\r
+    REQ(n, with_stmt);\r
+\r
+    /* process the with items inside-out */\r
+    i = NCH(n) - 1;\r
+    /* the suite of the innermost with item is the suite of the with stmt */\r
+    inner = ast_for_suite(c, CHILD(n, i));\r
+    if (!inner)\r
+        return NULL;\r
+\r
+    for (;;) {\r
+        i -= 2;\r
+        ret = ast_for_with_item(c, CHILD(n, i), inner);\r
+        if (!ret)\r
+            return NULL;\r
+        /* was this the last item? */\r
+        if (i == 1)\r
+            break;\r
+        /* if not, wrap the result so far in a new sequence */\r
+        inner = asdl_seq_new(1, c->c_arena);\r
+        if (!inner)\r
+            return NULL;\r
+        asdl_seq_SET(inner, 0, ret);\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+static stmt_ty\r
+ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)\r
+{\r
+    /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */\r
+    PyObject *classname;\r
+    asdl_seq *bases, *s;\r
+\r
+    REQ(n, classdef);\r
+\r
+    if (!forbidden_check(c, n, STR(CHILD(n, 1))))\r
+            return NULL;\r
+\r
+    if (NCH(n) == 4) {\r
+        s = ast_for_suite(c, CHILD(n, 3));\r
+        if (!s)\r
+            return NULL;\r
+        classname = NEW_IDENTIFIER(CHILD(n, 1));\r
+        if (!classname)\r
+            return NULL;\r
+        return ClassDef(classname, NULL, s, decorator_seq, LINENO(n),\r
+                        n->n_col_offset, c->c_arena);\r
+    }\r
+    /* check for empty base list */\r
+    if (TYPE(CHILD(n,3)) == RPAR) {\r
+        s = ast_for_suite(c, CHILD(n,5));\r
+        if (!s)\r
+            return NULL;\r
+        classname = NEW_IDENTIFIER(CHILD(n, 1));\r
+        if (!classname)\r
+            return NULL;\r
+        return ClassDef(classname, NULL, s, decorator_seq, LINENO(n),\r
+                        n->n_col_offset, c->c_arena);\r
+    }\r
+\r
+    /* else handle the base class list */\r
+    bases = ast_for_class_bases(c, CHILD(n, 3));\r
+    if (!bases)\r
+        return NULL;\r
+\r
+    s = ast_for_suite(c, CHILD(n, 6));\r
+    if (!s)\r
+        return NULL;\r
+    classname = NEW_IDENTIFIER(CHILD(n, 1));\r
+    if (!classname)\r
+        return NULL;\r
+    return ClassDef(classname, bases, s, decorator_seq,\r
+                    LINENO(n), n->n_col_offset, c->c_arena);\r
+}\r
+\r
+static stmt_ty\r
+ast_for_stmt(struct compiling *c, const node *n)\r
+{\r
+    if (TYPE(n) == stmt) {\r
+        assert(NCH(n) == 1);\r
+        n = CHILD(n, 0);\r
+    }\r
+    if (TYPE(n) == simple_stmt) {\r
+        assert(num_stmts(n) == 1);\r
+        n = CHILD(n, 0);\r
+    }\r
+    if (TYPE(n) == small_stmt) {\r
+        n = CHILD(n, 0);\r
+        /* small_stmt: expr_stmt | print_stmt  | del_stmt | pass_stmt\r
+                     | flow_stmt | import_stmt | global_stmt | exec_stmt\r
+                     | assert_stmt\r
+        */\r
+        switch (TYPE(n)) {\r
+            case expr_stmt:\r
+                return ast_for_expr_stmt(c, n);\r
+            case print_stmt:\r
+                return ast_for_print_stmt(c, n);\r
+            case del_stmt:\r
+                return ast_for_del_stmt(c, n);\r
+            case pass_stmt:\r
+                return Pass(LINENO(n), n->n_col_offset, c->c_arena);\r
+            case flow_stmt:\r
+                return ast_for_flow_stmt(c, n);\r
+            case import_stmt:\r
+                return ast_for_import_stmt(c, n);\r
+            case global_stmt:\r
+                return ast_for_global_stmt(c, n);\r
+            case exec_stmt:\r
+                return ast_for_exec_stmt(c, n);\r
+            case assert_stmt:\r
+                return ast_for_assert_stmt(c, n);\r
+            default:\r
+                PyErr_Format(PyExc_SystemError,\r
+                             "unhandled small_stmt: TYPE=%d NCH=%d\n",\r
+                             TYPE(n), NCH(n));\r
+                return NULL;\r
+        }\r
+    }\r
+    else {\r
+        /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt\r
+                        | funcdef | classdef | decorated\r
+        */\r
+        node *ch = CHILD(n, 0);\r
+        REQ(n, compound_stmt);\r
+        switch (TYPE(ch)) {\r
+            case if_stmt:\r
+                return ast_for_if_stmt(c, ch);\r
+            case while_stmt:\r
+                return ast_for_while_stmt(c, ch);\r
+            case for_stmt:\r
+                return ast_for_for_stmt(c, ch);\r
+            case try_stmt:\r
+                return ast_for_try_stmt(c, ch);\r
+            case with_stmt:\r
+                return ast_for_with_stmt(c, ch);\r
+            case funcdef:\r
+                return ast_for_funcdef(c, ch, NULL);\r
+            case classdef:\r
+                return ast_for_classdef(c, ch, NULL);\r
+            case decorated:\r
+                return ast_for_decorated(c, ch);\r
+            default:\r
+                PyErr_Format(PyExc_SystemError,\r
+                             "unhandled small_stmt: TYPE=%d NCH=%d\n",\r
+                             TYPE(n), NCH(n));\r
+                return NULL;\r
+        }\r
+    }\r
+}\r
+\r
+static PyObject *\r
+parsenumber(struct compiling *c, const char *s)\r
+{\r
+        const char *end;\r
+        long x;\r
+        double dx;\r
+#ifndef WITHOUT_COMPLEX\r
+        Py_complex complex;\r
+        int imflag;\r
+#endif\r
+\r
+        assert(s != NULL);\r
+        errno = 0;\r
+        end = s + strlen(s) - 1;\r
+#ifndef WITHOUT_COMPLEX\r
+        imflag = *end == 'j' || *end == 'J';\r
+#endif\r
+        if (*end == 'l' || *end == 'L')\r
+                return PyLong_FromString((char *)s, (char **)0, 0);\r
+        x = PyOS_strtol((char *)s, (char **)&end, 0);\r
+        if (*end == '\0') {\r
+                if (errno != 0)\r
+                        return PyLong_FromString((char *)s, (char **)0, 0);\r
+                return PyInt_FromLong(x);\r
+        }\r
+        /* XXX Huge floats may silently fail */\r
+#ifndef WITHOUT_COMPLEX\r
+        if (imflag) {\r
+                complex.real = 0.;\r
+                complex.imag = PyOS_string_to_double(s, (char **)&end, NULL);\r
+                if (complex.imag == -1.0 && PyErr_Occurred())\r
+                        return NULL;\r
+                return PyComplex_FromCComplex(complex);\r
+        }\r
+        else\r
+#endif\r
+        {\r
+                dx = PyOS_string_to_double(s, NULL, NULL);\r
+                if (dx == -1.0 && PyErr_Occurred())\r
+                        return NULL;\r
+                return PyFloat_FromDouble(dx);\r
+        }\r
+}\r
+\r
+static PyObject *\r
+decode_utf8(struct compiling *c, const char **sPtr, const char *end, char* encoding)\r
+{\r
+#ifndef Py_USING_UNICODE\r
+        Py_FatalError("decode_utf8 should not be called in this build.");\r
+        return NULL;\r
+#else\r
+        PyObject *u, *v;\r
+        char *s, *t;\r
+        t = s = (char *)*sPtr;\r
+        /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */\r
+        while (s < end && (*s & 0x80)) s++;\r
+        *sPtr = s;\r
+        u = PyUnicode_DecodeUTF8(t, s - t, NULL);\r
+        if (u == NULL)\r
+                return NULL;\r
+        v = PyUnicode_AsEncodedString(u, encoding, NULL);\r
+        Py_DECREF(u);\r
+        return v;\r
+#endif\r
+}\r
+\r
+#ifdef Py_USING_UNICODE\r
+static PyObject *\r
+decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, const char *encoding)\r
+{\r
+        PyObject *v;\r
+        PyObject *u = NULL;\r
+        char *buf;\r
+        char *p;\r
+        const char *end;\r
+        if (encoding != NULL && strcmp(encoding, "iso-8859-1")) {\r
+                /* check for integer overflow */\r
+                if (len > PY_SIZE_MAX / 6)\r
+                        return NULL;\r
+                /* "<C3><A4>" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5\r
+                   "\รค" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */\r
+                u = PyString_FromStringAndSize((char *)NULL, len * 6);\r
+                if (u == NULL)\r
+                        return NULL;\r
+                p = buf = PyString_AsString(u);\r
+                end = s + len;\r
+                while (s < end) {\r
+                        if (*s == '\\') {\r
+                                *p++ = *s++;\r
+                                if (*s & 0x80) {\r
+                                        strcpy(p, "u005c");\r
+                                        p += 5;\r
+                                }\r
+                        }\r
+                        if (*s & 0x80) { /* XXX inefficient */\r
+                                PyObject *w;\r
+                                char *r;\r
+                                Py_ssize_t rn, i;\r
+                                w = decode_utf8(c, &s, end, "utf-32-be");\r
+                                if (w == NULL) {\r
+                                        Py_DECREF(u);\r
+                                        return NULL;\r
+                                }\r
+                                r = PyString_AsString(w);\r
+                                rn = PyString_Size(w);\r
+                                assert(rn % 4 == 0);\r
+                                for (i = 0; i < rn; i += 4) {\r
+                                        sprintf(p, "\\U%02x%02x%02x%02x",\r
+                                                r[i + 0] & 0xFF,\r
+                                                r[i + 1] & 0xFF,\r
+                                                r[i + 2] & 0xFF,\r
+                                                r[i + 3] & 0xFF);\r
+                                        p += 10;\r
+                                }\r
+                                Py_DECREF(w);\r
+                        } else {\r
+                                *p++ = *s++;\r
+                        }\r
+                }\r
+                len = p - buf;\r
+                s = buf;\r
+        }\r
+        if (rawmode)\r
+                v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL);\r
+        else\r
+                v = PyUnicode_DecodeUnicodeEscape(s, len, NULL);\r
+        Py_XDECREF(u);\r
+        return v;\r
+}\r
+#endif\r
+\r
+/* s is a Python string literal, including the bracketing quote characters,\r
+ * and r &/or u prefixes (if any), and embedded escape sequences (if any).\r
+ * parsestr parses it, and returns the decoded Python string object.\r
+ */\r
+static PyObject *\r
+parsestr(struct compiling *c, const node *n, const char *s)\r
+{\r
+        size_t len, i;\r
+        int quote = Py_CHARMASK(*s);\r
+        int rawmode = 0;\r
+        int need_encoding;\r
+        int unicode = c->c_future_unicode;\r
+        int bytes = 0;\r
+\r
+        if (isalpha(quote) || quote == '_') {\r
+                if (quote == 'u' || quote == 'U') {\r
+                        quote = *++s;\r
+                        unicode = 1;\r
+                }\r
+                if (quote == 'b' || quote == 'B') {\r
+                        quote = *++s;\r
+                        unicode = 0;\r
+                        bytes = 1;\r
+                }\r
+                if (quote == 'r' || quote == 'R') {\r
+                        quote = *++s;\r
+                        rawmode = 1;\r
+                }\r
+        }\r
+        if (quote != '\'' && quote != '\"') {\r
+                PyErr_BadInternalCall();\r
+                return NULL;\r
+        }\r
+        s++;\r
+        len = strlen(s);\r
+        if (len > INT_MAX) {\r
+                PyErr_SetString(PyExc_OverflowError,\r
+                                "string to parse is too long");\r
+                return NULL;\r
+        }\r
+        if (s[--len] != quote) {\r
+                PyErr_BadInternalCall();\r
+                return NULL;\r
+        }\r
+        if (len >= 4 && s[0] == quote && s[1] == quote) {\r
+                s += 2;\r
+                len -= 2;\r
+                if (s[--len] != quote || s[--len] != quote) {\r
+                        PyErr_BadInternalCall();\r
+                        return NULL;\r
+                }\r
+        }\r
+        if (Py_Py3kWarningFlag && bytes) {\r
+            for (i = 0; i < len; i++) {\r
+                if ((unsigned char)s[i] > 127) {\r
+                    if (!ast_warn(c, n,\r
+                        "non-ascii bytes literals not supported in 3.x"))\r
+                        return NULL;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+#ifdef Py_USING_UNICODE\r
+        if (unicode || Py_UnicodeFlag) {\r
+                return decode_unicode(c, s, len, rawmode, c->c_encoding);\r
+        }\r
+#endif\r
+        need_encoding = (c->c_encoding != NULL &&\r
+                         strcmp(c->c_encoding, "utf-8") != 0 &&\r
+                         strcmp(c->c_encoding, "iso-8859-1") != 0);\r
+        if (rawmode || strchr(s, '\\') == NULL) {\r
+                if (need_encoding) {\r
+#ifndef Py_USING_UNICODE\r
+                        /* This should not happen - we never see any other\r
+                           encoding. */\r
+                        Py_FatalError(\r
+                            "cannot deal with encodings in this build.");\r
+#else\r
+                        PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL);\r
+                        if (u == NULL)\r
+                                return NULL;\r
+                        v = PyUnicode_AsEncodedString(u, c->c_encoding, NULL);\r
+                        Py_DECREF(u);\r
+                        return v;\r
+#endif\r
+                } else {\r
+                        return PyString_FromStringAndSize(s, len);\r
+                }\r
+        }\r
+\r
+        return PyString_DecodeEscape(s, len, NULL, unicode,\r
+                                     need_encoding ? c->c_encoding : NULL);\r
+}\r
+\r
+/* Build a Python string object out of a STRING atom.  This takes care of\r
+ * compile-time literal catenation, calling parsestr() on each piece, and\r
+ * pasting the intermediate results together.\r
+ */\r
+static PyObject *\r
+parsestrplus(struct compiling *c, const node *n)\r
+{\r
+        PyObject *v;\r
+        int i;\r
+        REQ(CHILD(n, 0), STRING);\r
+        if ((v = parsestr(c, n, STR(CHILD(n, 0)))) != NULL) {\r
+                /* String literal concatenation */\r
+                for (i = 1; i < NCH(n); i++) {\r
+                        PyObject *s;\r
+                        s = parsestr(c, n, STR(CHILD(n, i)));\r
+                        if (s == NULL)\r
+                                goto onError;\r
+                        if (PyString_Check(v) && PyString_Check(s)) {\r
+                                PyString_ConcatAndDel(&v, s);\r
+                                if (v == NULL)\r
+                                    goto onError;\r
+                        }\r
+#ifdef Py_USING_UNICODE\r
+                        else {\r
+                                PyObject *temp = PyUnicode_Concat(v, s);\r
+                                Py_DECREF(s);\r
+                                Py_DECREF(v);\r
+                                v = temp;\r
+                                if (v == NULL)\r
+                                    goto onError;\r
+                        }\r
+#endif\r
+                }\r
+        }\r
+        return v;\r
+\r
+ onError:\r
+        Py_XDECREF(v);\r
+        return NULL;\r
+}\r