mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	 18f1226884
			
		
	
	
		18f1226884
		
			
		
	
	
	
	
		
			
			(cherry picked from commit ba6fd87e41)
Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
		
	
			
		
			
				
	
	
		
			153 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <Python.h>
 | |
| #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 = "<string>";
 | |
|     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 = "<string>";
 | |
|     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);
 | |
| }
 |