(root)/
Python-3.12.0/
Tools/
peg_generator/
peg_extension/
peg_extension.c
       1  #include "pegen.h"
       2  #include "pycore_compile.h"       // _PyAST_Compile()
       3  
       4  
       5  PyObject *
       6  _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *arena)
       7  {
       8      PyObject *result = NULL;
       9  
      10      if (mode == 2) {
      11          result = (PyObject *)_PyAST_Compile(module, filename_ob, NULL, -1, arena);
      12      } else if (mode == 1) {
      13          result = PyAST_mod2obj(module);
      14      } else {
      15          result = Py_NewRef(Py_None);
      16      }
      17  
      18      return result;
      19  }
      20  
      21  static PyObject *
      22  parse_file(PyObject *self, PyObject *args, PyObject *kwds)
      23  {
      24      static char *keywords[] = {"file", "mode", NULL};
      25      const char *filename;
      26      int mode = 2;
      27      if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &filename, &mode)) {
      28          return NULL;
      29      }
      30      if (mode < 0 || mode > 2) {
      31          return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");
      32      }
      33  
      34      PyArena *arena = _PyArena_New();
      35      if (arena == NULL) {
      36          return NULL;
      37      }
      38  
      39      PyObject *result = NULL;
      40  
      41      PyObject *filename_ob = PyUnicode_FromString(filename);
      42      if (filename_ob == NULL) {
      43          goto error;
      44      }
      45  
      46      FILE *fp = fopen(filename, "rb");
      47      if (fp == NULL) {
      48          PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
      49          goto error;
      50      }
      51  
      52      PyCompilerFlags flags = _PyCompilerFlags_INIT;
      53      mod_ty res = _PyPegen_run_parser_from_file_pointer(
      54                          fp, Py_file_input, filename_ob,
      55                          NULL, NULL, NULL, &flags, NULL, arena);
      56      fclose(fp);
      57      if (res == NULL) {
      58          goto error;
      59      }
      60  
      61      result = _build_return_object(res, mode, filename_ob, arena);
      62  
      63  error:
      64      Py_XDECREF(filename_ob);
      65      _PyArena_Free(arena);
      66      return result;
      67  }
      68  
      69  static PyObject *
      70  parse_string(PyObject *self, PyObject *args, PyObject *kwds)
      71  {
      72      static char *keywords[] = {"str", "mode", NULL};
      73      const char *the_string;
      74      int mode = 2;
      75      if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &the_string, &mode)) {
      76          return NULL;
      77      }
      78      if (mode < 0 || mode > 2) {
      79          return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");
      80      }
      81  
      82      PyArena *arena = _PyArena_New();
      83      if (arena == NULL) {
      84          return NULL;
      85      }
      86  
      87      PyObject *result = NULL;
      88  
      89      PyObject *filename_ob = PyUnicode_FromString("<string>");
      90      if (filename_ob == NULL) {
      91          goto error;
      92      }
      93  
      94      PyCompilerFlags flags = _PyCompilerFlags_INIT;
      95      mod_ty res = _PyPegen_run_parser_from_string(the_string, Py_file_input, filename_ob,
      96                                          &flags, arena);
      97      if (res == NULL) {
      98          goto error;
      99      }
     100      result = _build_return_object(res, mode, filename_ob, arena);
     101  
     102  error:
     103      Py_XDECREF(filename_ob);
     104      _PyArena_Free(arena);
     105      return result;
     106  }
     107  
     108  static PyObject *
     109  clear_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
     110  {
     111  #if defined(PY_DEBUG)
     112      _PyPegen_clear_memo_statistics();
     113  #endif
     114      Py_RETURN_NONE;
     115  }
     116  
     117  static PyObject *
     118  get_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
     119  {
     120  #if defined(PY_DEBUG)
     121      return _PyPegen_get_memo_statistics();
     122  #else
     123      Py_RETURN_NONE;
     124  #endif
     125  }
     126  
     127  // TODO: Write to Python's sys.stdout instead of C's stdout.
     128  static PyObject *
     129  dump_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
     130  {
     131  #if defined(PY_DEBUG)
     132      PyObject *list = _PyPegen_get_memo_statistics();
     133      if (list == NULL) {
     134          return NULL;
     135      }
     136      Py_ssize_t len = PyList_Size(list);
     137      for (Py_ssize_t i = 0; i < len; i++) {
     138          PyObject *value = PyList_GetItem(list, i);  // Borrowed reference.
     139          long count = PyLong_AsLong(value);
     140          if (count < 0) {
     141              break;
     142          }
     143          if (count > 0) {
     144              printf("%4zd %9ld\n", i, count);
     145          }
     146      }
     147      Py_DECREF(list);
     148  #endif
     149      Py_RETURN_NONE;
     150  }
     151  
     152  static PyMethodDef ParseMethods[] = {
     153      {"parse_file", _PyCFunction_CAST(parse_file), METH_VARARGS|METH_KEYWORDS, "Parse a file."},
     154      {"parse_string", _PyCFunction_CAST(parse_string), METH_VARARGS|METH_KEYWORDS, "Parse a string."},
     155      {"clear_memo_stats", clear_memo_stats, METH_NOARGS},
     156      {"dump_memo_stats", dump_memo_stats, METH_NOARGS},
     157      {"get_memo_stats", get_memo_stats, METH_NOARGS},
     158      {NULL, NULL, 0, NULL}        /* Sentinel */
     159  };
     160  
     161  static struct PyModuleDef parsemodule = {
     162      PyModuleDef_HEAD_INIT,
     163      .m_name = "parse",
     164      .m_doc = "A parser.",
     165      .m_methods = ParseMethods,
     166  };
     167  
     168  PyMODINIT_FUNC
     169  PyInit_parse(void)
     170  {
     171      return PyModule_Create(&parsemodule);
     172  }