#include #include "pegen_interface.h" static int _mode_str_to_int(char *mode_str) { int mode; if (strcmp(mode_str, "exec") == 0) { mode = Py_file_input; } else if (strcmp(mode_str, "eval") == 0) { mode = Py_eval_input; } else if (strcmp(mode_str, "single") == 0) { mode = Py_single_input; } else { mode = -1; } return mode; } static mod_ty _run_parser(char *str, char *filename, int mode, PyCompilerFlags *flags, PyArena *arena, int oldparser) { mod_ty mod; if (!oldparser) { mod = PyPegen_ASTFromString(str, filename, mode, flags, arena); } else { mod = PyParser_ASTFromString(str, filename, mode, flags, arena); } return mod; } PyObject * _Py_compile_string(PyObject *self, PyObject *args, PyObject *kwds) { static char *keywords[] = {"string", "filename", "mode", "oldparser", NULL}; char *the_string; char *filename = ""; char *mode_str = "exec"; int oldparser = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ssp", keywords, &the_string, &filename, &mode_str, &oldparser)) { return NULL; } int mode = _mode_str_to_int(mode_str); if (mode == -1) { return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); } PyCompilerFlags flags = _PyCompilerFlags_INIT; flags.cf_flags = PyCF_IGNORE_COOKIE; PyArena *arena = PyArena_New(); if (arena == NULL) { return NULL; } mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); if (mod == NULL) { PyArena_Free(arena); return NULL; } PyObject *filename_ob = PyUnicode_DecodeFSDefault(filename); if (filename_ob == NULL) { PyArena_Free(arena); return NULL; } PyCodeObject *result = PyAST_CompileObject(mod, filename_ob, &flags, -1, arena); Py_XDECREF(filename_ob); PyArena_Free(arena); return (PyObject *)result; } PyObject * _Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) { static char *keywords[] = {"string", "filename", "mode", "oldparser", "ast", NULL}; char *the_string; char *filename = ""; char *mode_str = "exec"; int oldparser = 0; int ast = 1; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sspp", keywords, &the_string, &filename, &mode_str, &oldparser, &ast)) { return NULL; } int mode = _mode_str_to_int(mode_str); if (mode == -1) { return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); } PyCompilerFlags flags = _PyCompilerFlags_INIT; flags.cf_flags = PyCF_IGNORE_COOKIE; PyArena *arena = PyArena_New(); if (arena == NULL) { return NULL; } mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); if (mod == NULL) { PyArena_Free(arena); return NULL; } PyObject *result; if (ast) { result = PyAST_mod2obj(mod); } else { Py_INCREF(Py_None); result = Py_None; } PyArena_Free(arena); return result; } static PyMethodDef ParseMethods[] = { { "parse_string", (PyCFunction)(void (*)(void))_Py_parse_string, METH_VARARGS|METH_KEYWORDS, "Parse a string, return an AST." }, { "compile_string", (PyCFunction)(void (*)(void))_Py_compile_string, METH_VARARGS|METH_KEYWORDS, "Compile a string, return a code object." }, {NULL, NULL, 0, NULL} /* Sentinel */ }; static struct PyModuleDef parsemodule = { PyModuleDef_HEAD_INIT, .m_name = "peg_parser", .m_doc = "A parser.", .m_methods = ParseMethods, }; PyMODINIT_FUNC PyInit__peg_parser(void) { return PyModule_Create(&parsemodule); }