Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ parse_start(Parser *p)
{
return start_rule(p);
}

// The end
'''

start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) }
Expand Down
4 changes: 2 additions & 2 deletions Include/pegen_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ extern "C" {

PyAPI_FUNC(mod_ty) PyPegen_ASTFromFile(const char *filename, PyArena *arena);
PyAPI_FUNC(mod_ty) PyPegen_ASTFromString(const char *str, PyArena *arena);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromFile(const char *filename, PyArena *arena);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromString(const char *str, PyArena *arena);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromFile(const char *filename);
PyAPI_FUNC(PyCodeObject *) PyPegen_CodeObjectFromString(const char *str);

#ifdef __cplusplus
}
Expand Down
16 changes: 10 additions & 6 deletions Modules/peg_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ _Py_parse_file(PyObject *self, PyObject *args)
return NULL;
}

PyObject *result = NULL;

mod_ty res = PyPegen_ASTFromFile(filename, arena);
if (res == NULL) {
PyArena_Free(arena);
return NULL;
goto error;
}
PyObject *result = PyAST_mod2obj(res);
result = PyAST_mod2obj(res);

error:
PyArena_Free(arena);
return result;
}
Expand All @@ -40,13 +42,15 @@ _Py_parse_string(PyObject *self, PyObject *args)
return NULL;
}

PyObject *result = NULL;

mod_ty res = PyPegen_ASTFromString(the_string, arena);
if (res == NULL) {
PyArena_Free(arena);
return NULL;
goto error;
}
PyObject *result = PyAST_mod2obj(res);
result = PyAST_mod2obj(res);

error:
PyArena_Free(arena);
return result;
}
Expand Down
2 changes: 2 additions & 0 deletions Parser/pegen/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -13564,3 +13564,5 @@ parse_start(Parser *p)
{
return start_rule(p);
}

// The end
70 changes: 64 additions & 6 deletions Parser/pegen/peg_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,81 @@
mod_ty
PyPegen_ASTFromString(const char *str, PyArena *arena)
{
return run_parser_from_string(str, parse_start, RAW_AST_OBJECT, arena);
PyObject *filename_ob = PyUnicode_FromString("<string>");
if (filename_ob == NULL) {
return NULL;
}

mod_ty result = run_parser_from_string(str, parse_start, filename_ob, arena);
Py_XDECREF(filename_ob);
return result;
}

mod_ty
PyPegen_ASTFromFile(const char *filename, PyArena *arena)
{
return run_parser_from_file(filename, parse_start, RAW_AST_OBJECT, arena);
PyObject *filename_ob = PyUnicode_FromString(filename);
if (filename_ob == NULL) {
return NULL;
}

mod_ty result = run_parser_from_file(filename, parse_start, filename_ob, arena);
Py_XDECREF(filename_ob);
return result;
}

PyCodeObject *
PyPegen_CodeObjectFromString(const char *str, PyArena *arena)
PyPegen_CodeObjectFromString(const char *str)
{
return run_parser_from_string(str, parse_start, CODE_OBJECT, arena);
PyArena *arena = PyArena_New();
if (arena == NULL) {
return NULL;
}

PyCodeObject *result = NULL;

PyObject *filename_ob = PyUnicode_FromString("<string>");
if (filename_ob == NULL) {
goto error;
}

mod_ty res = PyPegen_ASTFromString(str, arena);
if (res == NULL) {
goto error;
}

result = PyAST_CompileObject(res, filename_ob, NULL, -1, arena);

error:
Py_XDECREF(filename_ob);
PyArena_Free(arena);
return result;
}

PyCodeObject *
PyPegen_CodeObjectFromFile(const char *file, PyArena *arena)
PyPegen_CodeObjectFromFile(const char *filename)
{
return run_parser_from_file(file, parse_start, CODE_OBJECT, arena);
PyArena *arena = PyArena_New();
if (arena == NULL) {
return NULL;
}

PyCodeObject *result = NULL;

PyObject *filename_ob = PyUnicode_FromString(filename);
if (filename_ob == NULL) {
goto error;
}

mod_ty res = PyPegen_ASTFromFile(filename, arena);
if (res == NULL) {
goto error;
}

result = PyAST_CompileObject(res, filename_ob, NULL, -1, arena);

error:
Py_XDECREF(filename_ob);
PyArena_Free(arena);
return result;
}
68 changes: 24 additions & 44 deletions Parser/pegen/pegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,8 @@ Parser_New(struct tok_state *tok, mod_ty (*parse_func)(Parser *), int input_mode
return p;
}

void *
run_parser(Parser *p, int mode)
mod_ty
run_parser(Parser *p)
{
int error = setjmp(p->error_env);
if (error) {
Expand All @@ -559,89 +559,69 @@ run_parser(Parser *p, int mode)
return NULL;
}

void *result = NULL;
if (mode == CODE_OBJECT) {
result = PyAST_CompileObject(res, p->tok->filename, NULL, -1, p->arena);
}
else if (mode == AST_OBJECT) {
result = PyAST_mod2obj(res);
}
else {
result = res;
}

return result;
return res;
}

void *
run_parser_from_file(const char *filename, mod_ty (*parse_func)(Parser *), int mode,
PyArena *arena)
mod_ty
run_parser_from_file(const char *filename, mod_ty (*parse_func)(Parser *),
PyObject *filename_ob, PyArena *arena)
{
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
return NULL;
}

PyObject *filename_ob = NULL;
if ((filename_ob = PyUnicode_FromString(filename)) == NULL) {
return NULL;
}

// From here on we need to clean up even if there's an error
void *result = NULL;
mod_ty result = NULL;

struct tok_state *tok = PyTokenizer_FromFile(fp, NULL, NULL, NULL);
if (tok == NULL) {
goto error;
}

// Transfers ownership
// This transfers the ownership to the tokenizer
tok->filename = filename_ob;
filename_ob = NULL;
Py_INCREF(filename_ob);

Parser *p = Parser_New(tok, parse_func, FILE_INPUT, arena);
if (p == NULL) {
PyTokenizer_Free(tok);
goto error;
goto after_tok_error;
}

result = run_parser(p, mode);

result = run_parser(p);
Parser_Free(p);
PyTokenizer_Free(tok);

after_tok_error:
PyTokenizer_Free(tok);
error:
fclose(fp);
Py_XDECREF(filename_ob);
return result;
}

void *
run_parser_from_string(const char *str, mod_ty (*parse_func)(Parser *), int mode,
mod_ty
run_parser_from_string(const char *str, mod_ty (*parse_func)(Parser *), PyObject *filename_ob,
PyArena *arena)
{
void *result = NULL;
struct tok_state *tok = PyTokenizer_FromString(str, 1);
if (tok == NULL) {
return NULL;
}
// This transfers the ownership to the tokenizer
tok->filename = filename_ob;
Py_INCREF(filename_ob);

tok->filename = PyUnicode_FromString("<string>");
if (tok->filename == NULL) {
PyTokenizer_Free(tok);
return NULL;
}
// We need to clear up from here on
mod_ty result = NULL;

Parser *p = Parser_New(tok, parse_func, STRING_INPUT, arena);
if (p == NULL) {
PyTokenizer_Free(tok);
return NULL;
goto error;
}

result = run_parser(p, mode);

result = run_parser(p);
Parser_Free(p);

error:
PyTokenizer_Free(tok);
return result;
}
Expand Down
11 changes: 2 additions & 9 deletions Parser/pegen/pegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ enum INPUT_MODE {
};
typedef enum INPUT_MODE INPUT_MODE;

enum MODE {
RAW_AST_OBJECT,
AST_OBJECT,
CODE_OBJECT
};
typedef enum MODE MODE;

typedef struct _memo {
int type;
void *node;
Expand Down Expand Up @@ -143,8 +136,8 @@ CHECK_CALL_NULL_ALLOWED(Parser *p, void *result)
#define CHECK_NULL_ALLOWED(result) CHECK_CALL_NULL_ALLOWED(p, result)

PyObject *new_identifier(Parser *, char *);
void *run_parser_from_file(const char *, mod_ty(*)(Parser *), int, PyArena *);
void *run_parser_from_string(const char *, mod_ty(*)(Parser *), int, PyArena *);
mod_ty run_parser_from_file(const char *, mod_ty(*)(Parser *), PyObject *, PyArena *);
mod_ty run_parser_from_string(const char *, mod_ty(*)(Parser *), PyObject *, PyArena *);
asdl_seq *singleton_seq(Parser *, void *);
asdl_seq *seq_insert_in_front(Parser *, void *, asdl_seq *);
asdl_seq *seq_flatten(Parser *, asdl_seq *);
Expand Down
Loading