mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-40334: PEP 617 implementation: New PEG parser for CPython (GH-19503)
Co-authored-by: Guido van Rossum <guido@python.org> Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
This commit is contained in:
parent
a81849b031
commit
c5fc156852
91 changed files with 27057 additions and 146 deletions
|
|
@ -134,6 +134,9 @@ faulthandler faulthandler.c
|
|||
# can call _PyTraceMalloc_NewReference().
|
||||
_tracemalloc _tracemalloc.c hashtable.c
|
||||
|
||||
# PEG-based parser module -- slated to be *the* parser
|
||||
_peg_parser _peg_parser.c
|
||||
|
||||
# The rest of the modules listed in this file are all commented out by
|
||||
# default. Usually they can be detected and built as dynamically
|
||||
# loaded modules by the new setup.py script added in Python 2.1. If
|
||||
|
|
|
|||
107
Modules/_peg_parser.c
Normal file
107
Modules/_peg_parser.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#include <Python.h>
|
||||
#include <pegen_interface.h>
|
||||
|
||||
PyObject *
|
||||
_Py_parse_file(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"file", "mode", NULL};
|
||||
char *filename;
|
||||
char *mode_str = "exec";
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", keywords, &filename, &mode_str)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mode;
|
||||
if (strcmp(mode_str, "exec") == 0) {
|
||||
mode = Py_file_input;
|
||||
}
|
||||
else if (strcmp(mode_str, "single") == 0) {
|
||||
mode = Py_single_input;
|
||||
}
|
||||
else {
|
||||
return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'single'");
|
||||
}
|
||||
|
||||
PyArena *arena = PyArena_New();
|
||||
if (arena == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
mod_ty res = PyPegen_ASTFromFile(filename, mode, arena);
|
||||
if (res == NULL) {
|
||||
goto error;
|
||||
}
|
||||
result = PyAST_mod2obj(res);
|
||||
|
||||
error:
|
||||
PyArena_Free(arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"string", "mode", NULL};
|
||||
char *the_string;
|
||||
char *mode_str = "exec";
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", keywords, &the_string, &mode_str)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 {
|
||||
return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'");
|
||||
}
|
||||
|
||||
PyArena *arena = PyArena_New();
|
||||
if (arena == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
PyCompilerFlags flags = _PyCompilerFlags_INIT;
|
||||
flags.cf_flags = PyCF_IGNORE_COOKIE;
|
||||
|
||||
mod_ty res = PyPegen_ASTFromString(the_string, mode, &flags, arena);
|
||||
if (res == NULL) {
|
||||
goto error;
|
||||
}
|
||||
result = PyAST_mod2obj(res);
|
||||
|
||||
error:
|
||||
PyArena_Free(arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyMethodDef ParseMethods[] = {
|
||||
{"parse_file", (PyCFunction)(void (*)(void))_Py_parse_file, METH_VARARGS|METH_KEYWORDS, "Parse a file."},
|
||||
{"parse_string", (PyCFunction)(void (*)(void))_Py_parse_string, METH_VARARGS|METH_KEYWORDS,"Parse a string."},
|
||||
{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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue