/* parsermodule.c * * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic * Institute and State University, Blacksburg, Virginia, USA. * Portions copyright 1991-1995 by Stichting Mathematisch Centrum, * Amsterdam, The Netherlands. Copying is permitted under the terms * associated with the main Python distribution, with the additional * restriction that this additional notice be included and maintained * on all distributed copies. * * This module serves to replace the original parser module written * by Guido. The functionality is not matched precisely, but the * original may be implemented on top of this. This is desirable * since the source of the text to be parsed is now divorced from * this interface. * * Unlike the prior interface, the ability to give a parse tree * produced by Python code as a tuple to the compiler is enabled by * this module. See the documentation for more details. * * I've added some annotations that help with the lint code-checking * program, but they're not complete by a long shot. The real errors * that lint detects are gone, but there are still warnings with * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations * look like "NOTE(...)". */ #include "Python.h" /* general Python API */#include "graminit.h" /* symbols defined in the grammar */#include "node.h" /* internal parser structure */#include "errcode.h" /* error codes for PyNode_*() */#include "token.h" /* token definitions */ /* ISTERMINAL() / ISNONTERMINAL() */#include "compile.h" /* PyNode_Compile() */ #ifdef lint#include <note.h>#else#define NOTE(x)#endif /* String constants used to initialize module attributes. * */static char parser_copyright_string[] ="Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\Centrum, Amsterdam, The Netherlands."; PyDoc_STRVAR(parser_doc_string,"This is an interface to Python's internal parser."); static char parser_version_string[] = "0.5"; typedef PyObject* (*SeqMaker) (Py_ssize_t length);typedef int (*SeqInserter) (PyObject* sequence, Py_ssize_t index, PyObject* element); /* The function below is copyrighted by Stichting Mathematisch Centrum. The * original copyright statement is included below, and continues to apply * in full to the function immediately following. All other material is * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic * Institute and State University. Changes were made to comply with the * new naming conventions. Added arguments to provide support for creating * lists as well as tuples, and optionally including the line numbers. */ static PyObject*node2tuple(node *n, /* node to convert */ SeqMaker mkseq, /* create sequence */ SeqInserter addelem, /* func. to add elem. in seq. */ int lineno) /* include line numbers? */{ if (n == NULL) { Py_INCREF(Py_None); return (Py_None); } if (ISNONTERMINAL(TYPE(n))) { int i; PyObject *v; PyObject *w; v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); if (v == NULL) return (v); w = PyInt_FromLong(TYPE(n)); if (w == NULL) { Py_DECREF(v); return ((PyObject*) NULL); } (void) addelem(v, 0, w); for (i = 0; i < NCH(n); i++) { w = node2tuple(CHILD(n, i), mkseq, addelem, lineno); if (w == NULL) { Py_DECREF(v); return ((PyObject*) NULL); } (void) addelem(v, i+1, w); } if (TYPE(n) == encoding_decl) (void) addelem(v, i+1, PyString_FromString(STR(n))); return (v); } else if (ISTERMINAL(TYPE(n))) { PyObject *result = mkseq(2 + lineno); if (result != NULL) { (void) addelem(result, 0, PyInt_FromLong(TYPE(n))); (void) addelem(result, 1, PyString_FromString(STR(n))); if (lineno == 1) (void) addelem(result, 2, PyInt_FromLong(n->n_lineno)); } return (result); } else { PyErr_SetString(PyExc_SystemError, "unrecognized parse tree node type"); return ((PyObject*) NULL); }}/* * End of material copyrighted by Stichting Mathematisch Centrum. */ /* There are two types of intermediate objects we're interested in: * 'eval' and 'exec' types. These constants can be used in the st_type * field of the object type to identify which any given object represents. * These should probably go in an external header to allow other extensions * to use them, but then, we really should be using C++ too. ;-) */ #define PyST_EXPR 1#define PyST_SUITE 2 /* These are the internal objects and definitions required to implement the * ST type. Most of the internal names are more reminiscent of the 'old' * naming style, but the code uses the new naming convention. */ static PyObject*parser_error = 0; typedef struct { PyObject_HEAD /* standard object header */ node* st_node; /* the node* returned by the parser */ int st_type; /* EXPR or SUITE ? */} PyST_Object; static void parser_free(PyST_Object *st);static int parser_compare(PyST_Object *left, PyST_Object *right);static PyObject *parser_getattr(PyObject *self, char *name); staticPyTypeObject PyST_Type = { PyObject_HEAD_INIT(NULL) 0, "parser.st", /* tp_name */ (int) sizeof(PyST_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)parser_free, /* tp_dealloc */ 0, /* tp_print */ parser_getattr, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)parser_compare, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ /* Functions to access object as input/output buffer */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ /* __doc__ */ "Intermediate representation of a Python parse tree."}; /* PyST_Type */ static intparser_compare_nodes(node *left, node *right){ int j; if (TYPE(left) < TYPE(right)) return (-1); if (TYPE(right) < TYPE(left)) return (1); if (ISTERMINAL(TYPE(left))) return (strcmp(STR(left), STR(right))); if (NCH(left) < NCH(right)) return (-1); if (NCH(right) < NCH(left)) return (1); for (j = 0; j < NCH(left); ++j) { int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); if (v != 0) return (v); } return (0);} /* int parser_compare(PyST_Object* left, PyST_Object* right) * * Comparison function used by the Python operators ==, !=, <, >, <=, >= * This really just wraps a call to parser_compare_nodes() with some easy * checks and protection code. * */static intparser_compare(PyST_Object *left, PyST_Object *right){ if (left == right) return (0); if ((left == 0) || (right == 0)) return (-1); return (parser_compare_nodes(left->st_node, right->st_node));} /* parser_newstobject(node* st) * * Allocates a new Python object representing an ST. This is simply the * 'wrapper' object that holds a node* and allows it to be passed around in * Python code. * */static PyObject*parser_newstobject(node *st, int type){ PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type); if (o != 0) { o->st_node = st; o->st_type = type; } else { PyNode_Free(st); } return ((PyObject*)o);} /* void parser_free(PyST_Object* st) * * This is called by a del statement that reduces the reference count to 0. * */static voidparser_free(PyST_Object *st){ PyNode_Free(st->st_node); PyObject_Del(st);} /* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw) * * This provides conversion from a node* to a tuple object that can be * returned to the Python-level caller. The ST object is not modified. * */static PyObject*parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw){ PyObject *line_option = 0; PyObject *res = 0; int ok; static char *keywords[] = {"ast", "line_info", NULL}; if (self == NULL) { ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords, &PyST_Type, &self, &line_option); } else ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1], &line_option); if (ok != 0) { int lineno = 0; if (line_option != NULL) { lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0; } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(((PyST_Object*)self)->st_node, PyTuple_New, PyTuple_SetItem, lineno); } return (res);} /* parser_st2list(PyObject* self, PyObject* args, PyObject* kw) * * This provides conversion from a node* to a list object that can be * returned to the Python-level caller. The ST object is not modified. * */static PyObject*parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw){ PyObject *line_option = 0; PyObject *res = 0; int ok; static char *keywords[] = {"ast", "line_info", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords, &PyST_Type, &self, &line_option); else ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1], &line_option); if (ok) { int lineno = 0; if (line_option != 0) { lineno = PyObject_IsTrue(line_option) ? 1 : 0; } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(self->st_node, PyList_New, PyList_SetItem, lineno); } return (res);} /* parser_compilest(PyObject* self, PyObject* args) * * This function creates code objects from the parse tree represented by * the passed-in data object. An optional file name is passed in as well. * */static PyObject*parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw){ PyObject* res = 0; char* str = "<syntax-tree>"; int ok; static char *keywords[] = {"ast", "filename", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords, &PyST_Type, &self, &str); else ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], &str); if (ok) res = (PyObject *)PyNode_Compile(self->st_node, str); return (res);} /* PyObject* parser_isexpr(PyObject* self, PyObject* args) * PyObject* parser_issuite(PyObject* self, PyObject* args) * * Checks the passed-in ST object to determine if it is an expression or * a statement suite, respectively. The return is a Python truth value. * */static PyObject*parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw){ PyObject* res = 0; int ok; static char *keywords[] = {"ast", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords, &PyST_Type, &self); else ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]); if (ok) { /* Check to see if the ST represents an expression or not. */ res = (self->st_type == PyST_EXPR) ? Py_True : Py_False; Py_INCREF(res); } return (res);} static PyObject*parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw){ PyObject* res = 0; int ok; static char *keywords[] = {"ast", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords, &PyST_Type, &self); else ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]); if (ok) { /* Check to see if the ST represents an expression or not. */ res = (self->st_type == PyST_EXPR) ? Py_False : Py_True; Py_INCREF(res); } return (res);} #define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) static PyMethodDefparser_methods[] = { {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE, PyDoc_STR("Compile this ST object into a code object.")}, {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE, PyDoc_STR("Determines if this ST object was created from an expression.")}, {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE, PyDoc_STR("Determines if this ST object was created from a suite.")}, {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE, PyDoc_STR("Creates a list-tree representation of this ST.")}, {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE, PyDoc_STR("Creates a tuple-tree representation of this ST.")}, {NULL, NULL, 0, NULL}}; static PyObject*parser_getattr(PyObject *self, char *name){ return (Py_FindMethod(parser_methods, self, name));} /* err_string(char* message) * * Sets the error string for an exception of type ParserError. * */static voiderr_string(char *message){ PyErr_SetString(parser_error, message);} /* PyObject* parser_do_parse(PyObject* args, int type) * * Internal function to actually execute the parse and return the result if * successful or set an exception if not. * */static PyObject*parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type){ char* string = 0; PyObject* res = 0; static char *keywords[] = {"source", NULL}; if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { node* n = PyParser_SimpleParseString(string, (type == PyST_EXPR) ? eval_input : file_input); if (n) res = parser_newstobject(n, type); } return (res);}Lines 1–500 of 3279. Load more
/* parsermodule.c * * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic * Institute and State University, Blacksburg, Virginia, USA. * Portions copyright 1991-1995 by Stichting Mathematisch Centrum, * Amsterdam, The Netherlands. Copying is permitted under the terms * associated with the main Python distribution, with the additional * restriction that this additional notice be included and maintained * on all distributed copies. * * This module serves to replace the original parser module written * by Guido. The functionality is not matched precisely, but the * original may be implemented on top of this. This is desirable * since the source of the text to be parsed is now divorced from * this interface. * * Unlike the prior interface, the ability to give a parse tree * produced by Python code as a tuple to the compiler is enabled by * this module. See the documentation for more details. * * I've added some annotations that help with the lint code-checking * program, but they're not complete by a long shot. The real errors * that lint detects are gone, but there are still warnings with * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations * look like "NOTE(...)". */ #include "Python.h" /* general Python API */ #include "graminit.h" /* symbols defined in the grammar */ #include "node.h" /* internal parser structure */ #include "errcode.h" /* error codes for PyNode_*() */ #include "token.h" /* token definitions */ /* ISTERMINAL() / ISNONTERMINAL() */ #include "compile.h" /* PyNode_Compile() */ #ifdef lint #include <note.h> #else #define NOTE(x) #endif /* String constants used to initialize module attributes. * */ static char parser_copyright_string[] = "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\ University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\ Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\ Centrum, Amsterdam, The Netherlands."; PyDoc_STRVAR(parser_doc_string, "This is an interface to Python's internal parser."); static char parser_version_string[] = "0.5"; typedef PyObject* (*SeqMaker) (Py_ssize_t length); typedef int (*SeqInserter) (PyObject* sequence, Py_ssize_t index, PyObject* element); /* The function below is copyrighted by Stichting Mathematisch Centrum. The * original copyright statement is included below, and continues to apply * in full to the function immediately following. All other material is * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic * Institute and State University. Changes were made to comply with the * new naming conventions. Added arguments to provide support for creating * lists as well as tuples, and optionally including the line numbers. */ static PyObject* node2tuple(node *n, /* node to convert */ SeqMaker mkseq, /* create sequence */ SeqInserter addelem, /* func. to add elem. in seq. */ int lineno) /* include line numbers? */ { if (n == NULL) { Py_INCREF(Py_None); return (Py_None); } if (ISNONTERMINAL(TYPE(n))) { int i; PyObject *v; PyObject *w; v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); if (v == NULL) return (v); w = PyInt_FromLong(TYPE(n)); if (w == NULL) { Py_DECREF(v); return ((PyObject*) NULL); } (void) addelem(v, 0, w); for (i = 0; i < NCH(n); i++) { w = node2tuple(CHILD(n, i), mkseq, addelem, lineno); if (w == NULL) { Py_DECREF(v); return ((PyObject*) NULL); } (void) addelem(v, i+1, w); } if (TYPE(n) == encoding_decl) (void) addelem(v, i+1, PyString_FromString(STR(n))); return (v); } else if (ISTERMINAL(TYPE(n))) { PyObject *result = mkseq(2 + lineno); if (result != NULL) { (void) addelem(result, 0, PyInt_FromLong(TYPE(n))); (void) addelem(result, 1, PyString_FromString(STR(n))); if (lineno == 1) (void) addelem(result, 2, PyInt_FromLong(n->n_lineno)); } return (result); } else { PyErr_SetString(PyExc_SystemError, "unrecognized parse tree node type"); return ((PyObject*) NULL); } } /* * End of material copyrighted by Stichting Mathematisch Centrum. */ /* There are two types of intermediate objects we're interested in: * 'eval' and 'exec' types. These constants can be used in the st_type * field of the object type to identify which any given object represents. * These should probably go in an external header to allow other extensions * to use them, but then, we really should be using C++ too. ;-) */ #define PyST_EXPR 1 #define PyST_SUITE 2 /* These are the internal objects and definitions required to implement the * ST type. Most of the internal names are more reminiscent of the 'old' * naming style, but the code uses the new naming convention. */ static PyObject* parser_error = 0; typedef struct { PyObject_HEAD /* standard object header */ node* st_node; /* the node* returned by the parser */ int st_type; /* EXPR or SUITE ? */ } PyST_Object; static void parser_free(PyST_Object *st); static int parser_compare(PyST_Object *left, PyST_Object *right); static PyObject *parser_getattr(PyObject *self, char *name); static PyTypeObject PyST_Type = { PyObject_HEAD_INIT(NULL) 0, "parser.st", /* tp_name */ (int) sizeof(PyST_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)parser_free, /* tp_dealloc */ 0, /* tp_print */ parser_getattr, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)parser_compare, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ /* Functions to access object as input/output buffer */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ /* __doc__ */ "Intermediate representation of a Python parse tree." }; /* PyST_Type */ static int parser_compare_nodes(node *left, node *right) { int j; if (TYPE(left) < TYPE(right)) return (-1); if (TYPE(right) < TYPE(left)) return (1); if (ISTERMINAL(TYPE(left))) return (strcmp(STR(left), STR(right))); if (NCH(left) < NCH(right)) return (-1); if (NCH(right) < NCH(left)) return (1); for (j = 0; j < NCH(left); ++j) { int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); if (v != 0) return (v); } return (0); } /* int parser_compare(PyST_Object* left, PyST_Object* right) * * Comparison function used by the Python operators ==, !=, <, >, <=, >= * This really just wraps a call to parser_compare_nodes() with some easy * checks and protection code. * */ static int parser_compare(PyST_Object *left, PyST_Object *right) { if (left == right) return (0); if ((left == 0) || (right == 0)) return (-1); return (parser_compare_nodes(left->st_node, right->st_node)); } /* parser_newstobject(node* st) * * Allocates a new Python object representing an ST. This is simply the * 'wrapper' object that holds a node* and allows it to be passed around in * Python code. * */ static PyObject* parser_newstobject(node *st, int type) { PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type); if (o != 0) { o->st_node = st; o->st_type = type; } else { PyNode_Free(st); } return ((PyObject*)o); } /* void parser_free(PyST_Object* st) * * This is called by a del statement that reduces the reference count to 0. * */ static void parser_free(PyST_Object *st) { PyNode_Free(st->st_node); PyObject_Del(st); } /* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw) * * This provides conversion from a node* to a tuple object that can be * returned to the Python-level caller. The ST object is not modified. * */ static PyObject* parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject *line_option = 0; PyObject *res = 0; int ok; static char *keywords[] = {"ast", "line_info", NULL}; if (self == NULL) { ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords, &PyST_Type, &self, &line_option); } else ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1], &line_option); if (ok != 0) { int lineno = 0; if (line_option != NULL) { lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0; } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(((PyST_Object*)self)->st_node, PyTuple_New, PyTuple_SetItem, lineno); } return (res); } /* parser_st2list(PyObject* self, PyObject* args, PyObject* kw) * * This provides conversion from a node* to a list object that can be * returned to the Python-level caller. The ST object is not modified. * */ static PyObject* parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject *line_option = 0; PyObject *res = 0; int ok; static char *keywords[] = {"ast", "line_info", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords, &PyST_Type, &self, &line_option); else ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1], &line_option); if (ok) { int lineno = 0; if (line_option != 0) { lineno = PyObject_IsTrue(line_option) ? 1 : 0; } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(self->st_node, PyList_New, PyList_SetItem, lineno); } return (res); } /* parser_compilest(PyObject* self, PyObject* args) * * This function creates code objects from the parse tree represented by * the passed-in data object. An optional file name is passed in as well. * */ static PyObject* parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject* res = 0; char* str = "<syntax-tree>"; int ok; static char *keywords[] = {"ast", "filename", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords, &PyST_Type, &self, &str); else ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], &str); if (ok) res = (PyObject *)PyNode_Compile(self->st_node, str); return (res); } /* PyObject* parser_isexpr(PyObject* self, PyObject* args) * PyObject* parser_issuite(PyObject* self, PyObject* args) * * Checks the passed-in ST object to determine if it is an expression or * a statement suite, respectively. The return is a Python truth value. * */ static PyObject* parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject* res = 0; int ok; static char *keywords[] = {"ast", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords, &PyST_Type, &self); else ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]); if (ok) { /* Check to see if the ST represents an expression or not. */ res = (self->st_type == PyST_EXPR) ? Py_True : Py_False; Py_INCREF(res); } return (res); } static PyObject* parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject* res = 0; int ok; static char *keywords[] = {"ast", NULL}; if (self == NULL) ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords, &PyST_Type, &self); else ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]); if (ok) { /* Check to see if the ST represents an expression or not. */ res = (self->st_type == PyST_EXPR) ? Py_False : Py_True; Py_INCREF(res); } return (res); } #define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) static PyMethodDef parser_methods[] = { {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE, PyDoc_STR("Compile this ST object into a code object.")}, {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE, PyDoc_STR("Determines if this ST object was created from an expression.")}, {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE, PyDoc_STR("Determines if this ST object was created from a suite.")}, {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE, PyDoc_STR("Creates a list-tree representation of this ST.")}, {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE, PyDoc_STR("Creates a tuple-tree representation of this ST.")}, {NULL, NULL, 0, NULL} }; static PyObject* parser_getattr(PyObject *self, char *name) { return (Py_FindMethod(parser_methods, self, name)); } /* err_string(char* message) * * Sets the error string for an exception of type ParserError. * */ static void err_string(char *message) { PyErr_SetString(parser_error, message); } /* PyObject* parser_do_parse(PyObject* args, int type) * * Internal function to actually execute the parse and return the result if * successful or set an exception if not. * */ static PyObject* parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type) { char* string = 0; PyObject* res = 0; static char *keywords[] = {"source", NULL}; if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { node* n = PyParser_SimpleParseString(string, (type == PyST_EXPR) ? eval_input : file_input); if (n) res = parser_newstobject(n, type); } return (res); }