From 69afdab40273575419c2dcfa98de4572d1871d64 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 5 May 2017 21:00:17 -0700 Subject: [PATCH] Implement lexing, almost. Currently, throws NoMemory exception on error. --- include/pyliblexmodule.h | 4 +- src/pyliblexmodule.c | 87 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/include/pyliblexmodule.h b/include/pyliblexmodule.h index ce14e77..a96b0da 100644 --- a/include/pyliblexmodule.h +++ b/include/pyliblexmodule.h @@ -4,13 +4,15 @@ #include "Python.h" static PyObject* pyliblex_init(PyObject* self, PyObject* args); -static PyObject* pyliblex_add_definitions(PyObject* self, PyObject* args); +static PyObject* pyliblex_add_definition(PyObject* self, PyObject* args); static PyObject* pyliblex_lex(PyObject* self, PyObject* args); static PyObject* pyliblex_test(PyObject* self, PyObject* args); static const char module_docstring[] = "A wrapper around a homemade lexing library, liblex."; static PyMethodDef module_methods[] = { {"init", pyliblex_init, METH_VARARGS, "Initialize a liblex library object." }, + {"add_definition", pyliblex_add_definition, METH_VARARGS, "Add a regular expression definition." }, + {"lex", pyliblex_lex, METH_VARARGS, "Lex a string, converting it to tokens." }, {"test", pyliblex_test, METH_VARARGS, "Tests whether the library is working." }, { NULL, NULL, 0, NULL } }; diff --git a/src/pyliblexmodule.c b/src/pyliblexmodule.c index 7931c40..0c2525a 100644 --- a/src/pyliblexmodule.c +++ b/src/pyliblexmodule.c @@ -25,8 +25,91 @@ static PyObject* pyliblex_init(PyObject* self, PyObject* args){ return return_object; } -static PyObject* pyliblex_add_definitions(PyObject* self, PyObject* args); -static PyObject* pyliblex_lex(PyObject* self, PyObject* args); +static PyObject* pyliblex_add_definition(PyObject* self, PyObject* args){ + PyObject* return_object = NULL; + + PyObject* capsule; + const char* regex; + int id; + + if(PyArg_ParseTuple(args, "Osi", &capsule, ®ex, &id)) { + eval_config* config = PyCapsule_GetPointer(capsule, NULL); + if(config){ + liblex_result result = eval_config_add(config, regex, id); + if(result != LIBLEX_SUCCESS){ + return_object = PyErr_NoMemory(); + } else { + Py_INCREF(Py_None); + return_object = Py_None; + } + } + } + + return return_object; +} +static int _pyliblex_add_match(void* data, va_list args){ + int return_code = 0; + match* match = data; + const char* string = va_arg(args, const char*); + PyObject* list = va_arg(args, PyObject*); + PyObject* string_object = NULL; + PyObject* int_object = NULL; + PyObject* tuple = NULL; + + string_object = PyUnicode_FromStringAndSize(string + match->from, match->to - match->from); + int_object = PyLong_FromLong(match->pattern); + if(string_object && int_object){ + tuple = PyTuple_New(2); + if(tuple){ + return_code = PyTuple_SetItem(tuple, 0, string_object); + if(return_code == 0) return_code = PyTuple_SetItem(tuple, 1, int_object); + } + } + + if(tuple) { + if(return_code != 0) Py_DECREF(tuple); + else return_code = PyList_Append(list, tuple); + } + return return_code; +} +static PyObject* pyliblex_lex(PyObject* self, PyObject* args){ + PyObject* return_object = NULL; + + PyObject* capsule; + const char* string; + + if(PyArg_ParseTuple(args, "Os", &capsule, &string)) { + eval_config* config = PyCapsule_GetPointer(capsule, NULL); + if(config){ + ll match_ll; + liblex_result result; + + ll_init(&match_ll); + result = eval_all(string, 0, config, &match_ll); + if(result != LIBLEX_SUCCESS){ + return_object = PyErr_NoMemory(); + } else { + int return_code = 0; + PyObject* list = PyList_New(0); + + if(list){ + return_code = ll_foreach(&match_ll, NULL, compare_always, _pyliblex_add_match, string, list); + if(return_code != 0) { + Py_DECREF(list); + list = PyList_New(0); + } + } + + ll_foreach(&match_ll, NULL, compare_always, eval_foreach_match_free); + ll_clear(&match_ll); + + return_object = list; + } + ll_free(&match_ll); + } + } + return return_object; +} static PyObject* pyliblex_test(PyObject* self, PyObject* args) { return PyUnicode_FromString("Test from liblex!"); }