17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parsermodule.c
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Institute and State University, Blacksburg, Virginia, USA.
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Amsterdam, The Netherlands.  Copying is permitted under the terms
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  associated with the main Python distribution, with the additional
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  restriction that this additional notice be included and maintained
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  on all distributed copies.
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This module serves to replace the original parser module written
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  by Guido.  The functionality is not matched precisely, but the
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  original may be implemented on top of this.  This is desirable
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  since the source of the text to be parsed is now divorced from
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  this interface.
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Unlike the prior interface, the ability to give a parse tree
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  produced by Python code as a tuple to the compiler is enabled by
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  this module.  See the documentation for more details.
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  I've added some annotations that help with the lint code-checking
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  program, but they're not complete by a long shot.  The real errors
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  that lint detects are gone, but there are still warnings with
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Py_[X]DECREF() and Py_[X]INCREF() macros.  The lint annotations
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  look like "NOTE(...)".
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"                     /* general Python API             */
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python-ast.h"                 /* mod_ty */
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "graminit.h"                   /* symbols defined in the grammar */
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "node.h"                       /* internal parser structure      */
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "errcode.h"                    /* error codes for PyNode_*()     */
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "token.h"                      /* token definitions              */
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "grammar.h"
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "parsetok.h"
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                        /* ISTERMINAL() / ISNONTERMINAL() */
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "compile.h"
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef Yield
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "ast.h"
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "pyarena.h"
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielextern grammar _PyParser_Grammar; /* From graminit.c */
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef lint
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <note.h>
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define NOTE(x)
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  String constants used to initialize module attributes.
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic char parser_copyright_string[] =
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielUniversity, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVirginia, USA.  Portions copyright 1991-1995 by Stichting Mathematisch\n\
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielCentrum, Amsterdam, The Netherlands.";
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(parser_doc_string,
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"This is an interface to Python's internal parser.");
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic char parser_version_string[] = "0.5";
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef PyObject* (*SeqMaker) (Py_ssize_t length);
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef int (*SeqInserter) (PyObject* sequence,
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            Py_ssize_t index,
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            PyObject* element);
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  The function below is copyrighted by Stichting Mathematisch Centrum.  The
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  original copyright statement is included below, and continues to apply
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  in full to the function immediately following.  All other material is
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Institute and State University.  Changes were made to comply with the
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  new naming conventions.  Added arguments to provide support for creating
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  lists as well as tuples, and optionally including the line numbers.
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnode2tuple(node *n,                     /* node to convert               */
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           SeqMaker mkseq,              /* create sequence               */
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           SeqInserter addelem,         /* func. to add elem. in seq.    */
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           int lineno,                  /* include line numbers?         */
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           int col_offset)              /* include column offsets?       */
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (n == NULL) {
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(Py_None);
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (Py_None);
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ISNONTERMINAL(TYPE(n))) {
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i;
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *v;
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *w;
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (v == NULL)
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (v);
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        w = PyInt_FromLong(TYPE(n));
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (w == NULL) {
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(v);
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return ((PyObject*) NULL);
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) addelem(v, 0, w);
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 0; i < NCH(n); i++) {
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset);
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (w == NULL) {
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(v);
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return ((PyObject*) NULL);
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (void) addelem(v, i+1, w);
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(n) == encoding_decl)
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (void) addelem(v, i+1, PyString_FromString(STR(n)));
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (v);
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (ISTERMINAL(TYPE(n))) {
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *result = mkseq(2 + lineno + col_offset);
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result != NULL) {
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (void) addelem(result, 1, PyString_FromString(STR(n)));
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (lineno == 1)
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (col_offset == 1)
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void) addelem(result, 3, PyInt_FromLong(n->n_col_offset));
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (result);
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_SystemError,
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "unrecognized parse tree node type");
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return ((PyObject*) NULL);
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  End of material copyrighted by Stichting Mathematisch Centrum.
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  There are two types of intermediate objects we're interested in:
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  'eval' and 'exec' types.  These constants can be used in the st_type
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  field of the object type to identify which any given object represents.
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  These should probably go in an external header to allow other extensions
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  to use them, but then, we really should be using C++ too.  ;-)
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyST_EXPR  1
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyST_SUITE 2
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  These are the internal objects and definitions required to implement the
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  ST type.  Most of the internal names are more reminiscent of the 'old'
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  naming style, but the code uses the new naming convention.
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_error = 0;
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct {
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_HEAD                       /* standard object header           */
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    node* st_node;                      /* the node* returned by the parser */
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int   st_type;                      /* EXPR or SUITE ?                  */
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyCompilerFlags st_flags;           /* Parser and compiler flags        */
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} PyST_Object;
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void parser_free(PyST_Object *st);
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_sizeof(PyST_Object *, void *);
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int parser_compare(PyST_Object *left, PyST_Object *right);
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *parser_getattr(PyObject *self, char *name);
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *);
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *);
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *);
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *);
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *);
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_methods[] = {
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"compile",         (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Compile this ST object into a code object.")},
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"isexpr",          (PyCFunction)parser_isexpr,     PUBLIC_METHOD_TYPE,
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Determines if this ST object was created from an expression.")},
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"issuite",         (PyCFunction)parser_issuite,    PUBLIC_METHOD_TYPE,
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Determines if this ST object was created from a suite.")},
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"tolist",          (PyCFunction)parser_st2list,    PUBLIC_METHOD_TYPE,
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a list-tree representation of this ST.")},
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"totuple",         (PyCFunction)parser_st2tuple,   PUBLIC_METHOD_TYPE,
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a tuple-tree representation of this ST.")},
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"__sizeof__",      (PyCFunction)parser_sizeof,     METH_NOARGS,
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Returns size in memory, in bytes.")},
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL, 0, NULL}
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyTypeObject PyST_Type = {
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    "parser.st",                        /* tp_name              */
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (int) sizeof(PyST_Object),          /* tp_basicsize         */
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_itemsize          */
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (destructor)parser_free,            /* tp_dealloc           */
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_print             */
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    parser_getattr,                     /* tp_getattr           */
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_setattr           */
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (cmpfunc)parser_compare,            /* tp_compare           */
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_repr              */
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_as_number         */
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_as_sequence       */
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_as_mapping        */
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_hash              */
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_call              */
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_str               */
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_getattro          */
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_setattro          */
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Functions to access object as input/output buffer */
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_as_buffer         */
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TPFLAGS_DEFAULT,                 /* tp_flags             */
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* __doc__ */
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    "Intermediate representation of a Python parse tree.",
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_traverse */
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_clear */
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_richcompare */
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_weaklistoffset */
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_iter */
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                                  /* tp_iternext */
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    parser_methods,                     /* tp_methods */
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};  /* PyST_Type */
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_compare_nodes(node *left, node *right)
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (TYPE(left) < TYPE(right))
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (-1);
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (TYPE(right) < TYPE(left))
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (1);
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ISTERMINAL(TYPE(left)))
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (strcmp(STR(left), STR(right)));
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (NCH(left) < NCH(right))
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (-1);
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (NCH(right) < NCH(left))
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (1);
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (j = 0; j < NCH(left); ++j) {
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (v != 0)
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (v);
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (0);
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  int parser_compare(PyST_Object* left, PyST_Object* right)
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Comparison function used by the Python operators ==, !=, <, >, <=, >=
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This really just wraps a call to parser_compare_nodes() with some easy
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  checks and protection code.
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_compare(PyST_Object *left, PyST_Object *right)
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (left == right)
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((left == 0) || (right == 0))
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (-1);
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (parser_compare_nodes(left->st_node, right->st_node));
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parser_newstobject(node* st)
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Allocates a new Python object representing an ST.  This is simply the
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  'wrapper' object that holds a node* and allows it to be passed around in
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Python code.
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_newstobject(node *st, int type)
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (o != 0) {
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        o->st_node = st;
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        o->st_type = type;
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        o->st_flags.cf_flags = 0;
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyNode_Free(st);
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ((PyObject*)o);
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  void parser_free(PyST_Object* st)
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This is called by a del statement that reduces the reference count to 0.
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_free(PyST_Object *st)
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyNode_Free(st->st_node);
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_Del(st);
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This provides conversion from a node* to a tuple object that can be
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  returned to the Python-level caller.  The ST object is not modified.
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *line_option = 0;
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *col_option = 0;
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *res = 0;
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"ast", "line_info", "col_info", NULL};
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL) {
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords,
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &PyST_Type, &self, &line_option,
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &col_option);
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:totuple", &keywords[1],
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &line_option, &col_option);
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok != 0) {
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int lineno = 0;
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int col_offset = 0;
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (line_option != NULL) {
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            lineno = PyObject_IsTrue(line_option);
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (lineno < 0)
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (col_option != NULL) {
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            col_offset = PyObject_IsTrue(col_option);
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (col_offset < 0)
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  Convert ST into a tuple representation.  Use Guido's function,
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  since it's known to work already.
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = node2tuple(((PyST_Object*)self)->st_node,
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         PyTuple_New, PyTuple_SetItem, lineno, col_offset);
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_ast2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_WarnPy3k("ast2tuple is removed in 3.x; use st2tuple", 1) < 0)
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return parser_st2tuple(self, args, kw);
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This provides conversion from a node* to a list object that can be
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  returned to the Python-level caller.  The ST object is not modified.
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *line_option = 0;
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *col_option = 0;
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *res = 0;
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"ast", "line_info", "col_info", NULL};
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords,
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &PyST_Type, &self, &line_option,
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &col_option);
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:tolist", &keywords[1],
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &line_option, &col_option);
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok) {
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int lineno = 0;
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int col_offset = 0;
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (line_option != 0) {
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            lineno = PyObject_IsTrue(line_option);
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (lineno < 0)
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (col_option != 0) {
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            col_offset = PyObject_IsTrue(col_option);
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (col_offset < 0)
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  Convert ST into a tuple representation.  Use Guido's function,
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  since it's known to work already.
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = node2tuple(self->st_node,
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         PyList_New, PyList_SetItem, lineno, col_offset);
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_ast2list(PyST_Object *self, PyObject *args, PyObject *kw)
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_WarnPy3k("ast2list is removed in 3.x; use st2list", 1) < 0)
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return parser_st2list(self, args, kw);
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parser_compilest(PyObject* self, PyObject* args)
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This function creates code objects from the parse tree represented by
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the passed-in data object.  An optional file name is passed in as well.
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject*     res = 0;
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyArena*      arena;
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    mod_ty        mod;
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char*         str = "<syntax-tree>";
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"ast", "filename", NULL};
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &PyST_Type, &self, &str);
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &str);
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok) {
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        arena = PyArena_New();
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (arena) {
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena);
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           if (mod) {
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena);
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           }
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           PyArena_Free(arena);
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_compileast(PyST_Object *self, PyObject *args, PyObject *kw)
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_WarnPy3k("compileast is removed in 3.x; use compilest", 1) < 0)
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return parser_compilest(self, args, kw);
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  PyObject* parser_isexpr(PyObject* self, PyObject* args)
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  PyObject* parser_issuite(PyObject* self, PyObject* args)
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Checks the passed-in ST object to determine if it is an expression or
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  a statement suite, respectively.  The return is a Python truth value.
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject* res = 0;
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"ast", NULL};
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &PyST_Type, &self);
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok) {
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Check to see if the ST represents an expression or not. */
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(res);
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject* res = 0;
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"ast", NULL};
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         &PyST_Type, &self);
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok) {
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Check to see if the ST represents an expression or not. */
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(res);
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_getattr(PyObject *self, char *name)
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (Py_FindMethod(parser_methods, self, name));
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  err_string(char* message)
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Sets the error string for an exception of type ParserError.
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielerr_string(char *message)
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyErr_SetString(parser_error, message);
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  PyObject* parser_do_parse(PyObject* args, int type)
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Internal function to actually execute the parse and return the result if
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  successful or set an exception if not.
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char*     string = 0;
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject* res    = 0;
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int flags        = 0;
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    perrdetail err;
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"source", NULL};
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL,
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                       &_PyParser_Grammar,
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                      (type == PyST_EXPR)
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                      ? eval_input : file_input,
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                      &err, &flags);
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (n) {
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = parser_newstobject(n, type);
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res)
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK;
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyParser_SetError(&err);
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  PyObject* parser_expr(PyObject* self, PyObject* args)
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  PyObject* parser_suite(PyObject* self, PyObject* args)
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  External interfaces to the parser itself.  Which is called determines if
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the parser attempts to recognize an expression ('eval' form) or statement
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  suite ('exec' form).  The real work is done by parser_do_parse() above.
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NOTE(ARGUNUSED(self))
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NOTE(ARGUNUSED(self))
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  This is the messy part of the code.  Conversion from a tuple to an ST
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  object requires that the input tuple be valid without having to rely on
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  catching an exception from the compiler.  This is done to allow the
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  compiler itself to remain fast, since most of its input will come from
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the parser directly, and therefore be known to be syntactically correct.
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This validation is done to ensure that we don't core dump the compile
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  phase, returning an exception instead.
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Two aspects can be broken out in this code:  creating a node tree from
6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the tuple passed in, and verifying that it is indeed valid.  It may be
6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  advantageous to expand the number of ST types to include funcdefs and
6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  lambdadefs to take advantage of the optimizer, recognizing those STs
6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  here.  They are not necessary, and not quite as useful in a raw form.
6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  For now, let's get expressions and suites working reliably.
6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic node* build_node_tree(PyObject *tuple);
6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int   validate_expr_tree(node *tree);
6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int   validate_file_input(node *tree);
6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int   validate_encoding_decl(node *tree);
6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  PyObject* parser_tuple2st(PyObject* self, PyObject* args)
6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This is the public function, called from the Python code.  It receives a
6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  single tuple object from the caller, and creates an ST object if the
6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  tuple can be validated.  It does this by checking the first code of the
6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  tuple, and, if acceptable, builds the internal representation.  If this
6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  step succeeds, the internal representation is validated as fully as
6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  possible with the various validate_*() routines defined below.
6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  This function must be changed if support is to be added for PyST_FRAGMENT
6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  ST objects.
6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NOTE(ARGUNUSED(self))
6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *st = 0;
6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *tuple;
6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    node *tree;
6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *keywords[] = {"sequence", NULL};
6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &tuple))
6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PySequence_Check(tuple)) {
6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "sequence2st() requires a single sequence argument");
6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*
6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  Convert the tree to the internal form before checking it.
6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    tree = build_node_tree(tuple);
6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (tree != 0) {
6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int start_sym = TYPE(tree);
6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (start_sym == eval_input) {
6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*  Might be an eval form.  */
6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (validate_expr_tree(tree))
6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                st = parser_newstobject(tree, PyST_EXPR);
6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else
6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyNode_Free(tree);
6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (start_sym == file_input) {
6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*  This looks like an exec form so far.  */
6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (validate_file_input(tree))
6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                st = parser_newstobject(tree, PyST_SUITE);
6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else
6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyNode_Free(tree);
6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (start_sym == encoding_decl) {
6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* This looks like an encoding_decl so far. */
6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (validate_encoding_decl(tree))
6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                st = parser_newstobject(tree, PyST_SUITE);
6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else
6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyNode_Free(tree);
6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*  This is a fragment, at best. */
6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyNode_Free(tree);
6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("parse tree does not use a valid start symbol");
6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*  Make sure we raise an exception on all errors.  We should never
7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  get this, but we'd do well to be sure something is done.
7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (st == NULL && !PyErr_Occurred())
7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("unspecified ST error occurred");
7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return st;
7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_tuple2ast(PyST_Object *self, PyObject *args, PyObject *kw)
7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_WarnPy3k("tuple2ast is removed in 3.x; use tuple2st", 1) < 0)
7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return parser_tuple2st(self, args, kw);
7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser_sizeof(PyST_Object *st, void *unused)
7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t res;
7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    res = sizeof(PyST_Object) + _PyNode_SizeOf(st->st_node);
7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyLong_FromSsize_t(res);
7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  node* build_node_children()
7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Iterate across the children of the current non-terminal node and build
7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  their structures.  If successful, return the root of this portion of
7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the tree, otherwise, 0.  Any required exception will be specified already,
7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  and no memory will have been deallocated.
7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic node*
7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbuild_node_children(PyObject *tuple, node *root, int *line_num)
7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t len = PyObject_Size(tuple);
7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t i;
7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int  err;
7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 1; i < len; ++i) {
7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* elem must always be a sequence, however simple */
7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject* elem = PySequence_GetItem(tuple, i);
7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int ok = elem != NULL;
7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        long  type = 0;
7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        char *strn = 0;
7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok)
7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = PySequence_Check(elem);
7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok) {
7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *temp = PySequence_GetItem(elem, 0);
7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (temp == NULL)
7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = 0;
7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = PyInt_Check(temp);
7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (ok)
7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    type = PyInt_AS_LONG(temp);
7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(temp);
7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!ok) {
7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *err = Py_BuildValue("os", elem,
7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                          "Illegal node construct.");
7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetObject(parser_error, err);
7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(err);
7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(elem);
7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (0);
7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ISTERMINAL(type)) {
7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_ssize_t len = PyObject_Size(elem);
7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *temp;
7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((len != 2) && (len != 3)) {
7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("terminal nodes must have 2 or 3 entries");
7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return 0;
7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            temp = PySequence_GetItem(elem, 1);
7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (temp == NULL)
7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return 0;
7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (!PyString_Check(temp)) {
7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyErr_Format(parser_error,
7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             "second item in terminal node must be a string,"
7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             " found %s",
7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             Py_TYPE(temp)->tp_name);
7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(temp);
7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return 0;
7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (len == 3) {
7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyObject *o = PySequence_GetItem(elem, 2);
7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (o != NULL) {
7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (PyInt_Check(o))
7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        *line_num = PyInt_AS_LONG(o);
7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    else {
7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        PyErr_Format(parser_error,
7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     "third item in terminal node must be an"
7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     " integer, found %s",
7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     Py_TYPE(temp)->tp_name);
8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        Py_DECREF(o);
8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        Py_DECREF(temp);
8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        return 0;
8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    Py_DECREF(o);
8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            len = PyString_GET_SIZE(temp) + 1;
8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strn = (char *)PyObject_MALLOC(len);
8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (strn != NULL)
8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void) memcpy(strn, PyString_AS_STRING(temp), len);
8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(temp);
8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (!ISNONTERMINAL(type)) {
8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  It has to be one or the other; this is an error.
8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  Raise an exception.
8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetObject(parser_error, err);
8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(err);
8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(elem);
8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (0);
8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err = PyNode_AddChild(root, type, strn, *line_num, 0);
8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (err == E_NOMEM) {
8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject_FREE(strn);
8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (node *) PyErr_NoMemory();
8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (err == E_OVERFLOW) {
8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject_FREE(strn);
8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            "unsupported number of child nodes");
8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ISNONTERMINAL(type)) {
8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            node* new_child = CHILD(root, i - 1);
8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (new_child != build_node_children(elem, new_child, line_num)) {
8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_XDECREF(elem);
8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return (0);
8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (type == NEWLINE) {     /* It's true:  we increment the     */
8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ++(*line_num);              /* line number *after* the newline! */
8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(elem);
8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return root;
8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic node*
8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbuild_node_tree(PyObject *tuple)
8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    node* res = 0;
8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *temp = PySequence_GetItem(tuple, 0);
8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    long num = -1;
8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (temp != NULL)
8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        num = PyInt_AsLong(temp);
8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(temp);
8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ISTERMINAL(num)) {
8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  The tuple is simple, but it doesn't start with a start symbol.
8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  Raise an exception now and be done with it.
8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tuple = Py_BuildValue("os", tuple,
8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    "Illegal syntax-tree; cannot start with terminal symbol.");
8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetObject(parser_error, tuple);
8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(tuple);
8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (ISNONTERMINAL(num)) {
8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  Not efficient, but that can be handled later.
8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int line_num = 0;
8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *encoding = NULL;
8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (num == encoding_decl) {
8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            encoding = PySequence_GetItem(tuple, 2);
8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* tuple isn't borrowed anymore here, need to DECREF */
8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            tuple = PySequence_GetSlice(tuple, 0, 2);
8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = PyNode_New(num);
8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res != NULL) {
8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res != build_node_children(tuple, res, &line_num)) {
8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyNode_Free(res);
8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = NULL;
8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && encoding) {
8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_ssize_t len;
8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                len = PyString_GET_SIZE(encoding) + 1;
8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res->n_str = (char *)PyObject_MALLOC(len);
8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (res->n_str != NULL)
8967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    (void) memcpy(res->n_str, PyString_AS_STRING(encoding), len);
8977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(encoding);
8987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(tuple);
8997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
9017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
9037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  The tuple is illegal -- if the number is neither TERMINAL nor
9047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  NONTERMINAL, we can't use it.  Not sure the implementation
9057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  allows this condition, but the API doesn't preclude it.
9067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
9077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *err = Py_BuildValue("os", tuple,
9087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                      "Illegal component tuple.");
9097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetObject(parser_error, err);
9107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(err);
9117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
9147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
9157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
9187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  Validation routines used within the validation section:
9197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
9207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int validate_terminal(node *terminal, int type, char *string);
9217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_ampersand(ch)  validate_terminal(ch,      AMPER, "&")
9237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
9247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_colon(ch)      validate_terminal(ch,      COLON, ":")
9257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_comma(ch)      validate_terminal(ch,      COMMA, ",")
9267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_dedent(ch)     validate_terminal(ch,     DEDENT, "")
9277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_equal(ch)      validate_terminal(ch,      EQUAL, "=")
9287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_indent(ch)     validate_terminal(ch,     INDENT, (char*)NULL)
9297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_lparen(ch)     validate_terminal(ch,       LPAR, "(")
9307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_newline(ch)    validate_terminal(ch,    NEWLINE, (char*)NULL)
9317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_rparen(ch)     validate_terminal(ch,       RPAR, ")")
9327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_semi(ch)       validate_terminal(ch,       SEMI, ";")
9337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_star(ch)       validate_terminal(ch,       STAR, "*")
9347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_vbar(ch)       validate_terminal(ch,       VBAR, "|")
9357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
9367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_dot(ch)        validate_terminal(ch,        DOT, ".")
9377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_at(ch)         validate_terminal(ch,         AT, "@")
9387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define validate_name(ch, str)  validate_terminal(ch,       NAME, str)
9397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define VALIDATER(n)    static int validate_##n(node *tree)
9417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(node);                VALIDATER(small_stmt);
9437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(class);               VALIDATER(node);
9447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(parameters);          VALIDATER(suite);
9457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(testlist);            VALIDATER(varargslist);
9467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(fpdef);               VALIDATER(fplist);
9477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(stmt);                VALIDATER(simple_stmt);
9487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(expr_stmt);           VALIDATER(power);
9497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(print_stmt);          VALIDATER(del_stmt);
9507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(return_stmt);         VALIDATER(list_iter);
9517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(raise_stmt);          VALIDATER(import_stmt);
9527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(import_name);         VALIDATER(import_from);
9537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(global_stmt);         VALIDATER(list_if);
9547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(assert_stmt);         VALIDATER(list_for);
9557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(exec_stmt);           VALIDATER(compound_stmt);
9567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(while);               VALIDATER(for);
9577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(try);                 VALIDATER(except_clause);
9587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(test);                VALIDATER(and_test);
9597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(not_test);            VALIDATER(comparison);
9607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(comp_op);             VALIDATER(expr);
9617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(xor_expr);            VALIDATER(and_expr);
9627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(shift_expr);          VALIDATER(arith_expr);
9637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(term);                VALIDATER(factor);
9647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(atom);                VALIDATER(lambdef);
9657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(trailer);             VALIDATER(subscript);
9667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(subscriptlist);       VALIDATER(sliceop);
9677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(exprlist);            VALIDATER(dictorsetmaker);
9687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(arglist);             VALIDATER(argument);
9697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(listmaker);           VALIDATER(yield_stmt);
9707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(testlist1);           VALIDATER(comp_for);
9717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(comp_iter);           VALIDATER(comp_if);
9727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(testlist_comp);       VALIDATER(yield_expr);
9737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(yield_or_testlist);   VALIDATER(or_test);
9747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVALIDATER(old_test);            VALIDATER(old_lambdef);
9757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef VALIDATER
9777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define is_even(n)      (((n) & 1) == 0)
9797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define is_odd(n)       (((n) & 1) == 1)
9807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
9837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_ntype(node *n, int t)
9847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
9857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (TYPE(n) != t) {
9867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error, "Expected node type %d, got %d.",
9877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     t, TYPE(n));
9887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
9897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 1;
9917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
9927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  Verifies that the number of child nodes is exactly 'num', raising
9957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  an exception if it isn't.  The exception message does not indicate
9967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  the exact number of nodes, allowing this to be used to raise the
9977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  "right" exception when the wrong number of nodes is present in a
9987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  specific variant of a statement's syntax.  This is commonly used
9997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  in that fashion.
10007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
10017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
10027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_numnodes(node *n, int num, const char *const name)
10037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (NCH(n) != num) {
10057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
10067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Illegal number of children for %s node.", name);
10077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
10087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 1;
10107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
10147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_terminal(node *terminal, int type, char *string)
10157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(terminal, type)
10177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
10187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred()) {
10207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
10217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Illegal terminal: expected \"%s\"", string);
10227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
10247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  X (',' X) [',']
10287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
10297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
10307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
10317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        const char *const name)
10327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
10347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (nch && validate_ntype(tree, ntype)
10357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && vfunc(CHILD(tree, 0)));
10367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
10387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 1, name);
10397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
10407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (is_even(nch))
10417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_comma(CHILD(tree, --nch));
10427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && nch > 1) {
10437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            int pos = 1;
10447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for ( ; res && pos < nch; pos += 2)
10457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_comma(CHILD(tree, pos))
10467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && vfunc(CHILD(tree, pos + 1)));
10477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
10487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
10507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  validate_class()
10547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
10557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  classdef:
10567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      'class' NAME ['(' testlist ')'] ':' suite
10577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
10587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
10597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_class(node *tree)
10607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
10627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, classdef) &&
10637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ((nch == 4) || (nch == 6) || (nch == 7)));
10647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
10667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "class")
10677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, 1), NAME)
10687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, nch - 2))
10697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, nch - 1)));
10707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
10727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 4, "class");
10737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
10767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch == 7) {
10777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = ((validate_lparen(CHILD(tree, 2)) &&
10787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        validate_testlist(CHILD(tree, 3)) &&
10797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        validate_rparen(CHILD(tree, 4))));
10807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
10817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch == 6) {
10827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_lparen(CHILD(tree,2)) &&
10837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        validate_rparen(CHILD(tree,3)));
10847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
10857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
10877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  if_stmt:
10917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
10927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
10937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
10947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_if(node *tree)
10957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
10977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, if_stmt)
10987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch >= 4)
10997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "if")
11007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 1))
11017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 2))
11027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 3)));
11037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && ((nch % 4) == 3)) {
11057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  ... 'else' ':' suite  */
11067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, nch - 3), "else")
11077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, nch - 2))
11087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, nch - 1)));
11097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        nch -= 3;
11107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (!res && !PyErr_Occurred())
11127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 4, "if");
11137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((nch % 4) != 0)
11147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Will catch the case for nch < 4 */
11157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 0, "if");
11167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (res && (nch > 4)) {
11177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  ... ('elif' test ':' suite)+ ...  */
11187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int j = 4;
11197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while ((j < nch) && res) {
11207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_name(CHILD(tree, j), "elif")
11217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_colon(CHILD(tree, j + 2))
11227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_test(CHILD(tree, j + 1))
11237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_suite(CHILD(tree, j + 3)));
11247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            j += 4;
11257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
11267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
11287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  parameters:
11327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      '(' [varargslist] ')'
11337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
11347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
11357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
11367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_parameters(node *tree)
11377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
11397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
11407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
11427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_lparen(CHILD(tree, 0))
11437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_rparen(CHILD(tree, nch - 1)));
11447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && (nch == 3))
11457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_varargslist(CHILD(tree, 1));
11467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
11487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 2, "parameters");
11497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
11517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  validate_suite()
11557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
11567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  suite:
11577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      simple_stmt
11587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    | NEWLINE INDENT stmt+ DEDENT
11597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
11607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
11617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_suite(node *tree)
11627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
11647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
11657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 1))
11677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_simple_stmt(CHILD(tree, 0));
11687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (res) {
11697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  NEWLINE INDENT stmt+ DEDENT  */
11707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_newline(CHILD(tree, 0))
11717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_indent(CHILD(tree, 1))
11727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_stmt(CHILD(tree, 2))
11737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_dedent(CHILD(tree, nch - 1)));
11747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && (nch > 4)) {
11767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            int i = 3;
11777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            --nch;                      /* forget the DEDENT     */
11787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for ( ; res && (i < nch); ++i)
11797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_stmt(CHILD(tree, i));
11807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
11817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch < 4)
11827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_numnodes(tree, 4, "suite");
11837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
11857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
11897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_testlist(node *tree)
11907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, testlist,
11927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_test, "testlist"));
11937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
11977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_testlist1(node *tree)
11987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, testlist1,
12007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_test, "testlist1"));
12017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
12057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_testlist_safe(node *tree)
12067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, testlist_safe,
12087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_old_test, "testlist_safe"));
12097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* '*' NAME [',' '**' NAME] | '**' NAME
12137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
12147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
12157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_varargslist_trailer(node *tree, int start)
12167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
12187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = 0;
12197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int sym;
12207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch <= start) {
12227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("expected variable argument trailer for varargslist");
12237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
12247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sym = TYPE(CHILD(tree, start));
12267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (sym == STAR) {
12277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
12287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  ('*' NAME [',' '**' NAME]
12297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
12307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch-start == 2)
12317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_name(CHILD(tree, start+1), NULL);
12327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch-start == 5)
12337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_name(CHILD(tree, start+1), NULL)
12347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_comma(CHILD(tree, start+2))
12357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_doublestar(CHILD(tree, start+3))
12367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, start+4), NULL));
12377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (sym == DOUBLESTAR) {
12397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
12407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  '**' NAME
12417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
12427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch-start == 2)
12437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_name(CHILD(tree, start+1), NULL);
12447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res)
12467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("illegal variable argument trailer for varargslist");
12477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
12487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  validate_varargslist()
12527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
12537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  varargslist:
12547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      (fpdef ['=' test] ',')*
12557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *           ('*' NAME [',' '**' NAME]
12567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *         | '**' NAME)
12577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    | fpdef ['=' test] (',' fpdef ['=' test])* [',']
12587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
12597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
12607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
12617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_varargslist(node *tree)
12627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
12647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, varargslist) && (nch != 0);
12657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int sym;
12667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res)
12687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
12697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch < 1) {
12707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("varargslist missing child nodes");
12717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
12727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sym = TYPE(CHILD(tree, 0));
12747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (sym == STAR || sym == DOUBLESTAR)
12757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* whole thing matches:
12767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *      '*' NAME [',' '**' NAME] | '**' NAME
12777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
12787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_varargslist_trailer(tree, 0);
12797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (sym == fpdef) {
12807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i = 0;
12817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sym = TYPE(CHILD(tree, nch-1));
12837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (sym == NAME) {
12847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
12857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *   (fpdef ['=' test] ',')+
12867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *       ('*' NAME [',' '**' NAME]
12877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *     | '**' NAME)
12887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
12897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* skip over (fpdef ['=' test] ',')+ */
12907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (res && (i+2 <= nch)) {
12917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_fpdef(CHILD(tree, i));
12927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ++i;
12937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
12947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    res = (validate_equal(CHILD(tree, i))
12957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           && validate_test(CHILD(tree, i+1)));
12967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (res)
12977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        i += 2;
12987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
12997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (res && i < nch) {
13007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    res = validate_comma(CHILD(tree, i));
13017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    ++i;
13027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (res && i < nch
13037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        && (TYPE(CHILD(tree, i)) == DOUBLESTAR
13047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            || TYPE(CHILD(tree, i)) == STAR))
13057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        break;
13067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
13077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
13087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* ... '*' NAME [',' '**' NAME] | '**' NAME
13097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             * i --^^^
13107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
13117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res)
13127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_varargslist_trailer(tree, i);
13137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
13147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
13157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
13167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  fpdef ['=' test] (',' fpdef ['=' test])* [',']
13177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
13187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* strip trailing comma node */
13197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (sym == COMMA) {
13207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_comma(CHILD(tree, nch-1));
13217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (!res)
13227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    return 0;
13237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                --nch;
13247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
13257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
13267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  fpdef ['=' test] (',' fpdef ['=' test])*
13277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
13287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_fpdef(CHILD(tree, 0));
13297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ++i;
13307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
13317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_equal(CHILD(tree, i))
13327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_test(CHILD(tree, i+1)));
13337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                i += 2;
13347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
13357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
13367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  ... (',' fpdef ['=' test])*
13377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  i ---^^^
13387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
13397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (res && (nch - i) >= 2) {
13407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_comma(CHILD(tree, i))
13417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_fpdef(CHILD(tree, i+1)));
13427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                i += 2;
13437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
13447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    res = (validate_equal(CHILD(tree, i))
13457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           && validate_test(CHILD(tree, i+1)));
13467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    i += 2;
13477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
13487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
13497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && nch - i != 0) {
13507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = 0;
13517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal formation for varargslist");
13527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
13537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
13547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
13567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  list_iter:  list_for | list_if
13607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
13617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
13627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_list_iter(node *tree)
13637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, list_iter)
13657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_numnodes(tree, 1, "list_iter"));
13667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && TYPE(CHILD(tree, 0)) == list_for)
13677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_list_for(CHILD(tree, 0));
13687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
13697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_list_if(CHILD(tree, 0));
13707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
13727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  comp_iter:  comp_for | comp_if
13757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
13767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
13777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_comp_iter(node *tree)
13787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, comp_iter)
13807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_numnodes(tree, 1, "comp_iter"));
13817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && TYPE(CHILD(tree, 0)) == comp_for)
13827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_comp_for(CHILD(tree, 0));
13837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
13847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_comp_if(CHILD(tree, 0));
13857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
13877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  list_for:  'for' exprlist 'in' testlist [list_iter]
13907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
13917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
13927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_list_for(node *tree)
13937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
13957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res;
13967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 5)
13987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_list_iter(CHILD(tree, 4));
13997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
14007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 4, "list_for");
14017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
14037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "for")
14047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_exprlist(CHILD(tree, 1))
14057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 2), "in")
14067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_testlist_safe(CHILD(tree, 3)));
14077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
14097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  comp_for:  'for' exprlist 'in' test [comp_iter]
14127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
14137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
14147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_comp_for(node *tree)
14157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
14177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res;
14187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 5)
14207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_comp_iter(CHILD(tree, 4));
14217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
14227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 4, "comp_for");
14237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
14257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "for")
14267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_exprlist(CHILD(tree, 1))
14277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 2), "in")
14287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_or_test(CHILD(tree, 3)));
14297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
14317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  list_if:  'if' old_test [list_iter]
14347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
14357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
14367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_list_if(node *tree)
14377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
14397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res;
14407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 3)
14427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_list_iter(CHILD(tree, 2));
14437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
14447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 2, "list_if");
14457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
14477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "if")
14487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_old_test(CHILD(tree, 1)));
14497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
14517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  comp_if:  'if' old_test [comp_iter]
14547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
14557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
14567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_comp_if(node *tree)
14577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
14597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res;
14607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 3)
14627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_comp_iter(CHILD(tree, 2));
14637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
14647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 2, "comp_if");
14657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
14677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "if")
14687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_old_test(CHILD(tree, 1)));
14697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
14717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  validate_fpdef()
14747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
14757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  fpdef:
14767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      NAME
14777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    | '(' fplist ')'
14787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
14797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
14807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_fpdef(node *tree)
14817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
14837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, fpdef);
14847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
14867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch == 1)
14877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_ntype(CHILD(tree, 0), NAME);
14887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch == 3)
14897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_lparen(CHILD(tree, 0))
14907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_fplist(CHILD(tree, 1))
14917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_rparen(CHILD(tree, 2)));
14927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
14937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_numnodes(tree, 1, "fpdef");
14947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
14967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_fplist(node *tree)
15017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, fplist,
15037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_fpdef, "fplist"));
15047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  simple_stmt | compound_stmt
15087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
15097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
15107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_stmt(node *tree)
15127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, stmt)
15147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_numnodes(tree, 1, "stmt"));
15157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
15177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tree = CHILD(tree, 0);
15187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(tree) == simple_stmt)
15207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_simple_stmt(tree);
15217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
15227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_compound_stmt(tree);
15237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
15257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  small_stmt (';' small_stmt)* [';'] NEWLINE
15297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
15307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
15317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_simple_stmt(node *tree)
15337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
15357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, simple_stmt)
15367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch >= 2)
15377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_small_stmt(CHILD(tree, 0))
15387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_newline(CHILD(tree, nch - 1)));
15397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch < 2)
15417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 2, "simple_stmt");
15427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    --nch;                              /* forget the NEWLINE    */
15437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && is_even(nch))
15447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_semi(CHILD(tree, --nch));
15457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch > 2)) {
15467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i;
15477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 1; res && (i < nch); i += 2)
15497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_semi(CHILD(tree, i))
15507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_small_stmt(CHILD(tree, i + 1)));
15517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
15537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_small_stmt(node *tree)
15587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
15607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_numnodes(tree, 1, "small_stmt");
15617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
15637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int ntype = TYPE(CHILD(tree, 0));
15647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (  (ntype == expr_stmt)
15667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == print_stmt)
15677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == del_stmt)
15687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == pass_stmt)
15697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == flow_stmt)
15707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == import_stmt)
15717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == global_stmt)
15727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == assert_stmt)
15737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              || (ntype == exec_stmt))
15747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_node(CHILD(tree, 0));
15757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
15767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
15777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal small_stmt child type");
15787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
15797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (nch == 1) {
15817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = 0;
15827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
15837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Unrecognized child node of small_stmt: %d.",
15847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     TYPE(CHILD(tree, 0)));
15857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
15877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  compound_stmt:
15917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
15927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
15937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_compound_stmt(node *tree)
15957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, compound_stmt)
15977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_numnodes(tree, 1, "compound_stmt"));
15987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ntype;
15997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res)
16017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
16027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    tree = CHILD(tree, 0);
16047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ntype = TYPE(tree);
16057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (  (ntype == if_stmt)
16067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == while_stmt)
16077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == for_stmt)
16087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == try_stmt)
16097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == with_stmt)
16107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == funcdef)
16117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == classdef)
16127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          || (ntype == decorated))
16137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_node(tree);
16147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
16157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = 0;
16167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
16177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Illegal compound statement type: %d.", TYPE(tree));
16187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
16207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
16237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_yield_or_testlist(node *tree)
16247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
16257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(tree) == yield_expr)
16267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return validate_yield_expr(tree);
16277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
16287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return validate_testlist(tree);
16297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
16327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_expr_stmt(node *tree)
16337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
16347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
16357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
16367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, expr_stmt)
16377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
16387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_testlist(CHILD(tree, 0)));
16397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && nch == 3
16417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && TYPE(CHILD(tree, 1)) == augassign) {
16427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
16437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_yield_or_testlist(CHILD(tree, 2));
16447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res) {
16467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            char *s = STR(CHILD(CHILD(tree, 1), 0));
16477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (strcmp(s, "+=") == 0
16497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "-=") == 0
16507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "*=") == 0
16517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "/=") == 0
16527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "//=") == 0
16537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "%=") == 0
16547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "&=") == 0
16557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "|=") == 0
16567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "^=") == 0
16577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "<<=") == 0
16587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, ">>=") == 0
16597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || strcmp(s, "**=") == 0);
16607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (!res)
16617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal augmented assignment operator");
16627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
16637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
16657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (j = 1; res && (j < nch); j += 2)
16667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_equal(CHILD(tree, j))
16677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_yield_or_testlist(CHILD(tree, j + 1));
16687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
16707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  print_stmt:
16747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
16757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      'print' ( [ test (',' test)* [','] ]
16767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *              | '>>' test [ (',' test)+ [','] ] )
16777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
16787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
16797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_print_stmt(node *tree)
16807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
16817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
16827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, print_stmt)
16837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch > 0)
16847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "print"));
16857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && nch > 1) {
16877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int sym = TYPE(CHILD(tree, 1));
16887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i = 1;
16897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int allow_trailing_comma = 1;
16907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (sym == test)
16927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_test(CHILD(tree, i++));
16937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
16947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (nch < 3)
16957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_numnodes(tree, 3, "print_stmt");
16967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
16977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_ntype(CHILD(tree, i), RIGHTSHIFT)
16987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_test(CHILD(tree, i+1)));
16997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                i += 2;
17007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                allow_trailing_comma = 0;
17017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
17027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
17037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res) {
17047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*  ... (',' test)* [',']  */
17057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (res && i+2 <= nch) {
17067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_comma(CHILD(tree, i))
17077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_test(CHILD(tree, i+1)));
17087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                allow_trailing_comma = 1;
17097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                i += 2;
17107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
17117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && !allow_trailing_comma)
17127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_numnodes(tree, i, "print_stmt");
17137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (res && i < nch)
17147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_comma(CHILD(tree, i));
17157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
17167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
17187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
17227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_del_stmt(node *tree)
17237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_numnodes(tree, 2, "del_stmt")
17257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_name(CHILD(tree, 0), "del")
17267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_exprlist(CHILD(tree, 1)));
17277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
17317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_return_stmt(node *tree)
17327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
17347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, return_stmt)
17357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 1) || (nch == 2))
17367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "return"));
17377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 2))
17397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_testlist(CHILD(tree, 1));
17407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
17427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
17467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_raise_stmt(node *tree)
17477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
17497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, raise_stmt)
17507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
17517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
17537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_name(CHILD(tree, 0), "raise");
17547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && (nch >= 2))
17557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_test(CHILD(tree, 1));
17567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && nch > 2) {
17577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_comma(CHILD(tree, 2))
17587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_test(CHILD(tree, 3)));
17597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && (nch > 4))
17607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_comma(CHILD(tree, 4))
17617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_test(CHILD(tree, 5)));
17627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
17637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
17657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 2, "raise");
17667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 4))
17677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comma(CHILD(tree, 2))
17687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 3)));
17697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
17717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* yield_expr: 'yield' [testlist]
17757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
17767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
17777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_yield_expr(node *tree)
17787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
17807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, yield_expr)
17817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 1) || (nch == 2))
17827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "yield"));
17837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 2))
17857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_testlist(CHILD(tree, 1));
17867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
17887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* yield_stmt: yield_expr
17927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
17937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
17947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_yield_stmt(node *tree)
17957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_ntype(tree, yield_stmt)
17977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_numnodes(tree, 1, "yield_stmt")
17987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_yield_expr(CHILD(tree, 0)));
17997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_import_as_name(node *tree)
18047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
18067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = validate_ntype(tree, import_as_name);
18077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok) {
18097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch == 1)
18107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_name(CHILD(tree, 0), NULL);
18117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch == 3)
18127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_name(CHILD(tree, 0), NULL)
18137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_name(CHILD(tree, 1), "as")
18147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_name(CHILD(tree, 2), NULL));
18157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
18167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_numnodes(tree, 3, "import_as_name");
18177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
18187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
18197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* dotted_name:  NAME ("." NAME)*
18237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
18247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_dotted_name(node *tree)
18267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
18287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, dotted_name)
18297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
18307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), NULL));
18317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
18327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 1; res && (i < nch); i += 2) {
18347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_dot(CHILD(tree, i))
18357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, i+1), NULL));
18367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
18377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
18387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* dotted_as_name:  dotted_name [NAME NAME]
18427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
18437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_dotted_as_name(node *tree)
18457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
18477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, dotted_as_name);
18487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
18507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch == 1)
18517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_dotted_name(CHILD(tree, 0));
18527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch == 3)
18537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_dotted_name(CHILD(tree, 0))
18547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, 1), "as")
18557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, 2), NULL));
18567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
18577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
18587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal number of children for dotted_as_name");
18597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
18607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
18617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
18627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* dotted_as_name (',' dotted_as_name)* */
18667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_dotted_as_names(node *tree)
18687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int nch = NCH(tree);
18707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
18717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i;
18727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 1; res && (i < nch); i += 2)
18747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_comma(CHILD(tree, i))
18757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_dotted_as_name(CHILD(tree, i + 1)));
18767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (res);
18777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* import_as_name (',' import_as_name)* [','] */
18817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_import_as_names(node *tree)
18837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
18857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_import_as_name(CHILD(tree, 0));
18867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
18877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 1; res && (i + 1 < nch); i += 2)
18897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comma(CHILD(tree, i))
18907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_import_as_name(CHILD(tree, i + 1)));
18917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
18927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
18937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 'import' dotted_as_names */
18967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
18977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_import_name(node *tree)
18987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (validate_ntype(tree, import_name)
19007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_numnodes(tree, 2, "import_name")
19017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_name(CHILD(tree, 0), "import")
19027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_dotted_as_names(CHILD(tree, 1)));
19037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
19047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Helper function to count the number of leading dots in
19067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 'from ...module import name'
19077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
19087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
19097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielcount_from_dots(node *tree)
19107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
19117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i;
19127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 1; i < NCH(tree); i++)
19137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (TYPE(CHILD(tree, i)) != DOT)
19147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        break;
19157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return i-1;
19167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
19177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* import_from: ('from' ('.'* dotted_name | '.'+)
19197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *               'import' ('*' | '(' import_as_names ')' | import_as_names))
19207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
19217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
19227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_import_from(node *tree)
19237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
19247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int nch = NCH(tree);
19257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int ndots = count_from_dots(tree);
19267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name);
19277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int offset = ndots + havename;
19287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int res = validate_ntype(tree, import_from)
19297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && (offset >= 1)
19307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && (nch >= 3 + offset)
19317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_name(CHILD(tree, 0), "from")
19327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && (!havename || validate_dotted_name(CHILD(tree, ndots + 1)))
19337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_name(CHILD(tree, offset + 1), "import");
19347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res && TYPE(CHILD(tree, offset + 2)) == LPAR)
19367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = ((nch == offset + 5)
19377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_lparen(CHILD(tree, offset + 2))
19387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_import_as_names(CHILD(tree, offset + 3))
19397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_rparen(CHILD(tree, offset + 4)));
19407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (res && TYPE(CHILD(tree, offset + 2)) != STAR)
19417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_import_as_names(CHILD(tree, offset + 2));
19427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (res);
19437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
19447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* import_stmt: import_name | import_from */
19477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
19487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_import_stmt(node *tree)
19497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
19507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
19517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_numnodes(tree, 1, "import_stmt");
19527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
19547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int ntype = TYPE(CHILD(tree, 0));
19557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ntype == import_name || ntype == import_from)
19577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_node(CHILD(tree, 0));
19587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
19597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
19607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal import_stmt child type");
19617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
19627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
19637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (nch == 1) {
19647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = 0;
19657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
19667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Unrecognized child node of import_stmt: %d.",
19677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     TYPE(CHILD(tree, 0)));
19687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
19697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
19707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
19717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
19767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_global_stmt(node *tree)
19777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
19787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
19797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
19807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, global_stmt)
19817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_even(nch) && (nch >= 2));
19827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
19847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("illegal global statement");
19857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
19877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "global")
19887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, 1), NAME));
19897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (j = 2; res && (j < nch); j += 2)
19907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comma(CHILD(tree, j))
19917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, j + 1), NAME));
19927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
19947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
19957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  exec_stmt:
19987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
19997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  'exec' expr ['in' test [',' test]]
20007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
20017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
20027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_exec_stmt(node *tree)
20037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
20057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, exec_stmt)
20067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 2) || (nch == 4) || (nch == 6))
20077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "exec")
20087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_expr(CHILD(tree, 1)));
20097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
20117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("illegal exec statement");
20127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch > 2))
20137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 2), "in")
20147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 3)));
20157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 6))
20167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comma(CHILD(tree, 4))
20177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 5)));
20187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
20207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  assert_stmt:
20247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
20257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  'assert' test [',' test]
20267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
20277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
20287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_assert_stmt(node *tree)
20297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
20317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, assert_stmt)
20327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 2) || (nch == 4))
20337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (validate_name(CHILD(tree, 0), "assert"))
20347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 1)));
20357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
20377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("illegal assert statement");
20387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch > 2))
20397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comma(CHILD(tree, 2))
20407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 3)));
20417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
20437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
20477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_while(node *tree)
20487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
20507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, while_stmt)
20517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 4) || (nch == 7))
20527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "while")
20537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 1))
20547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 2))
20557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 3)));
20567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 7))
20587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 4), "else")
20597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 5))
20607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 6)));
20617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
20637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
20677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_for(node *tree)
20687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
20707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, for_stmt)
20717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 6) || (nch == 9))
20727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "for")
20737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_exprlist(CHILD(tree, 1))
20747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 2), "in")
20757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_testlist(CHILD(tree, 3))
20767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 4))
20777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 5)));
20787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 9))
20807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 6), "else")
20817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 7))
20827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 8)));
20837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
20857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  try_stmt:
20897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
20907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                   ['finally' ':' suite]
20917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    | 'try' ':' suite 'finally' ':' suite
20927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
20937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
20947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
20957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_try(node *tree)
20967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
20987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos = 3;
20997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, try_stmt)
21007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch >= 6) && ((nch % 3) == 0));
21017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
21037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, 0), "try")
21047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 1))
21057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 2))
21067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, nch - 2))
21077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, nch - 1)));
21087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (!PyErr_Occurred()) {
21097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        const char* name = "except";
21107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(CHILD(tree, nch - 3)) != except_clause)
21117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            name = STR(CHILD(tree, nch - 3));
21127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(parser_error,
21147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Illegal number of children for try/%s node.", name);
21157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Handle try/finally statement */
21177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (TYPE(CHILD(tree, pos)) == NAME) &&
21187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) {
21197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_numnodes(tree, 6, "try/finally")
21207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, 4))
21217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, 5)));
21227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (res);
21237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* try/except statement: skip past except_clause sections */
21257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (res && pos < nch && (TYPE(CHILD(tree, pos)) == except_clause)) {
21267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_except_clause(CHILD(tree, pos))
21277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, pos + 1))
21287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, pos + 2)));
21297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        pos += 3;
21307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* skip else clause */
21327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && pos < nch && (TYPE(CHILD(tree, pos)) == NAME) &&
21337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (strcmp(STR(CHILD(tree, pos)), "else") == 0)) {
21347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_colon(CHILD(tree, pos + 1))
21357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, pos + 2)));
21367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        pos += 3;
21377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && pos < nch) {
21397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* last clause must be a finally */
21407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, pos), "finally")
21417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_numnodes(tree, pos + 3, "try/except/finally")
21427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, pos + 1))
21437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(CHILD(tree, pos + 2)));
21447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
21467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
21477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
21507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_except_clause(node *tree)
21517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
21527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
21537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, except_clause)
21547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 1) || (nch == 2) || (nch == 4))
21557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "except"));
21567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch > 1))
21587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_test(CHILD(tree, 1));
21597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 4)) {
21607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(CHILD(tree, 2)) == NAME)
21617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_name(CHILD(tree, 2), "as");
21627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
21637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_comma(CHILD(tree, 2));
21647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = res && validate_test(CHILD(tree, 3));
21657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
21677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
21687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
21717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_test(node *tree)
21727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
21737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
21747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, test) && is_odd(nch);
21757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (TYPE(CHILD(tree, 0)) == lambdef))
21777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = ((nch == 1)
21787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_lambdef(CHILD(tree, 0)));
21797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (res) {
21807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_or_test(CHILD(tree, 0));
21817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (res && (nch == 1 || (nch == 5 &&
21827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            validate_name(CHILD(tree, 1), "if") &&
21837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            validate_or_test(CHILD(tree, 2)) &&
21847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            validate_name(CHILD(tree, 3), "else") &&
21857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            validate_test(CHILD(tree, 4)))));
21867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
21877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
21887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
21897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
21917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_old_test(node *tree)
21927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
21937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
21947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, old_test) && (nch == 1);
21957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (TYPE(CHILD(tree, 0)) == old_lambdef))
21977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_old_lambdef(CHILD(tree, 0)));
21987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (res) {
21997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_or_test(CHILD(tree, 0)));
22007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
22017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
22027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
22037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
22057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_or_test(node *tree)
22067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
22077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
22087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, or_test) && is_odd(nch);
22097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
22117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int pos;
22127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_and_test(CHILD(tree, 0));
22137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (pos = 1; res && (pos < nch); pos += 2)
22147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_name(CHILD(tree, pos), "or")
22157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_and_test(CHILD(tree, pos + 1)));
22167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
22177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
22187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
22197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
22227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_and_test(node *tree)
22237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
22247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos;
22257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
22267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, and_test)
22277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
22287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_not_test(CHILD(tree, 0)));
22297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (pos = 1; res && (pos < nch); pos += 2)
22317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_name(CHILD(tree, pos), "and")
22327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_not_test(CHILD(tree, 0)));
22337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
22357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
22367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
22397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_not_test(node *tree)
22407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
22417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
22427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
22437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
22457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch == 2)
22467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_name(CHILD(tree, 0), "not")
22477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_not_test(CHILD(tree, 1)));
22487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (nch == 1)
22497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_comparison(CHILD(tree, 0));
22507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
22517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
22527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
22537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
22567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_comparison(node *tree)
22577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
22587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos;
22597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
22607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, comparison)
22617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
22627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_expr(CHILD(tree, 0)));
22637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (pos = 1; res && (pos < nch); pos += 2)
22657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_comp_op(CHILD(tree, pos))
22667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_expr(CHILD(tree, pos + 1)));
22677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
22697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
22707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
22737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_comp_op(node *tree)
22747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
22757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = 0;
22767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
22777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
22787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!validate_ntype(tree, comp_op))
22797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
22807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 1) {
22817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
22827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  Only child will be a terminal with a well-defined symbolic name
22837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *  or a NAME with a string of either 'is' or 'in'
22847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
22857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tree = CHILD(tree, 0);
22867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (TYPE(tree)) {
22877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case LESS:
22887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case GREATER:
22897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case EQEQUAL:
22907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case EQUAL:
22917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case LESSEQUAL:
22927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case GREATEREQUAL:
22937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case NOTEQUAL:
22947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              res = 1;
22957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              break;
22967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case NAME:
22977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              res = ((strcmp(STR(tree), "in") == 0)
22987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     || (strcmp(STR(tree), "is") == 0));
22997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              if (!res) {
23007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  PyErr_Format(parser_error,
23017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               "illegal operator '%s'", STR(tree));
23027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              }
23037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              break;
23047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          default:
23057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              err_string("illegal comparison operator type");
23067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              break;
23077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
23087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
23097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
23107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_ntype(CHILD(tree, 0), NAME)
23117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, 1), NAME)
23127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
23137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
23147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
23157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
23167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!res && !PyErr_Occurred())
23177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("unknown comparison operator");
23187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
23197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
23207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
23247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_expr(node *tree)
23257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
23267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
23277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
23287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, expr)
23297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
23307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_xor_expr(CHILD(tree, 0)));
23317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (j = 2; res && (j < nch); j += 2)
23337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_xor_expr(CHILD(tree, j))
23347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_vbar(CHILD(tree, j - 1)));
23357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
23377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
23417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_xor_expr(node *tree)
23427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
23437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
23447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
23457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, xor_expr)
23467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
23477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_and_expr(CHILD(tree, 0)));
23487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (j = 2; res && (j < nch); j += 2)
23507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_circumflex(CHILD(tree, j - 1))
23517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_and_expr(CHILD(tree, j)));
23527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
23547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
23587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_and_expr(node *tree)
23597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
23607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos;
23617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
23627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, and_expr)
23637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
23647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_shift_expr(CHILD(tree, 0)));
23657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (pos = 1; res && (pos < nch); pos += 2)
23677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_ampersand(CHILD(tree, pos))
23687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_shift_expr(CHILD(tree, pos + 1)));
23697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
23717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
23757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
23767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {
23777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos = 1;
23787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
23797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (is_odd(nch)
23807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (*termvalid)(CHILD(tree, 0)));
23817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for ( ; res && (pos < nch); pos += 2) {
23837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(CHILD(tree, pos)) != op1)
23847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_ntype(CHILD(tree, pos), op2);
23857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res)
23867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (*termvalid)(CHILD(tree, pos + 1));
23877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
23887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
23897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
23927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
23937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_shift_expr(node *tree)
23947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
23957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_ntype(tree, shift_expr)
23967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_chain_two_ops(tree, validate_arith_expr,
23977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                      LEFTSHIFT, RIGHTSHIFT));
23987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
23997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
24027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_arith_expr(node *tree)
24037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
24047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_ntype(tree, arith_expr)
24057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
24067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
24077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
24107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_term(node *tree)
24117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
24127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos = 1;
24137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
24147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, term)
24157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && is_odd(nch)
24167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_factor(CHILD(tree, 0)));
24177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for ( ; res && (pos < nch); pos += 2)
24197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (((TYPE(CHILD(tree, pos)) == STAR)
24207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               || (TYPE(CHILD(tree, pos)) == SLASH)
24217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               || (TYPE(CHILD(tree, pos)) == DOUBLESLASH)
24227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               || (TYPE(CHILD(tree, pos)) == PERCENT))
24237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_factor(CHILD(tree, pos + 1)));
24247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
24267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
24277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  factor:
24307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
24317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  factor: ('+'|'-'|'~') factor | power
24327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
24337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
24347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_factor(node *tree)
24357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
24367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
24377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, factor)
24387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (((nch == 2)
24397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    && ((TYPE(CHILD(tree, 0)) == PLUS)
24407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == MINUS)
24417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == TILDE))
24427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    && validate_factor(CHILD(tree, 1)))
24437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   || ((nch == 1)
24447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_power(CHILD(tree, 0)))));
24457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
24467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
24477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  power:
24507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
24517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  power: atom trailer* ('**' factor)*
24527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
24537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
24547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_power(node *tree)
24557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
24567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos = 1;
24577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
24587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, power) && (nch >= 1)
24597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_atom(CHILD(tree, 0)));
24607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
24627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_trailer(CHILD(tree, pos++));
24637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (pos < nch)) {
24647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!is_even(nch - pos)) {
24657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal number of nodes for 'power'");
24667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return (0);
24677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
24687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for ( ; res && (pos < (nch - 1)); pos += 2)
24697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_doublestar(CHILD(tree, pos))
24707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_factor(CHILD(tree, pos + 1)));
24717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
24727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
24737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
24747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
24777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_atom(node *tree)
24787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
24797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos;
24807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
24817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, atom);
24827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && nch < 1)
24847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, nch+1, "atom");
24857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
24867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (TYPE(CHILD(tree, 0))) {
24877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case LPAR:
24887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = ((nch <= 3)
24897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && (validate_rparen(CHILD(tree, nch - 1))));
24907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
24917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && (nch == 3)) {
24927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (TYPE(CHILD(tree, 1))==yield_expr)
24937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        res = validate_yield_expr(CHILD(tree, 1));
24947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                else
24957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        res = validate_testlist_comp(CHILD(tree, 1));
24967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
24977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
24987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case LSQB:
24997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (nch == 2)
25007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_ntype(CHILD(tree, 1), RSQB);
25017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (nch == 3)
25027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = (validate_listmaker(CHILD(tree, 1))
25037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       && validate_ntype(CHILD(tree, 2), RSQB));
25047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
25057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = 0;
25067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal list display atom");
25077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
25087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case LBRACE:
25107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = ((nch <= 3)
25117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_ntype(CHILD(tree, nch - 1), RBRACE));
25127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && (nch == 3))
25147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_dictorsetmaker(CHILD(tree, 1));
25157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case BACKQUOTE:
25177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = ((nch == 3)
25187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_testlist1(CHILD(tree, 1))
25197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_ntype(CHILD(tree, 2), BACKQUOTE));
25207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case NAME:
25227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case NUMBER:
25237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (nch == 1);
25247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case STRING:
25267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for (pos = 1; res && (pos < nch); ++pos)
25277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_ntype(CHILD(tree, pos), STRING);
25287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          default:
25307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
25317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
25327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
25337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
25347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
25357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
25367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  listmaker:
25397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    test ( list_for | (',' test)* [','] )
25407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
25417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
25427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_listmaker(node *tree)
25437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
25447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
25457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = nch;
25467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 0)
25487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("missing child nodes of listmaker");
25497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
25507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_test(CHILD(tree, 0));
25517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*
25537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  list_for | (',' test)* [',']
25547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
25557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for)
25567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_list_for(CHILD(tree, 1));
25577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
25587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  (',' test)* [',']  */
25597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i = 1;
25607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (ok && nch - i >= 2) {
25617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_comma(CHILD(tree, i))
25627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_test(CHILD(tree, i+1)));
25637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 2;
25647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
25657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok && i == nch-1)
25667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_comma(CHILD(tree, i));
25677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (i != nch) {
25687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = 0;
25697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal trailing nodes for listmaker");
25707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
25717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
25727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
25737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
25747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  testlist_comp:
25767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    test ( comp_for | (',' test)* [','] )
25777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
25787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
25797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_testlist_comp(node *tree)
25807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
25817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
25827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = nch;
25837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 0)
25857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("missing child nodes of testlist_comp");
25867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
25877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_test(CHILD(tree, 0));
25887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
25897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
25907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*
25917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  comp_for | (',' test)* [',']
25927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
25937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for)
25947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_comp_for(CHILD(tree, 1));
25957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
25967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*  (',' test)* [',']  */
25977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i = 1;
25987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (ok && nch - i >= 2) {
25997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_comma(CHILD(tree, i))
26007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_test(CHILD(tree, i+1)));
26017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 2;
26027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
26037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok && i == nch-1)
26047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_comma(CHILD(tree, i));
26057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (i != nch) {
26067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = 0;
26077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal trailing nodes for testlist_comp");
26087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
26097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
26107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
26117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
26127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  decorator:
26147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
26157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
26167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
26177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_decorator(node *tree)
26187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
26197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok;
26207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
26217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ok = (validate_ntype(tree, decorator) &&
26227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          (nch == 3 || nch == 5 || nch == 6) &&
26237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          validate_at(CHILD(tree, 0)) &&
26247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          validate_dotted_name(CHILD(tree, 1)) &&
26257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          validate_newline(RCHILD(tree, -1)));
26267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok && nch != 3) {
26287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = (validate_lparen(CHILD(tree, 2)) &&
26297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              validate_rparen(RCHILD(tree, -2)));
26307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok && nch == 6)
26327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_arglist(CHILD(tree, 3));
26337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
26347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
26367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
26377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  decorators:
26397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    decorator+
26407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
26417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
26427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_decorators(node *tree)
26437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
26447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i, nch, ok;
26457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    nch = NCH(tree);
26467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ok = validate_ntype(tree, decorators) && nch >= 1;
26477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; ok && i < nch; ++i)
26497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_decorator(CHILD(tree, i));
26507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
26527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
26537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  with_item:
26557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   test ['as' expr]
26567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
26577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
26587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_with_item(node *tree)
26597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
26607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
26617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = (validate_ntype(tree, with_item)
26627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && (nch == 1 || nch == 3)
26637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_test(CHILD(tree, 0)));
26647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok && nch == 3)
26657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = (validate_name(CHILD(tree, 1), "as")
26667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_expr(CHILD(tree, 2)));
26677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
26687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
26697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  with_stmt:
26717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *    0      1          ...             -2   -1
26727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   'with' with_item (',' with_item)* ':' suite
26737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
26747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
26757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_with_stmt(node *tree)
26767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
26777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
26787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
26797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = (validate_ntype(tree, with_stmt)
26807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && (nch % 2 == 0)
26817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && validate_name(CHILD(tree, 0), "with")
26827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && validate_colon(RCHILD(tree, -2))
26837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && validate_suite(RCHILD(tree, -1)));
26847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 1; ok && i < nch - 2; i += 2)
26857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_with_item(CHILD(tree, i));
26867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
26877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
26887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
26897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  funcdef:
26907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
26917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *     -5   -4         -3  -2    -1
26927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  'def' NAME parameters ':' suite
26937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
26947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
26957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_funcdef(node *tree)
26967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
26977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
26987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = (validate_ntype(tree, funcdef)
26997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch == 5)
27007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(RCHILD(tree, -5), "def")
27017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(RCHILD(tree, -4), NAME)
27027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(RCHILD(tree, -2))
27037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_parameters(RCHILD(tree, -3))
27047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_suite(RCHILD(tree, -1)));
27057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
27067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
27077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* decorated
27107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   decorators (classdef | funcdef)
27117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
27127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
27137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_decorated(node *tree)
27147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
27157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
27167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = (validate_ntype(tree, decorated)
27177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && (nch == 2)
27187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_decorators(RCHILD(tree, -2)));
27197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (TYPE(RCHILD(tree, -1)) == funcdef)
27207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = ok && validate_funcdef(RCHILD(tree, -1));
27217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
27227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = ok && validate_class(RCHILD(tree, -1));
27237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
27247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
27257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
27277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_lambdef(node *tree)
27287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
27297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
27307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, lambdef)
27317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 3) || (nch == 4))
27327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "lambda")
27337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, nch - 2))
27347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, nch - 1)));
27357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 4))
27377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_varargslist(CHILD(tree, 1));
27387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (!res && !PyErr_Occurred())
27397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 3, "lambdef");
27407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
27427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
27437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
27467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_old_lambdef(node *tree)
27477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
27487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
27497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, old_lambdef)
27507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 3) || (nch == 4))
27517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_name(CHILD(tree, 0), "lambda")
27527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_colon(CHILD(tree, nch - 2))
27537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, nch - 1)));
27547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 4))
27567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_varargslist(CHILD(tree, 1));
27577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (!res && !PyErr_Occurred())
27587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 3, "old_lambdef");
27597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
27617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
27627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  arglist:
27657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
27667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
27677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
27687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
27697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_arglist(node *tree)
27707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
27717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
27727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i = 0;
27737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = 1;
27747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch <= 0)
27767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* raise the right error from having an invalid number of children */
27777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return validate_numnodes(tree, nch + 1, "arglist");
27787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch > 1) {
27807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i=0; i<nch; i++) {
27817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (TYPE(CHILD(tree, i)) == argument) {
27827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                node *ch = CHILD(tree, i);
27837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == comp_for) {
27847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    err_string("need '(', ')' for generator expression");
27857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    return 0;
27867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
27877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
27887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
27897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
27907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (ok && nch-i >= 2) {
27927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* skip leading (argument ',') */
27937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = (validate_argument(CHILD(tree, i))
27947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_comma(CHILD(tree, i+1)));
27957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ok)
27967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 2;
27977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
27987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_Clear();
27997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
28007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ok = 1;
28017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch-i > 0) {
28027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /*
28037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         * argument | '*' test [',' '**' test] | '**' test
28047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
28057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int sym = TYPE(CHILD(tree, i));
28067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (sym == argument) {
28087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_argument(CHILD(tree, i));
28097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (ok && i+1 != nch) {
28107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal arglist specification"
28117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           " (extra stuff on end)");
28127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = 0;
28137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
28147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
28157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (sym == STAR) {
28167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_star(CHILD(tree, i));
28177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (ok && (nch-i == 2))
28187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = validate_test(CHILD(tree, i+1));
28197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (ok && (nch-i == 5))
28207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = (validate_test(CHILD(tree, i+1))
28217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      && validate_comma(CHILD(tree, i+2))
28227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      && validate_doublestar(CHILD(tree, i+3))
28237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      && validate_test(CHILD(tree, i+4)));
28247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
28257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal use of '*' in arglist");
28267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = 0;
28277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
28287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
28297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (sym == DOUBLESTAR) {
28307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (nch-i == 2)
28317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = (validate_doublestar(CHILD(tree, i))
28327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      && validate_test(CHILD(tree, i+1)));
28337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
28347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal use of '**' in arglist");
28357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = 0;
28367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
28377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
28387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
28397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal arglist specification");
28407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = 0;
28417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
28427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
28437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (ok);
28447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
28457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  argument:
28497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
28507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  [test '='] test [comp_for]
28517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
28527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
28537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_argument(node *tree)
28547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
28557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
28567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, argument)
28577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && ((nch == 1) || (nch == 2) || (nch == 3))
28587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 0)));
28597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 2))
28617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_comp_for(CHILD(tree, 1));
28627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (res && (nch == 3))
28637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = (validate_equal(CHILD(tree, 1))
28647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_test(CHILD(tree, 2)));
28657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
28677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
28687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  trailer:
28727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
28737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
28747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
28757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
28767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_trailer(node *tree)
28777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
28787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
28797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
28807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
28817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
28827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (TYPE(CHILD(tree, 0))) {
28837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case LPAR:
28847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_rparen(CHILD(tree, nch - 1));
28857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && (nch == 3))
28867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_arglist(CHILD(tree, 1));
28877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
28887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case LSQB:
28897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_numnodes(tree, 3, "trailer")
28907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_subscriptlist(CHILD(tree, 1))
28917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_ntype(CHILD(tree, 2), RSQB));
28927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
28937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case DOT:
28947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_numnodes(tree, 2, "trailer")
28957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_ntype(CHILD(tree, 1), NAME));
28967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
28977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          default:
28987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
28997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
29007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
29017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
29037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (void) validate_numnodes(tree, 2, "trailer");
29047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
29067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
29077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  subscriptlist:
29107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
29117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  subscript (',' subscript)* [',']
29127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
29137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
29147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_subscriptlist(node *tree)
29157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
29167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, subscriptlist,
29177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_subscript, "subscriptlist"));
29187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
29197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  subscript:
29227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
29237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  '.' '.' '.' | test | [test] ':' [test] [sliceop]
29247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
29257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
29267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_subscript(node *tree)
29277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
29287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int offset = 0;
29297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
29307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
29317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res) {
29337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!PyErr_Occurred())
29347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("invalid number of arguments for subscript node");
29357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (0);
29367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (TYPE(CHILD(tree, 0)) == DOT)
29387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* take care of ('.' '.' '.') possibility */
29397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (validate_numnodes(tree, 3, "subscript")
29407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_dot(CHILD(tree, 0))
29417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_dot(CHILD(tree, 1))
29427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                && validate_dot(CHILD(tree, 2)));
29437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (nch == 1) {
29447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(CHILD(tree, 0)) == test)
29457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_test(CHILD(tree, 0));
29467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
29477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_colon(CHILD(tree, 0));
29487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return (res);
29497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*  Must be [test] ':' [test] [sliceop],
29517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  but at least one of the optional components will
29527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  be present, but we don't know which yet.
29537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
29547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
29557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_test(CHILD(tree, 0));
29567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        offset = 1;
29577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
29597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_colon(CHILD(tree, offset));
29607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res) {
29617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int rem = nch - ++offset;
29627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (rem) {
29637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (TYPE(CHILD(tree, offset)) == test) {
29647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_test(CHILD(tree, offset));
29657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ++offset;
29667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                --rem;
29677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
29687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res && rem)
29697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                res = validate_sliceop(CHILD(tree, offset));
29707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
29717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
29737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
29747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
29777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_sliceop(node *tree)
29787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
29797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
29807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
29817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_ntype(tree, sliceop);
29827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred()) {
29837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_numnodes(tree, 1, "sliceop");
29847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
29857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res)
29867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_colon(CHILD(tree, 0));
29877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res && (nch == 2))
29887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_test(CHILD(tree, 1));
29897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
29917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
29927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
29947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
29957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_exprlist(node *tree)
29967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
29977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (validate_repeating_list(tree, exprlist,
29987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    validate_expr, "exprlist"));
29997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
30007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
30037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * dictorsetmaker:
30047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
30057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * (test ':' test (comp_for | (',' test ':' test)* [','])) |
30067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * (test (comp_for | (',' test)* [',']))
30077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
30087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
30097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_dictorsetmaker(node *tree)
30107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
30117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
30127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ok = validate_ntype(tree, dictorsetmaker);
30137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i = 0;
30147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int check_trailing_comma = 0;
30157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(nch > 0);
30177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok && (nch == 1 || TYPE(CHILD(tree, 1)) == COMMA)) {
30197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* We got a set:
30207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *     test (',' test)* [',']
30217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
30227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = validate_test(CHILD(tree, i++));
30237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (ok && nch - i >= 2) {
30247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_comma(CHILD(tree, i))
30257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_test(CHILD(tree, i+1)));
30267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 2;
30277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
30287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        check_trailing_comma = 1;
30297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
30307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (ok && TYPE(CHILD(tree, 1)) == comp_for) {
30317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* We got a set comprehension:
30327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *     test comp_for
30337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
30347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = (validate_test(CHILD(tree, 0))
30357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_comp_for(CHILD(tree, 1)));
30367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
30377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (ok && NCH(tree) > 3 && TYPE(CHILD(tree, 3)) == comp_for) {
30387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* We got a dict comprehension:
30397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *     test ':' test comp_for
30407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
30417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ok = (validate_test(CHILD(tree, 0))
30427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_colon(CHILD(tree, 1))
30437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_test(CHILD(tree, 2))
30447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              && validate_comp_for(CHILD(tree, 3)));
30457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
30467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (ok) {
30477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* We got a dict:
30487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         *     test ':' test (',' test ':' test)* [',']
30497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
30507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nch >= 3) {
30517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_test(CHILD(tree, i))
30527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_colon(CHILD(tree, i+1))
30537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_test(CHILD(tree, i+2)));
30547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 3;
30557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
30567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
30577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = 0;
30587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal number of nodes for dictorsetmaker");
30597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
30607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (ok && nch - i >= 4) {
30627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = (validate_comma(CHILD(tree, i))
30637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_test(CHILD(tree, i+1))
30647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_colon(CHILD(tree, i+2))
30657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  && validate_test(CHILD(tree, i+3)));
30667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i += 4;
30677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
30687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        check_trailing_comma = 1;
30697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
30707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ok && check_trailing_comma) {
30717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (i == nch-1)
30727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = validate_comma(CHILD(tree, i));
30737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (i != nch) {
30747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ok = 0;
30757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("illegal trailing nodes for dictorsetmaker");
30767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
30777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
30787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ok;
30807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
30817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
30847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_eval_input(node *tree)
30857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
30867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int pos;
30877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
30887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = (validate_ntype(tree, eval_input)
30897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && (nch >= 2)
30907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_testlist(CHILD(tree, 0))
30917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
30927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (pos = 1; res && (pos < (nch - 1)); ++pos)
30947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        res = validate_ntype(CHILD(tree, pos), NEWLINE);
30957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
30977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
30987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
30997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
31007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
31017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_node(node *tree)
31027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
31037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int   nch  = 0;                     /* num. children on current node  */
31047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int   res  = 1;                     /* result value                   */
31057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    node* next = 0;                     /* node to process after this one */
31067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
31077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (res && (tree != 0)) {
31087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        nch  = NCH(tree);
31097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        next = 0;
31107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (TYPE(tree)) {
31117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
31127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  Definition nodes.
31137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
31147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case funcdef:
31157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_funcdef(tree);
31167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case with_stmt:
31187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_with_stmt(tree);
31197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case classdef:
31217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_class(tree);
31227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case decorated:
31247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_decorated(tree);
31257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
31277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  "Trivial" parse tree nodes.
31287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  (Why did I call these trivial?)
31297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
31307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case stmt:
31317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_stmt(tree);
31327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case small_stmt:
31347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
31357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
31367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  | import_stmt | global_stmt | exec_stmt | assert_stmt
31377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
31387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_small_stmt(tree);
31397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case flow_stmt:
31417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res  = (validate_numnodes(tree, 1, "flow_stmt")
31427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    && ((TYPE(CHILD(tree, 0)) == break_stmt)
31437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == continue_stmt)
31447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == yield_stmt)
31457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == return_stmt)
31467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        || (TYPE(CHILD(tree, 0)) == raise_stmt)));
31477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res)
31487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                next = CHILD(tree, 0);
31497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (nch == 1)
31507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                err_string("illegal flow_stmt type");
31517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case yield_stmt:
31537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_yield_stmt(tree);
31547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
31567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  Compound statements.
31577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
31587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case simple_stmt:
31597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_simple_stmt(tree);
31607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case compound_stmt:
31627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_compound_stmt(tree);
31637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
31657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  Fundamental statements.
31667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
31677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case expr_stmt:
31687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_expr_stmt(tree);
31697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case print_stmt:
31717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_print_stmt(tree);
31727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case del_stmt:
31747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_del_stmt(tree);
31757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case pass_stmt:
31777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_numnodes(tree, 1, "pass")
31787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, 0), "pass"));
31797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case break_stmt:
31817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_numnodes(tree, 1, "break")
31827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, 0), "break"));
31837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case continue_stmt:
31857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = (validate_numnodes(tree, 1, "continue")
31867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   && validate_name(CHILD(tree, 0), "continue"));
31877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case return_stmt:
31897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_return_stmt(tree);
31907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case raise_stmt:
31927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_raise_stmt(tree);
31937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case import_stmt:
31957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_import_stmt(tree);
31967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
31977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case import_name:
31987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_import_name(tree);
31997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case import_from:
32017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_import_from(tree);
32027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case global_stmt:
32047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_global_stmt(tree);
32057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case exec_stmt:
32077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_exec_stmt(tree);
32087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case assert_stmt:
32107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_assert_stmt(tree);
32117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case if_stmt:
32137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_if(tree);
32147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case while_stmt:
32167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_while(tree);
32177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case for_stmt:
32197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_for(tree);
32207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case try_stmt:
32227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_try(tree);
32237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case suite:
32257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_suite(tree);
32267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /*
32287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             *  Expression nodes.
32297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
32307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case testlist:
32317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_testlist(tree);
32327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case yield_expr:
32347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_yield_expr(tree);
32357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case testlist1:
32377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_testlist1(tree);
32387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case test:
32407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_test(tree);
32417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case and_test:
32437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_and_test(tree);
32447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case not_test:
32467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_not_test(tree);
32477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case comparison:
32497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_comparison(tree);
32507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case exprlist:
32527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_exprlist(tree);
32537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case comp_op:
32557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_comp_op(tree);
32567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case expr:
32587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_expr(tree);
32597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case xor_expr:
32617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_xor_expr(tree);
32627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case and_expr:
32647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_and_expr(tree);
32657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case shift_expr:
32677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_shift_expr(tree);
32687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case arith_expr:
32707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_arith_expr(tree);
32717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case term:
32737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_term(tree);
32747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case factor:
32767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_factor(tree);
32777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case power:
32797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_power(tree);
32807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          case atom:
32827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_atom(tree);
32837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
32857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          default:
32867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* Hopefully never reached! */
32877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            err_string("unrecognized node type");
32887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = 0;
32897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
32907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
32917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tree = next;
32927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
32937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
32947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
32957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
32967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
32977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
32987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_expr_tree(node *tree)
32997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
33007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = validate_eval_input(tree);
33017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
33037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("could not validate expression tuple");
33047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
33067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
33077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  file_input:
33107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *      (NEWLINE | stmt)* ENDMARKER
33117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
33127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
33137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_file_input(node *tree)
33147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
33157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int j;
33167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree) - 1;
33177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = ((nch >= 0)
33187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               && validate_ntype(CHILD(tree, nch), ENDMARKER));
33197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (j = 0; res && (j < nch); ++j) {
33217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (TYPE(CHILD(tree, j)) == stmt)
33227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_stmt(CHILD(tree, j));
33237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
33247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = validate_newline(CHILD(tree, j));
33257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
33267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*  This stays in to prevent any internal failures from getting to the
33277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  user.  Hopefully, this won't be needed.  If a user reports getting
33287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     *  this, we have some debugging to do.
33297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
33307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
33317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("VALIDATION FAILURE: report this to the maintainer!");
33327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (res);
33347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
33357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
33377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvalidate_encoding_decl(node *tree)
33387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
33397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int nch = NCH(tree);
33407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int res = ((nch == 1)
33417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && validate_file_input(CHILD(tree, 0)));
33427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!res && !PyErr_Occurred())
33447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        err_string("Error Parsing encoding_decl");
33457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
33477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
33487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
33507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpickle_constructor = NULL;
33517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
33547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielparser__pickler(PyObject *self, PyObject *args)
33557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
33567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NOTE(ARGUNUSED(self))
33577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = NULL;
33587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *st = NULL;
33597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *empty_dict = NULL;
33607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
33627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *newargs;
33637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *tuple;
33647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((empty_dict = PyDict_New()) == NULL)
33667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
33677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
33687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
33697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
33707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (tuple != NULL) {
33717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            result = Py_BuildValue("O(O)", pickle_constructor, tuple);
33727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(tuple);
33737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
33747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(empty_dict);
33757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(newargs);
33767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
33777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  finally:
33787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(empty_dict);
33797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (result);
33817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
33827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
33847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*  Functions exported by this module.  Most of this should probably
33857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  be converted into an ST object with methods, but that is better
33867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  done directly in Python, allowing subclasses to be created directly.
33877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  We'd really have to write a wrapper around it all anyway to allow
33887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *  inheritance.
33897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
33907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef parser_functions[] =  {
33917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ast2tuple",       (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
33927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a tuple-tree representation of an ST.")},
33937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ast2list",        (PyCFunction)parser_ast2list,  PUBLIC_METHOD_TYPE,
33947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a list-tree representation of an ST.")},
33957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"compileast",      (PyCFunction)parser_compileast,PUBLIC_METHOD_TYPE,
33967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Compiles an ST object into a code object.")},
33977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"compilest",      (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
33987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Compiles an ST object into a code object.")},
33997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"expr",            (PyCFunction)parser_expr,      PUBLIC_METHOD_TYPE,
34007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from an expression.")},
34017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"isexpr",          (PyCFunction)parser_isexpr,    PUBLIC_METHOD_TYPE,
34027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Determines if an ST object was created from an expression.")},
34037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"issuite",         (PyCFunction)parser_issuite,   PUBLIC_METHOD_TYPE,
34047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Determines if an ST object was created from a suite.")},
34057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"suite",           (PyCFunction)parser_suite,     PUBLIC_METHOD_TYPE,
34067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from a suite.")},
34077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"sequence2ast",    (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
34087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from a tree representation.")},
34097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"sequence2st",     (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
34107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from a tree representation.")},
34117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"st2tuple",        (PyCFunction)parser_st2tuple,  PUBLIC_METHOD_TYPE,
34127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a tuple-tree representation of an ST.")},
34137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"st2list",         (PyCFunction)parser_st2list,   PUBLIC_METHOD_TYPE,
34147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates a list-tree representation of an ST.")},
34157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"tuple2ast",       (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
34167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from a tree representation.")},
34177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"tuple2st",        (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
34187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Creates an ST object from a tree representation.")},
34197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* private stuff: support pickle module */
34217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"_pickler",        (PyCFunction)parser__pickler,  METH_VARARGS,
34227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")},
34237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL, 0, NULL}
34257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    };
34267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC initparser(void);  /* supply a prototype */
34297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
34317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinitparser(void)
34327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
34337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *module, *copyreg;
34347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TYPE(&PyST_Type) = &PyType_Type;
34367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    module = Py_InitModule("parser", parser_functions);
34377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (module == NULL)
34387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
34397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (parser_error == 0)
34417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
34427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (parser_error == 0)
34447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* caller will check PyErr_Occurred() */
34457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
34467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* CAUTION:  The code next used to skip bumping the refcount on
34477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * parser_error.  That's a disaster if initparser() gets called more
34487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * than once.  By incref'ing, we ensure that each module dict that
34497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * gets created owns its reference to the shared parser_error object,
34507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * and the file static parser_error vrbl owns a reference too.
34517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
34527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(parser_error);
34537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
34547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
34557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(&PyST_Type);
34577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
34587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(&PyST_Type);
34597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type);
34607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(module, "__copyright__",
34627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               parser_copyright_string);
34637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(module, "__doc__",
34647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               parser_doc_string);
34657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(module, "__version__",
34667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               parser_version_string);
34677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Register to support pickling.
34697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * If this fails, the import of this module will fail because an
34707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * exception will be raised here; should we clear the exception?
34717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
34727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    copyreg = PyImport_ImportModuleNoBlock("copy_reg");
34737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (copyreg != NULL) {
34747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *func, *pickler;
34757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        func = PyObject_GetAttrString(copyreg, "pickle");
34777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        pickle_constructor = PyObject_GetAttrString(module, "sequence2st");
34787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        pickler = PyObject_GetAttrString(module, "_pickler");
34797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XINCREF(pickle_constructor);
34807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((func != NULL) && (pickle_constructor != NULL)
34817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            && (pickler != NULL)) {
34827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *res;
34837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
34847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
34857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                               pickle_constructor, NULL);
34867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(res);
34877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
34887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(func);
34897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(pickle_constructor);
34907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(pickler);
34917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(copyreg);
34927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
34937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3494