Path: blob/main/Tools/peg_generator/peg_extension/peg_extension.c
12 views
#include "pegen.h"1#include "pycore_compile.h" // _PyAST_Compile()234PyObject *5_build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *arena)6{7PyObject *result = NULL;89if (mode == 2) {10result = (PyObject *)_PyAST_Compile(module, filename_ob, NULL, -1, arena);11} else if (mode == 1) {12result = PyAST_mod2obj(module);13} else {14result = Py_NewRef(Py_None);15}1617return result;18}1920static PyObject *21parse_file(PyObject *self, PyObject *args, PyObject *kwds)22{23static char *keywords[] = {"file", "mode", NULL};24const char *filename;25int mode = 2;26if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &filename, &mode)) {27return NULL;28}29if (mode < 0 || mode > 2) {30return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");31}3233PyArena *arena = _PyArena_New();34if (arena == NULL) {35return NULL;36}3738PyObject *result = NULL;3940PyObject *filename_ob = PyUnicode_FromString(filename);41if (filename_ob == NULL) {42goto error;43}4445FILE *fp = fopen(filename, "rb");46if (fp == NULL) {47PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);48goto error;49}5051PyCompilerFlags flags = _PyCompilerFlags_INIT;52mod_ty res = _PyPegen_run_parser_from_file_pointer(53fp, Py_file_input, filename_ob,54NULL, NULL, NULL, &flags, NULL, arena);55fclose(fp);56if (res == NULL) {57goto error;58}5960result = _build_return_object(res, mode, filename_ob, arena);6162error:63Py_XDECREF(filename_ob);64_PyArena_Free(arena);65return result;66}6768static PyObject *69parse_string(PyObject *self, PyObject *args, PyObject *kwds)70{71static char *keywords[] = {"str", "mode", NULL};72const char *the_string;73int mode = 2;74if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &the_string, &mode)) {75return NULL;76}77if (mode < 0 || mode > 2) {78return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");79}8081PyArena *arena = _PyArena_New();82if (arena == NULL) {83return NULL;84}8586PyObject *result = NULL;8788PyObject *filename_ob = PyUnicode_FromString("<string>");89if (filename_ob == NULL) {90goto error;91}9293PyCompilerFlags flags = _PyCompilerFlags_INIT;94mod_ty res = _PyPegen_run_parser_from_string(the_string, Py_file_input, filename_ob,95&flags, arena);96if (res == NULL) {97goto error;98}99result = _build_return_object(res, mode, filename_ob, arena);100101error:102Py_XDECREF(filename_ob);103_PyArena_Free(arena);104return result;105}106107static PyObject *108clear_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))109{110#if defined(PY_DEBUG)111_PyPegen_clear_memo_statistics();112#endif113Py_RETURN_NONE;114}115116static PyObject *117get_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))118{119#if defined(PY_DEBUG)120return _PyPegen_get_memo_statistics();121#else122Py_RETURN_NONE;123#endif124}125126// TODO: Write to Python's sys.stdout instead of C's stdout.127static PyObject *128dump_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))129{130#if defined(PY_DEBUG)131PyObject *list = _PyPegen_get_memo_statistics();132if (list == NULL) {133return NULL;134}135Py_ssize_t len = PyList_Size(list);136for (Py_ssize_t i = 0; i < len; i++) {137PyObject *value = PyList_GetItem(list, i); // Borrowed reference.138long count = PyLong_AsLong(value);139if (count < 0) {140break;141}142if (count > 0) {143printf("%4zd %9ld\n", i, count);144}145}146Py_DECREF(list);147#endif148Py_RETURN_NONE;149}150151static PyMethodDef ParseMethods[] = {152{"parse_file", _PyCFunction_CAST(parse_file), METH_VARARGS|METH_KEYWORDS, "Parse a file."},153{"parse_string", _PyCFunction_CAST(parse_string), METH_VARARGS|METH_KEYWORDS, "Parse a string."},154{"clear_memo_stats", clear_memo_stats, METH_NOARGS},155{"dump_memo_stats", dump_memo_stats, METH_NOARGS},156{"get_memo_stats", get_memo_stats, METH_NOARGS},157{NULL, NULL, 0, NULL} /* Sentinel */158};159160static struct PyModuleDef parsemodule = {161PyModuleDef_HEAD_INIT,162.m_name = "parse",163.m_doc = "A parser.",164.m_methods = ParseMethods,165};166167PyMODINIT_FUNC168PyInit_parse(void)169{170return PyModule_Create(&parsemodule);171}172173174