1 #include <Python.h> 2 #include "pegen_interface.h" 3 4 static int 5 _mode_str_to_int(char *mode_str) 6 { 7 int mode; 8 if (strcmp(mode_str, "exec") == 0) { 9 mode = Py_file_input; 10 } 11 else if (strcmp(mode_str, "eval") == 0) { 12 mode = Py_eval_input; 13 } 14 else if (strcmp(mode_str, "single") == 0) { 15 mode = Py_single_input; 16 } 17 else { 18 mode = -1; 19 } 20 return mode; 21 } 22 23 static mod_ty 24 _run_parser(char *str, char *filename, int mode, PyCompilerFlags *flags, PyArena *arena, int oldparser) 25 { 26 mod_ty mod; 27 if (!oldparser) { 28 mod = PyPegen_ASTFromString(str, filename, mode, flags, arena); 29 } 30 else { 31 mod = PyParser_ASTFromString(str, filename, mode, flags, arena); 32 } 33 return mod; 34 } 35 36 PyObject * 37 _Py_compile_string(PyObject *self, PyObject *args, PyObject *kwds) 38 { 39 static char *keywords[] = {"string", "filename", "mode", "oldparser", NULL}; 40 char *the_string; 41 char *filename = "<string>"; 42 char *mode_str = "exec"; 43 int oldparser = 0; 44 45 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ssp", keywords, 46 &the_string, &filename, &mode_str, &oldparser)) { 47 return NULL; 48 } 49 50 int mode = _mode_str_to_int(mode_str); 51 if (mode == -1) { 52 return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); 53 } 54 55 PyCompilerFlags flags = _PyCompilerFlags_INIT; 56 flags.cf_flags = PyCF_IGNORE_COOKIE; 57 58 PyArena *arena = PyArena_New(); 59 if (arena == NULL) { 60 return NULL; 61 } 62 63 mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); 64 if (mod == NULL) { 65 PyArena_Free(arena); 66 return NULL; 67 } 68 69 PyObject *filename_ob = PyUnicode_DecodeFSDefault(filename); 70 if (filename_ob == NULL) { 71 PyArena_Free(arena); 72 return NULL; 73 } 74 PyCodeObject *result = PyAST_CompileObject(mod, filename_ob, &flags, -1, arena); 75 Py_XDECREF(filename_ob); 76 PyArena_Free(arena); 77 return (PyObject *)result; 78 } 79 80 PyObject * 81 _Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) 82 { 83 static char *keywords[] = {"string", "filename", "mode", "oldparser", "ast", NULL}; 84 char *the_string; 85 char *filename = "<string>"; 86 char *mode_str = "exec"; 87 int oldparser = 0; 88 int ast = 1; 89 90 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sspp", keywords, 91 &the_string, &filename, &mode_str, &oldparser, &ast)) { 92 return NULL; 93 } 94 95 int mode = _mode_str_to_int(mode_str); 96 if (mode == -1) { 97 return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); 98 } 99 100 PyCompilerFlags flags = _PyCompilerFlags_INIT; 101 flags.cf_flags = PyCF_IGNORE_COOKIE; 102 103 PyArena *arena = PyArena_New(); 104 if (arena == NULL) { 105 return NULL; 106 } 107 108 mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); 109 if (mod == NULL) { 110 PyArena_Free(arena); 111 return NULL; 112 } 113 114 PyObject *result; 115 if (ast) { 116 result = PyAST_mod2obj(mod); 117 } 118 else { 119 Py_INCREF(Py_None); 120 result = Py_None; 121 } 122 PyArena_Free(arena); 123 return result; 124 } 125 126 static PyMethodDef ParseMethods[] = { 127 { 128 "parse_string", 129 (PyCFunction)(void (*)(void))_Py_parse_string, 130 METH_VARARGS|METH_KEYWORDS, 131 "Parse a string, return an AST." 132 }, 133 { 134 "compile_string", 135 (PyCFunction)(void (*)(void))_Py_compile_string, 136 METH_VARARGS|METH_KEYWORDS, 137 "Compile a string, return a code object." 138 }, 139 {NULL, NULL, 0, NULL} /* Sentinel */ 140 }; 141 142 static struct PyModuleDef parsemodule = { 143 PyModuleDef_HEAD_INIT, 144 .m_name = "peg_parser", 145 .m_doc = "A parser.", 146 .m_methods = ParseMethods, 147 }; 148 149 PyMODINIT_FUNC 150 PyInit__peg_parser(void) 151 { 152 return PyModule_Create(&parsemodule); 153 } 154